Revert "camera: use VGA camera resolution for esp32s3"
What changed, and why it matters
This commit reverts a previous change that made the Jade Plus (ESP32-S3) camera use a higher VGA resolution. It returns all hardware variants to the lower QVGA resolution because QVGA was found to scan QR codes faster and more accurately on Jade Plus. It also removes the larger VGA test images and simplifies the output-message buffer size logic. There is no security fix or vulnerability here.
No security action required. Treat as a normal functional regression/revert and verify QR scanning still passes on Jade Plus with QVGA.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch removes ESP32-S3-specific VGA (640x480) camera configuration and restores a single QVGA (320x240) resolution for all targets. It deletes all qr_vga_* test fixtures and updates test_jade.py to run only QVGA scan tests regardless of BOARD_TYPE. In process.h it collapses the MAX_OUTPUT_MSG_SIZE definition: without CONFIG_RETURN_CAMERA_IMAGES it stays at 3 KiB; with it, it is fixed at 90 KiB (previously 90 KiB for non-S3 and 300 KiB for S3). The camera task stack size is also unified to 16 KiB. No memory-safety, cryptographic, or access-control changes are present.
Changed components
main/camera.cmain/camera.hmain/process.htest_jade.pytest_data/qr_vga_* (deleted)Inspect captured patch +14 / −132
diff --git a/main/camera.c b/main/camera.c
index f33fb2d..ce5fac0 100644
--- a/main/camera.c
+++ b/main/camera.c
@@ -37,12 +37,10 @@ void camera_set_debug_image(const uint8_t* data, const size_t len)
// as we don't want the unit to shut down because of apparent inactivity.
#define CAMERA_MIN_TIMEOUT_SECS 300
-// Size of the image as provided by the camera - note this should be consistent
-// with CAMERA_IMAGE_WIDTH and CAMERA_IMAGE_HEIGHT ! TODO: fetch from Kconfig?
-#ifdef CONFIG_IDF_TARGET_ESP32S3
-#define CAMERA_IMAGE_RESOLUTION FRAMESIZE_VGA
-#else
+// Size of the image as provided by the camera
#define CAMERA_IMAGE_RESOLUTION FRAMESIZE_QVGA
+#if (CAMERA_IMAGE_WIDTH != 320) || (CAMERA_IMAGE_HEIGHT != 240)
+#error CAMERA_IMAGE_WIDTH/HEIGHT inconsistent with CAMERA_IMAGE_RESOLUTION!
#endif
#define CAM_MIN(a, b) (a < b ? a : b)
@@ -543,12 +541,7 @@ void jade_camera_process_images(camera_process_fn_t fn, void* ctx, const bool sh
const UBaseType_t mem_caps = MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL;
#endif
-#if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(CONFIG_RETURN_CAMERA_IMAGES)
- const uint32_t stack_size = 18 * 1024;
-#else
const uint32_t stack_size = 16 * 1024;
-#endif
-
TaskHandle_t camera_task;
const BaseType_t retval = xTaskCreatePinnedToCoreWithCaps(&jade_camera_task, "jade_camera", stack_size,
&camera_config, JADE_TASK_PRIO_CAMERA, &camera_task, JADE_CORE_SECONDARY, mem_caps);
diff --git a/main/camera.h b/main/camera.h
index f0a8de5..8c8bfe2 100644
--- a/main/camera.h
+++ b/main/camera.h
@@ -8,15 +8,10 @@
#include <stddef.h>
#include <stdint.h>
-// Size of the image as provided by the camera - note this should be consistent
-// with CAMERA_IMAGE_RESOLUTION ! TODO: fetch from Kconfig?
-#ifdef CONFIG_IDF_TARGET_ESP32S3
-#define CAMERA_IMAGE_WIDTH 640
-#define CAMERA_IMAGE_HEIGHT 480
-#else
+// Size of the image as provided by the camera
+// TODO: fetch from Kconfig?
#define CAMERA_IMAGE_WIDTH 320
#define CAMERA_IMAGE_HEIGHT 240
-#endif
// How much image (central area) is displayed on screen
uint16_t camera_displayed_image_width(void);
diff --git a/main/process.h b/main/process.h
index d25e9dc..35bf8d4 100644
--- a/main/process.h
+++ b/main/process.h
@@ -21,20 +21,15 @@
#define MAX_INPUT_MSG_SIZE (1024 * 401)
#endif
+#ifndef CONFIG_RETURN_CAMERA_IMAGES
// This should be the size of the largest valid output message.
// Used by ble and serial when sending messages. (pinserver handshake)
-// NOTE: if CONFIG_RETURN_CAMERA_IMAGES is defined we allocate a larger
-// buffer as image sizes are much larger than standard messges.
-#define MAX_STANDARD_OUTPUT_MSG_SIZE (1024 * 3)
-#ifdef CONFIG_RETURN_CAMERA_IMAGES
-#ifdef CONFIG_IDF_TARGET_ESP32S3
-#define MAX_OUTPUT_MSG_SIZE (MAX_STANDARD_OUTPUT_MSG_SIZE * 100)
-#else
-#define MAX_OUTPUT_MSG_SIZE (MAX_STANDARD_OUTPUT_MSG_SIZE * 30)
-#endif // CONFIG_IDF_TARGET_ESP32S3
+#define MAX_OUTPUT_MSG_SIZE (1024 * 3)
#else
-#define MAX_OUTPUT_MSG_SIZE MAX_STANDARD_OUTPUT_MSG_SIZE
-#endif // CONFIG_RETURN_CAMERA_IMAGES
+// When CONFIG_RETURN_CAMERA_IMAGES is defined we allocate a larger
+// buffer as image sizes are much larger than standard messges.
+#define MAX_OUTPUT_MSG_SIZE ((1024 * 3) * 30)
+#endif
// Cbor encoding function prototype
typedef void (*cbor_encoder_fn_t)(const void*, CborEncoder*);
diff --git a/test_data/qr_vga_bcur_psbt.dat b/test_data/qr_vga_bcur_psbt.dat
deleted file mode 100644
index e5f7907..0000000
Binary files a/test_data/qr_vga_bcur_psbt.dat and /dev/null differ
diff --git a/test_data/qr_vga_bcur_psbt.json b/test_data/qr_vga_bcur_psbt.json
deleted file mode 100644
index 10819ea..0000000
--- a/test_data/qr_vga_bcur_psbt.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "input": {
- "image": "qr_vga_bcur_psbt.dat"
- },
- "expected_output": {
- "text": "UR:CRYPTO-PSBT/HDRKJOJKIDJYZMADAEGMAOAEAEAEADHEHKDKKPZCNETTHHMYVWDNMNADWZSPBBSFSWCADNCWFWQDKSIAZTGHTIJPCFNSZTAEAEAEAEAEZMZMZMZMADRFAOAEAEAEAEAEAECMAEBBKSHGTECWKIEMMKFYVSZMVWFNWYNSZECNWLUYLNTTAEAEAEAEAEADADCTKNAXAEAEAEAEAEAECMAEBBWLLFESBGNYAXMYGOCHKKCFVYKNHDRHIOIYOSOLYNCPAMAXLEOLSRPRFEINGEPYDSMYBEVECFGSVOWZBKAMZOSRAXWLRLHTDPSOLOPYWMGOMSGLCSLGISMNNBGHAEAELAAEAEAELAAEAEAELAAEAEAEAEAOAEAEAEAEAEBYBTDEIE"
- }
-}
diff --git a/test_data/qr_vga_compactseedqr_vec1.dat b/test_data/qr_vga_compactseedqr_vec1.dat
deleted file mode 100644
index 5b69544..0000000
Binary files a/test_data/qr_vga_compactseedqr_vec1.dat and /dev/null differ
diff --git a/test_data/qr_vga_compactseedqr_vec1.json b/test_data/qr_vga_compactseedqr_vec1.json
deleted file mode 100644
index 698b006..0000000
--- a/test_data/qr_vga_compactseedqr_vec1.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "input": {
- "image": "qr_vga_compactseedqr_vec1.dat"
- },
- "expected_output": {
- "hex": "0e74b64107f94cc0ccfae6a13dcbec3662154fec67e0e00999c07892597d190a"
- }
-}
diff --git a/test_data/qr_vga_compactseedqr_vec7.dat b/test_data/qr_vga_compactseedqr_vec7.dat
deleted file mode 100644
index 074bd31..0000000
Binary files a/test_data/qr_vga_compactseedqr_vec7.dat and /dev/null differ
diff --git a/test_data/qr_vga_compactseedqr_vec7.json b/test_data/qr_vga_compactseedqr_vec7.json
deleted file mode 100644
index 8aede3f..0000000
--- a/test_data/qr_vga_compactseedqr_vec7.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "input": {
- "image": "qr_vga_compactseedqr_vec7.dat"
- },
- "expected_output": {
- "hex": "3e1e0bc1e31e0e4315348b76dfec0a98"
- }
-}
diff --git a/test_data/qr_vga_compactseedqr_vec8.dat b/test_data/qr_vga_compactseedqr_vec8.dat
deleted file mode 100644
index 0a9a97f..0000000
Binary files a/test_data/qr_vga_compactseedqr_vec8.dat and /dev/null differ
diff --git a/test_data/qr_vga_compactseedqr_vec8.json b/test_data/qr_vga_compactseedqr_vec8.json
deleted file mode 100644
index b319000..0000000
--- a/test_data/qr_vga_compactseedqr_vec8.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "input": {
- "image": "qr_vga_compactseedqr_vec8.dat"
- },
- "expected_output": {
- "hex": "307eaf058659ca7a7a0d63152509e541"
- }
-}
diff --git a/test_data/qr_vga_compactseedqr_vec9.dat b/test_data/qr_vga_compactseedqr_vec9.dat
deleted file mode 100644
index c2a1f5d..0000000
Binary files a/test_data/qr_vga_compactseedqr_vec9.dat and /dev/null differ
diff --git a/test_data/qr_vga_compactseedqr_vec9.json b/test_data/qr_vga_compactseedqr_vec9.json
deleted file mode 100644
index 8565d4c..0000000
--- a/test_data/qr_vga_compactseedqr_vec9.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "input": {
- "image": "qr_vga_compactseedqr_vec9.dat"
- },
- "expected_output": {
- "hex": "f55cf587f2543d01090d0ae710bd3b6d"
- }
-}
diff --git a/test_data/qr_vga_high_res.dat b/test_data/qr_vga_high_res.dat
deleted file mode 100644
index d0c214d..0000000
Binary files a/test_data/qr_vga_high_res.dat and /dev/null differ
diff --git a/test_data/qr_vga_high_res.json b/test_data/qr_vga_high_res.json
deleted file mode 100644
index eea81d4..0000000
--- a/test_data/qr_vga_high_res.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "input": {
- "image": "qr_vga_high_res.dat"
- },
- "expected_output": {
- "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Odio eu feugiat pretium nibh ipsum consequat. Fermentum posuere urna nec tincidunt praesent semper feugiat nibh sed."
- }
-}
diff --git a/test_data/qr_vga_hotp.dat b/test_data/qr_vga_hotp.dat
deleted file mode 100644
index 35f6935..0000000
Binary files a/test_data/qr_vga_hotp.dat and /dev/null differ
diff --git a/test_data/qr_vga_hotp.json b/test_data/qr_vga_hotp.json
deleted file mode 100644
index dbd030a..0000000
--- a/test_data/qr_vga_hotp.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "input": {
- "image": "qr_vga_hotp.dat"
- },
- "expected_output": {
- "text": "otpauth://hotp/ACME%20Co:john.doe@email.com?secret=GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ&issuer=ACME%20Co&digits=8&counter=5"
- }
-}
diff --git a/test_data/qr_vga_low_res.dat b/test_data/qr_vga_low_res.dat
deleted file mode 100644
index 1992ba2..0000000
Binary files a/test_data/qr_vga_low_res.dat and /dev/null differ
diff --git a/test_data/qr_vga_low_res.json b/test_data/qr_vga_low_res.json
deleted file mode 100644
index a0d831b..0000000
--- a/test_data/qr_vga_low_res.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "input": {
- "image": "qr_vga_low_res.dat"
- },
- "expected_output": {
- "text": "This is a test of Jade's QR scanner."
- }
-}
diff --git a/test_data/qr_vga_mnemonic_prefixes.dat b/test_data/qr_vga_mnemonic_prefixes.dat
deleted file mode 100644
index 044db84..0000000
Binary files a/test_data/qr_vga_mnemonic_prefixes.dat and /dev/null differ
diff --git a/test_data/qr_vga_mnemonic_prefixes.json b/test_data/qr_vga_mnemonic_prefixes.json
deleted file mode 100644
index 178a3bf..0000000
--- a/test_data/qr_vga_mnemonic_prefixes.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "input": {
- "image": "qr_vga_mnemonic_prefixes.dat"
- },
- "expected_output": {
- "text": "fish inne face gin orc perm usef meth fen kidn chuc part fav suns draw limb scie cran ova let slot invi sadn bana"
- }
-}
diff --git a/test_data/qr_vga_seedqr_vec1.dat b/test_data/qr_vga_seedqr_vec1.dat
deleted file mode 100644
index f8d1f95..0000000
Binary files a/test_data/qr_vga_seedqr_vec1.dat and /dev/null differ
diff --git a/test_data/qr_vga_seedqr_vec1.json b/test_data/qr_vga_seedqr_vec1.json
deleted file mode 100644
index 630427d..0000000
--- a/test_data/qr_vga_seedqr_vec1.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "input": {
- "image": "qr_vga_seedqr_vec1.dat"
- },
- "expected_output": {
- "text": "011513251154012711900771041507421289190620080870026613431420201617920614089619290300152408010643"
- }
-}
diff --git a/test_data/qr_vga_test_mnemonic.dat b/test_data/qr_vga_test_mnemonic.dat
deleted file mode 100644
index ea7bef1..0000000
Binary files a/test_data/qr_vga_test_mnemonic.dat and /dev/null differ
diff --git a/test_data/qr_vga_test_mnemonic.json b/test_data/qr_vga_test_mnemonic.json
deleted file mode 100644
index a47ff83..0000000
--- a/test_data/qr_vga_test_mnemonic.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "input": {
- "image": "qr_vga_test_mnemonic.dat"
- },
- "expected_output": {
- "text": "fish inner face ginger orchard permit useful method fence kidney chuckle party favorite sunset draw limb science crane oval letter slot invite sadness banana"
- }
-}
diff --git a/test_data/qr_vga_totp.dat b/test_data/qr_vga_totp.dat
deleted file mode 100644
index fb29cf5..0000000
Binary files a/test_data/qr_vga_totp.dat and /dev/null differ
diff --git a/test_data/qr_vga_totp.json b/test_data/qr_vga_totp.json
deleted file mode 100644
index 052342f..0000000
--- a/test_data/qr_vga_totp.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "input": {
- "image": "qr_vga_totp.dat"
- },
- "expected_output": {
- "text": "otpauth://totp/ACME%20Co:john.doe@email.com?secret=GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ&issuer=ACME%20Co&digits=8&algorithm=SHA256"
- }
-}
diff --git a/test_jade.py b/test_jade.py
index 7c72f98..dd4b599 100644
--- a/test_jade.py
+++ b/test_jade.py
@@ -562,7 +562,6 @@ YzNnQaWx24j5hX8iWcaZgTZJ6Y3sedLi'),
# Hold test data in separate files as can be large
QR_QVGA_SCAN_TESTS = 'qr_qvga_*.json'
-QR_VGA_SCAN_TESTS = 'qr_vga_*.json'
MULTI_REG_TESTS = 'multisig_reg_*.json'
MULTI_REG_SS_TESTS = 'multisig_reg_ss_*.json'
MULTI_REG_FILE_TESTS = 'multisig_file_*.json'
@@ -2271,10 +2270,8 @@ def test_passphrase(jade):
# Test qr scanning - can be slow as image data large (slow to upload) and
# tests involve starting the camera (and associated tasks).
-def test_scan_qr(jadeapi, use_vga_images):
- # Higher res images for s3 hardware
- pattern = QR_VGA_SCAN_TESTS if use_vga_images else QR_QVGA_SCAN_TESTS
- for qr_data in _get_test_cases(pattern):
+def test_scan_qr(jadeapi):
+ for qr_data in _get_test_cases(QR_QVGA_SCAN_TESTS):
expected = qr_data['expected_output']
image_filename = qr_data['input']['image']
with open('./test_data/' + image_filename, 'rb') as f:
@@ -3895,9 +3892,7 @@ def run_interface_tests(jadeapi,
# Only run QR scan/camera tests a) over serial, and b) on proper Jade hw
if not qemu and not isble and startinfo['BOARD_TYPE'] in ['JADE', 'JADE_V1.1', 'JADE_V2']:
- # Higher res images for s3 hardware
- use_vga_images = startinfo['BOARD_TYPE'] == 'JADE_V2'
- test_scan_qr(jadeapi, use_vga_images)
+ test_scan_qr(jadeapi)
# Too much input test - sends a lot of data so only run
# if not running over BLE (as would take a long time)
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.