Skip to content

BLE: JadeBoardType enum causes CBOR decode failure on iOS (Error 531) — Root Cause & Fix Included #93

@CaTeIM

Description

@CaTeIM

Description

All Jade DIY hardware (TTGO T-Display, T-Display S3, Waveshare, M5Stack, etc.) is unable to connect to Green iOS. The app establishes the BLE connection and completes pairing successfully, but immediately disconnects with reason code 531 (Remote User Terminated Connection) after receiving the get_version_info response.

The root cause is a strict CBOR deserialization failure in the hardware abstraction layer. The JadeBoardType enum only accepts three raw values, but DIY firmware sends board-specific strings like "TTGO_TDISPLAY", "M5FIRE", "TTGO_TDISPLAYS3", etc.

This blocks 100% of connection attempts from any non-official Jade hardware on iOS. Android (Green for Android) is not affected because it handles the board type field differently.

Steps to Reproduce

  1. Flash a generic ESP32 with Jade DIY firmware (ensure CONFIG_BOARD_TYPE is set to specific hardware like TTGO_TDISPLAY).
  2. Open Green iOS (v5.1.6+).
  3. Attempt to add a new Jade device via BLE.
  4. Observe that pairing succeeds, but connection drops immediately after receiving version info.

Environment

  • Green iOS version: 5.1.6+
  • Hardware: TTGO T-Display (ESP32) running Jade DIY firmware v1.0.38
  • iOS version: 18.x
  • Jade firmware config: CONFIG_BOARD_TYPE_TTGO_TDISPLAY=y, JADE_FEATURES="DEV"

Root Cause

In hw/Models/Enums.swift, the JadeBoardType enum is defined as:

public enum JadeBoardType: String, CaseIterable, Codable {
    case v1 = "JADE"
    case v1_1 = "JADE_V1.1"
    case v2 = "JADE_V2"
}

The Jade DIY firmware sends BOARD_TYPE = "TTGO_TDISPLAY" (or equivalent per-board string) in the get_version_info CBOR response. Since Swift's Codable protocol performs all-or-nothing decoding, the unrecognized board type causes the entire JadeVersionInfo struct to fail decoding — not just the boardType field.

The failure chain is:

sequenceDiagram
    participant G as Green iOS
    participant J as Jade DIY

    G->>J: BLE Connect + Bond
    G->>J: get_version_info (CBOR RPC)
    J->>G: Response (BOARD_TYPE="TTGO_TDISPLAY")
    Note over G: CBOR decode into JadeVersionInfo
    Note over G: JadeBoardType("TTGO_TDISPLAY") → ❌ FAIL
    Note over G: res.result = nil
    Note over G: throw HWError.Abort("Invalid response")
    G->>J: Disconnect (reason 531)

Loading

Evidence from BLE Logs

Before fix (firmware sending BOARD_TYPE = "TTGO_TDISPLAY"):

Delta from connect Event
+0ms Connection established
+6.3s Pairing complete, bonded, encrypted
+8.0s get_version_info RPC received (35 bytes)
+8.1s CBOR response sent
+8.13s App disconnects (reason 531) — 20ms after response

The disconnect occurs 20ms after the response — confirming a synchronous decode failure, not a timeout.

Click to view Raw BLE/Console Logs
Executing action: monitor
Running idf_monitor in directory D:\GitHub\tdisplay\Jade
Executing "C:\Espressif\python_env\idf5.4_py3.11_env\Scripts\python.exe C:\Espressif\frameworks\esp-idf-v5.4\tools/idf_monitor.py -p COM5 -b 115200 --toolchain-prefix xtensa-esp32-elf- --target esp32 --revision 100 D:\GitHub\tdisplay\Jade\build\jade.elf --force-color -m 'C:\Espressif\python_env\idf5.4_py3.11_env\Scripts\python.exe' 'C:\Espressif\frameworks\esp-idf-v5.4\tools\idf.py' '-p' 'COM5'"...
--- Warning: GDB cannot open serial ports accessed as COMx
--- Using \\.\COM5 instead...
--- esp-idf-monitor 1.8.0 on \\.\COM5 115200
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H
ets Junets J]
             ��016�0:2&��j

rs���� (POW�}ISET�I����0x13BSPI�TMQ}LASH%==Q�
conV�ͥ�i 0,�*�]A�0xeeC�,k�E���0�0,qE���0x00,�E���0x00,�.����:0x0�
                                                                        }��v:0x��wp_���0A0
--- Warning: Failed to decode multiple lines in a row. Try checking the baud rate and XTAL frequency setting in menuconfig
m���DR� ␦��ck dZ��j��+��0x3ff�␦�����8�6
�+��0�007�00,lYK�ʊʒ
l+��0x����,le�'SH��+��0x����,le���Ӳj
entr^��Ѱ�063j
I (28) boot: ESP-IDF v5.4-dirty 2nd stage bootloader
I (28) boot: Multicore bootloader
I (29) boot: chip revision: v1.1
--- Warning: Failed to decode multiple lines in a row. Try checking the baud rate and XTAL frequency setting in menuconfig
I (29) boot.esp32: SPI Speed      : 40MHz
I (32) boot.esp32: SPI Mode       : DIO
I (36) boot.esp32: SPI Flash Size : 4MB
I (40) boot: Enabling RNG early entropy source...
I (44) boot: Partition Table:
I (47) boot: ## Label            Usage          Type ST Offset   Length
I (53) boot:  0 nvs              WiFi data        01 02 0000a000 00004000
I (60) boot:  1 otadata          OTA data         01 00 0000e000 00002000
I (66) boot:  2 ota_0            OTA app          00 10 00010000 001f0000
I (73) boot:  3 ota_1            OTA app          00 11 00200000 001f0000
I (79) boot:  4 nvs_key          NVS keys         01 04 003f0000 00001000
I (86) boot: End of partition table
I (89) boot: Enabled a check secure version of app for anti rollback
I (95) boot: Secure version (from eFuse) = 0
I (99) boot: otadata[0..1] in initial state
I (103) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=59f58h (368472) map
I (238) esp_image: segment 1: paddr=00069f80 vaddr=3ff80060 size=0001ch (    28) load
I (238) esp_image: segment 2: paddr=00069fa4 vaddr=3ffbdb60 size=06074h ( 24692) load
I (251) esp_image: segment 3: paddr=00070020 vaddr=400d0020 size=cf628h (849448) map
I (544) esp_image: segment 4: paddr=0013f650 vaddr=3ffc3bd4 size=004dch (  1244) load
I (545) esp_image: segment 5: paddr=0013fb34 vaddr=40080000 size=19d24h (105764) load
I (590) esp_image: segment 6: paddr=00159860 vaddr=400c0000 size=00060h (    96) load
I (604) boot: Loaded app from partition at offset 0x10000
I (655) boot: Set actual ota_seq=1 in otadata[0]
I (655) boot: Disabling RNG early entropy source...
I (664) cpu_start: Multicore app
I (673) cpu_start: Pro cpu start user code
I (673) cpu_start: cpu freq: 240000000 Hz
I (673) app_init: Application information:
I (673) app_init: App version:      1.0.38-82-ga9d475b9-dirty
I (678) app_init: Secure version:   0
I (682) app_init: ELF file SHA256:  9cf0af9dc...
I (686) app_init: ESP-IDF:          v5.4-dirty
I (690) efuse_init: Min chip rev:     v1.0
I (694) efuse_init: Max chip rev:     v3.99
I (698) efuse_init: Chip rev:         v1.1
I (702) heap_init: Initializing. RAM available for dynamic allocation:
I (708) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
I (713) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
I (718) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (723) heap_init: At 3FFC7EC8 len 00018138 (96 KiB): DRAM
I (729) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (734) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (739) heap_init: At 40099D24 len 000062DC (24 KiB): IRAM
I (746) spi_flash: detected chip: generic
I (748) spi_flash: flash io: dio
W (751) spi_flash: Detected size(16384k) larger than the size in the binary image header(4096k). Using the size in the binary image header.
I (765) main_task: Started on CPU0
I (775) main_task: Calling app_main()
I (775) main.c: 120: Running partition ptr: 0x3ffc8e54
I (775) main.c: 130: Running firmware version: 1.0.38-82-ga9d475b9-dirty
I (775) main.c: 142: Running partition state: 2
I (785) storage.c: 331: Calling nvs_flash_init()
I (805) storage.c: 186: nvs_get_blob() for keyflags - not found
I (805) display.c: 235: display/screen init
I (905) gpio: GPIO[4]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (905) gpio: GPIO[16]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (905) gpio: GPIO[23]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (1065) storage.c: 186: nvs_get_blob() for guiflags - not found
I (1065) main.c: 198: Showing splash screen
I (1175) idletimer.c: 204: esp_reset_reason: 1
I (1175) idletimer.c: 209: Resetting idle-state flag
I (1175) idletimer.c: 212: idle_state: 0
I (1175) idletimer.c: 217: powering screen, dimmed mode: 0
I (1175) gpio: GPIO[35]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (1185) button: IoTI (1195) sensitive.c: 90: Setting sens stack tls pointer to 0x3ffe35d8 for task 'main'
I (2225) wally_ext.c: 84: set_jade_wally_ctx() called by task 'main' with context 0x3ffe39e8
I (2245) wally_ext.c: 110: set_jade_wally_ctx() set context 0x3ffe3aac (0x3ffe39e8) for task 'main'
I (2255) ble.c: 477: Starting BLE by default (flags = 1)
I (2255) BTDM_INIT: BT controller compile version [20b459d]
I (2255) BTDM_INIT: Bluetooth MAC: 88:13:bf:fd:ae:41
I (2265) phy_init: phy_version 4840,02e0d70,Sep  2 2024,19:39:07
I (2515) ble.c: 438: BLE Host Task Started
I (2515) ble.c: 165: Registered service 0x1800 with handle=1
I (2515) ble.c: 170: Registering characteristic 0x2a00 with def_handle=2 val_handle=3
I (2515) ble.c: 170: Registering characteristic 0x2a01 with def_handle=4 val_handle=5
I (2525) ble.c: 165: Registered service 0x1801 with handle=6
I (2525) ble.c: 170: Registering characteristic 0x2a05 with def_handle=7 val_handle=8
I (2535) ble.c: 170: Registering characteristic 0x2b3a with def_handle=10 val_handle=11
I (2545) ble.c: 170: Registering characteristic 0x2b29 with def_handle=12 val_handle=13
I (2555) ble.c: 165: Registered service 6e400001-b5a3-f393-e0a9-e50e24dcca9e with handle=14
I (2565) ble.c: 170: Registering characteristic 6e400003-b5a3-f393-e0a9-e50e24dcca9e with def_handle=15 val_handle=16
I (2575) ble.c: 170: Registering characteristic 6e400002-b5a3-f393-e0a9-e50e24dcca9e with def_handle=18 val_handle=19
I (2615) idletimer.c: 127: Idle-timeout check - last-activity: 0, timeout period: 60000, projected-timeout: 60000, checktime: 185
I (2615) idletimer.c: 130: Idle task stack HWM: 520 free
I (2615) idletimer.c: 196: Next check in 6000
I (2625) ble.c: 384: ble sync() - Using RPA address
I (2635) ble.c: 233: ble_start_advertising() - Starting ble advertising with own_addr_type: 1
I (2645) ble.c: 285: Advertised address type: 1
I (2645) NimBLE: GAP procedure initiated: advertise;
I (2645) NimBLE: disc_mode=2
I (2645) NimBLE:  adv_channel_map=0 own_addr_type=1 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0
I (2655) NimBLE:

I (2665) ble.c: 299: Advertising started, (type 1, nrpa 0) with address:
I (2665) ble.c: 212: 46:1d:28:9f:91:e3
I (2685) main.c: 278: Starting dashboard on core 0, with priority 1
I (2685) dashboard.c: 2680: Starting: 37628
W (2685) gui.c: 680: Created unmanaged gui activity at 0x3fff6d34
I (2685) dashboard.c: 2769: Wallet/keys pin set but not yet loaded - showing home screen/Initialised
I (2695) dashboard.c: 2548: Main task stack HWM: 10036 free
I (2695) dashboard.c: 2549: DRAM block / free: 34816 / 35328
I (15525) ble.c: 581: Event 0
I (15525) ble.c: 587: connection established; status=0
I (15525) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (15525) ble.c: 212: 46:1d:28:9f:91:e3
I (15525) ble.c: 219:  our_id_addr_type=0 our_id_addr=
I (15535) ble.c: 212: 88:13:bf:fd:ae:41
I (15535) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (15535) ble.c: 212: f8:71:a6:34:07:ee
I (15545) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (15545) ble.c: 212: f8:71:a6:34:07:ee
I (15555) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=0 authenticated=0 bonded=0
I (15625) ble.c: 581: Event 38
I (15685) ble.c: 581: Event 34
I (15685) ble.c: 711: data length change event; conn_handle=0 max_tx_octets=251 max_tx_time=2120 max_rx_octets=251 max_rx_time=2120
I (15785) ble.c: 581: Event 15
I (15785) ble.c: 732: mtu update event; conn_handle=0 cid=4 mtu=517
I (16225) ble.c: 581: Event 17
I (16225) ble.c: 738: Repeat pairing
I (16295) ble.c: 581: Event 14
I (16295) ble.c: 718: subscribe event; conn_handle=0 attr_handle=8 reason=1 prevn=0 curn=0 previ=0 curi=1
I (16745) ble.c: 581: Event 11
I (16745) ble.c: 750: PASSKEY_ACTION_EVENT started: 4
I (16745) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (16745) ble.c: 212: 46:1d:28:9f:91:e3
I (16745) ble.c: 219:  our_id_addr_type=1 our_id_addr=
I (16755) ble.c: 212: 46:1d:28:9f:91:e3
I (16755) ble.c: 221:  peer_ota_addr_type=1 peer_ota_addr=
I (16765) ble.c: 212: 57:5e:30:3e:9b:eb
I (16765) ble.c: 223:  peer_id_addr_type=1 peer_id_addr=
I (16765) ble.c: 212: 57:5e:30:3e:9b:eb
I (16775) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=0 authenticated=0 bonded=0
I (16785) ble.c: 759: PASSKEY_ACTION_EVENT: NUMCMP
I (16785) ble.c: 761: Passkey on device's display: 637546
I (16795) ble.c: 767: Showing BLE confirm screen
I (20325) ble.c: 773: User pressed confirm
I (20815) ble.c: 581: Event 27
I (20825) ble.c: 581: Event 16
I (20825) ble.c: 680: identity resolved;
I (20825) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (20825) ble.c: 212: 46:1d:28:9f:91:e3
I (20825) ble.c: 219:  our_id_addr_type=1 our_id_addr=
I (20835) ble.c: 212: 46:1d:28:9f:91:e3
I (20835) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (20835) ble.c: 212: f8:71:a6:34:07:ee
I (20845) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (20845) ble.c: 212: f8:71:a6:34:07:ee
I (20855) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=1 authenticated=1 bonded=1
I (20885) ble.c: 581: Event 10
I (20885) ble.c: 704: encryption change event; status=0
I (20885) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (20885) ble.c: 212: 46:1d:28:9f:91:e3
I (20895) ble.c: 219:  our_id_addr_type=0 our_id_addr=
I (20895) ble.c: 212: 88:13:bf:fd:ae:41
I (20895) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (20905) ble.c: 212: f8:71:a6:34:07:ee
I (20905) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (20915) ble.c: 212: f8:71:a6:34:07:ee
I (20915) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=1 authenticated=1 bonded=1
I (20935) ble.c: 581: Event 14
I (20935) ble.c: 718: subscribe event; conn_handle=0 attr_handle=16 reason=1 prevn=0 curn=0 previ=0 curi=1
I (22255) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (22255) ble.c: 90: Reading from ble device
I (22255) ble.c: 93: Reading 35 bytes
I (22285) NimBLE: GATT procedure initiated: indicate;
I (22285) NimBLE: att_handle=16

I (22285) dashboard.c: 2548: Main task stack HWM: 10004 free
I (22285) ble.c: 581: Event 13
I (22285) dashboard.c: 2549: DRAM block / free: 34816 / 58512
I (22285) ble.c: 688: notify tx received, notifying writer
I (22435) ble.c: 581: Event 13
I (22435) ble.c: 688: notify tx received, notifying writer
I (22435) ble.c: 581: Event 14
I (22435) ble.c: 718: subscribe event; conn_handle=0 attr_handle=8 reason=2 prevn=0 curn=0 previ=1 curi=0
I (22445) ble.c: 581: Event 14
I (22445) ble.c: 718: subscribe event; conn_handle=0 attr_handle=16 reason=2 prevn=0 curn=0 previ=1 curi=0
I (22465) ble.c: 581: Event 1
I (22465) ble.c: 629: disconnect; reason=531
I (22465) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (22465) ble.c: 212: 46:1d:28:9f:91:e3
I (22475) ble.c: 219:  our_id_addr_type=0 our_id_addr=
I (22475) ble.c: 212: 88:13:bf:fd:ae:41
I (22485) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (22485) ble.c: 212: f8:71:a6:34:07:ee
I (22495) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (22495) ble.c: 212: f8:71:a6:34:07:ee
I (22495) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=1 authenticated=1 bonded=1
I (22505) ble.c: 233: ble_start_advertising() - Starting ble advertising with own_addr_type: 1
I (22515) ble.c: 285: Advertised address type: 1
I (22525) NimBLE: GAP procedure initiated: advertise;
I (22525) NimBLE: disc_mode=2
I (22525) NimBLE:  adv_channel_map=0 own_addr_type=1 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0
I (22535) NimBLE:

I (22545) ble.c: 299: Advertising started, (type 1, nrpa 0) with address:
I (22545) ble.c: 212: 46:1d:28:9f:91:e3
I (27835) ble.c: 581: Event 0
I (27835) ble.c: 587: connection established; status=0
I (27835) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (27845) ble.c: 212: 46:1d:28:9f:91:e3
I (27845) ble.c: 219:  our_id_addr_type=0 our_id_addr=
I (27845) ble.c: 212: 88:13:bf:fd:ae:41
I (27855) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (27855) ble.c: 212: f8:71:a6:34:07:ee
I (27865) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (27865) ble.c: 212: f8:71:a6:34:07:ee
I (27865) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=0 authenticated=0 bonded=0
I (28225) ble.c: 581: Event 27
I (28225) ble.c: 581: Event 10
I (28225) ble.c: 704: encryption change event; status=0
I (28225) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (28235) ble.c: 212: 46:1d:28:9f:91:e3
I (28235) ble.c: 219:  our_id_addr_type=0 our_id_addr=
I (28235) ble.c: 212: 88:13:bf:fd:ae:41
I (28245) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (28245) ble.c: 212: f8:71:a6:34:07:ee
I (28255) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (28255) ble.c: 212: f8:71:a6:34:07:ee
I (28255) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=1 authenticated=1 bonded=1
I (28265) ble.c: 581: Event 14
I (28275) ble.c: 718: subscribe event; conn_handle=0 attr_handle=8 reason=3 prevn=0 curn=0 previ=0 curi=1
I (28285) ble.c: 581: Event 14
I (28285) ble.c: 718: subscribe event; conn_handle=0 attr_handle=16 reason=3 prevn=0 curn=0 previ=0 curi=1
I (28295) ble.c: 581: Event 38
I (28315) ble.c: 581: Event 34
I (28315) ble.c: 711: data length change event; conn_handle=0 max_tx_octets=251 max_tx_time=2120 max_rx_octets=251 max_rx_time=2120
I (28375) ble.c: 581: Event 15
I (28375) ble.c: 732: mtu update event; conn_handle=0 cid=4 mtu=517
I (28495) ble.c: 581: Event 14
I (28495) ble.c: 718: subscribe event; conn_handle=0 attr_handle=16 reason=1 prevn=0 curn=0 previ=1 curi=0
I (28645) ble.c: 581: Event 14
I (28645) ble.c: 718: subscribe event; conn_handle=0 attr_handle=16 reason=1 prevn=0 curn=0 previ=0 curi=1
I (28735) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (28735) ble.c: 90: Reading from ble device
I (28735) ble.c: 93: Reading 35 bytes
I (28815) NimBLE: GATT procedure initiated: indicate;
I (28815) NimBLE: att_handle=16

I (28815) dashboard.c: 2548: Main task stack HWM: 10004 free
I (28815) ble.c: 581: Event 13
I (28815) dashboard.c: 2549: DRAM block / free: 34816 / 60200
I (28815) ble.c: 688: notify tx received, notifying writer
I (28885) ble.c: 581: Event 13
I (28885) ble.c: 688: notify tx received, notifying writer
I (28885) ble.c: 581: Event 14
I (28885) ble.c: 718: subscribe event; conn_handle=0 attr_handle=8 reason=2 prevn=0 curn=0 previ=1 curi=0
I (28895) ble.c: 581: Event 14
I (28895) ble.c: 718: subscribe event; conn_handle=0 attr_handle=16 reason=2 prevn=0 curn=0 previ=1 curi=0
I (28915) ble.c: 581: Event 1
I (28915) ble.c: 629: disconnect; reason=531
I (28915) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (28925) ble.c: 212: 46:1d:28:9f:91:e3
I (28925) ble.c: 219:  our_id_addr_type=0 our_id_addr=
I (28925) ble.c: 212: 88:13:bf:fd:ae:41
I (28935) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (28935) ble.c: 212: f8:71:a6:34:07:ee
I (28945) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (28945) ble.c: 212: f8:71:a6:34:07:ee
I (28945) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=1 authenticated=1 bonded=1
I (28955) ble.c: 233: ble_start_advertising() - Starting ble advertising with own_addr_type: 1
I (28965) ble.c: 285: Advertised address type: 1
I (28975) NimBLE: GAP procedure initiated: advertise;
I (28975) NimBLE: disc_mode=2
I (28975) NimBLE:  adv_channel_map=0 own_addr_type=1 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0
I (28985) NimBLE:

I (28995) ble.c: 299: Advertising started, (type 1, nrpa 0) with address:
I (28995) ble.c: 212: 46:1d:28:9f:91:e3

After fix (firmware sending BOARD_TYPE = "JADE"):

Delta from connect Event
+8.0s get_version_info accepted
+37s auth_user → PIN verified → Success
+40s+ get_xpubs, sign_message, get_receive_address — all working
Click to view Raw BLE/Console Logs
Executing action: monitor
Running idf_monitor in directory D:\GitHub\tdisplay\Jade
Executing "C:\Espressif\python_env\idf5.4_py3.11_env\Scripts\python.exe C:\Espressif\frameworks\esp-idf-v5.4\tools/idf_monitor.py -p COM5 -b 115200 --toolchain-prefix xtensa-esp32-elf- --target esp32 --revision 100 D:\GitHub\tdisplay\Jade\build\jade.elf --force-color -m 'C:\Espressif\python_env\idf5.4_py3.11_env\Scripts\python.exe' 'C:\Espressif\frameworks\esp-idf-v5.4\tools\idf.py' '-p' 'COM5'"...
--- Warning: GDB cannot open serial ports accessed as COMx
--- Using \\.\COM5 instead...
--- esp-idf-monitor 1.8.0 on \\.\COM5 115200
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H
�W��]
     8�������ҵ�H�
�.��xL��jUI��%�EU�      ��W¸�&BSU��P*�%1A�������˙i�N
                                                    i�b���]�:eC�,k}d��¸�,\E�������}�r�����.z�r�������v���0������A0C����'T���o--- Warning: Failed to decode multiple lines in a row. Try checking the baud rate and XTAL frequency setting in menuconfig
"���j��+�:�Mf�A�,��Y��0&S�l�X����0���0���'ʱN�H��a��¸��k�:�H���V¸��0�����3�MSHh��.A��0��6&j�I (28) boot: ESP-IDF v5.4-dirty 2nd stage bootloader
I (28) boot: Multicore bootloader
I (28) boot: chip revision: v1.1
I (29) boot.esp32: SPI Speed      : 40MHz
I (32) boot.esp32: SPI Mode       : DIO
I (36) boot.esp32: SPI Flash Size : 4MB
I (39) boot: Enabling RNG early entropy source...
I (44) boot: Partition Table:
I (46) boot: ## Label            Usage          Type ST Offset   Length
I (53) boot:  0 nvs              WiFi data        01 02 0000a000 00004000
I (59) boot:  1 otadata          OTA data         01 00 0000e000 00002000
I (66) boot:  2 ota_0            OTA app          00 10 00010000 001f0000
I (72) boot:  3 ota_1            OTA app          00 11 00200000 001f0000
I (79) boot:  4 nvs_key          NVS keys         01 04 003f0000 00001000
I (85) boot: End of partition table
I (89) boot: Enabled a check secure version of app for anti rollback
I (95) boot: Secure version (from eFuse) = 0
I (99) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=59f48h (368456) map
I (233) esp_image: segment 1: paddr=00069f70 vaddr=3ff80060 size=0001ch (    28) load
I (234) esp_image: segment 2: paddr=00069f94 vaddr=3ffbdb60 size=06084h ( 24708) load
I (247) esp_image: segment 3: paddr=00070020 vaddr=400d0020 size=cf628h (849448) map
I (540) esp_image: segment 4: paddr=0013f650 vaddr=3ffc3be4 size=004cch (  1228) load
I (540) esp_image: segment 5: paddr=0013fb24 vaddr=40080000 size=19d24h (105764) load
I (586) esp_image: segment 6: paddr=00159850 vaddr=400c0000 size=00060h (    96) load
I (600) boot: Loaded app from partition at offset 0x10000
I (600) boot: Disabling RNG early entropy source...
I (610) cpu_start: Multicore app
I (618) cpu_start: Pro cpu start user code
I (618) cpu_start: cpu freq: 240000000 Hz
I (619) app_init: Application information:
I (619) app_init: App version:      1.0.38-82-ga9d475b9-dirty
I (624) app_init: Secure version:   0
I (627) app_init: ELF file SHA256:  60150b4e1...
I (632) app_init: ESP-IDF:          v5.4-dirty
I (636) efuse_init: Min chip rev:     v1.0
I (640) efuse_init: Max chip rev:     v3.99
I (644) efuse_init: Chip rev:         v1.1
I (648) heap_init: Initializing. RAM available for dynamic allocation:
I (654) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
I (659) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
I (664) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (669) heap_init: At 3FFC7EC8 len 00018138 (96 KiB): DRAM
I (674) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (680) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (685) heap_init: At 40099D24 len 000062DC (24 KiB): IRAM
I (691) spi_flash: detected chip: generic
I (694) spi_flash: flash io: dio
W (697) spi_flash: Detected size(16384k) larger than the size in the binary image header(4096k). Using the size in the binary image header.
I (711) main_task: Started on CPU0
I (721) main_task: Calling app_main()
I (721) main.c: 120: Running partition ptr: 0x3ffc8e54
I (721) main.c: 130: Running firmware version: 1.0.38-82-ga9d475b9-dirty
I (721) main.c: 142: Running partition state: 2
I (731) storage.c: 331: Calling nvs_flash_init()
I (751) storage.c: 186: nvs_get_blob() for keyflags - not found
I (751) display.c: 235: display/screen init
I (851) gpio: GPIO[4]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (851) gpio: GPIO[16]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (851) gpio: GPIO[23]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (1011) storage.c: 186: nvs_get_blob() for guiflags - not found
I (1011) main.c: 198: Showing splash screen
I (1121) idletimer.c: 204: esp_reset_reason: 1
I (1121) idletimer.c: 209: Resetting idle-state flag
I (1121) idletimer.c: 212: idle_state: 0
I (1121) idletimer.c: 217: powering screen, dimmed mode: 0
I (1121) gpio: GPIO[35]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (1131) button: IoTI (1141) sensitive.c: 90: Setting sens stack tls pointer to 0x3ffe3558 for task 'main'
I (2171) wally_ext.c: 84: set_jade_wally_ctx() called by task 'main' with context 0x3ffe3968
I (2191) wally_ext.c: 110: set_jade_wally_ctx() set context 0x3ffe3a2c (0x3ffe3968) for task 'main'
I (2201) ble.c: 477: Starting BLE by default (flags = 1)
I (2201) BTDM_INIT: BT controller compile version [20b459d]
I (2201) BTDM_INIT: Bluetooth MAC: 88:13:bf:fd:ae:41
I (2211) phy_init: phy_version 4840,02e0d70,Sep  2 2024,19:39:07
I (2441) ble.c: 438: BLE Host Task Started
I (2441) ble.c: 165: Registered service 0x1800 with handle=1
I (2451) ble.c: 170: Registering characteristic 0x2a00 with def_handle=2 val_handle=3
I (2451) ble.c: 170: Registering characteristic 0x2a01 with def_handle=4 val_handle=5
I (2461) ble.c: 165: Registered service 0x1801 with handle=6
I (2461) ble.c: 170: Registering characteristic 0x2a05 with def_handle=7 val_handle=8
I (2471) ble.c: 170: Registering characteristic 0x2b3a with def_handle=10 val_handle=11
I (2481) ble.c: 170: Registering characteristic 0x2b29 with def_handle=12 val_handle=13
I (2491) ble.c: 165: Registered service 6e400001-b5a3-f393-e0a9-e50e24dcca9e with handle=14
I (2491) ble.c: 170: Registering characteristic 6e400003-b5a3-f393-e0a9-e50e24dcca9e with def_handle=15 val_handle=16
I (2501) ble.c: 170: Registering characteristic 6e400002-b5a3-f393-e0a9-e50e24dcca9e with def_handle=18 val_handle=19
I (2531) idletimer.c: 127: Idle-timeout check - last-activity: 0, timeout period: 60000, projected-timeout: 60000, checktime: 182
I (2531) idletimer.c: 130: Idle task stack HWM: 508 free
I (2531) idletimer.c: 196: Next check in 6000
I (2561) ble.c: 384: ble sync() - Using RPA address
I (2571) ble.c: 233: ble_start_advertising() - Starting ble advertising with own_addr_type: 1
I (2571) ble.c: 285: Advertised address type: 1
I (2581) NimBLE: GAP procedure initiated: advertise;
I (2581) NimBLE: disc_mode=2
I (2581) NimBLE:  adv_channel_map=0 own_addr_type=1 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0
I (2591) NimBLE:

I (2601) ble.c: 299: Advertising started, (type 1, nrpa 0) with address:
I (2601) ble.c: 212: 53:13:1d:24:1e:82
I (2611) main.c: 278: Starting dashboard on core 0, with priority 1
I (2611) dashboard.c: 2680: Starting: 37748
W (2611) gui.c: 680: Created unmanaged gui activity at 0x3fff6cb8
I (2621) dashboard.c: 2769: Wallet/keys pin set but not yet loaded - showing home screen/Initialised
I (2631) dashboard.c: 2548: Main task stack HWM: 10036 free
I (2631) dashboard.c: 2549: DRAM block / free: 34816 / 35452
I (47581) ble.c: 581: Event 0
I (47581) ble.c: 587: connection established; status=0
I (47581) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (47581) ble.c: 212: 53:13:1d:24:1e:82
I (47591) ble.c: 219:  our_id_addr_type=0 our_id_addr=
I (47591) ble.c: 212: 88:13:bf:fd:ae:41
I (47601) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (47601) ble.c: 212: f8:71:a6:34:07:ee
I (47611) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (47611) ble.c: 212: f8:71:a6:34:07:ee
I (47611) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=0 authenticated=0 bonded=0
I (47671) ble.c: 581: Event 38
I (47701) ble.c: 581: Event 34
I (47701) ble.c: 711: data length change event; conn_handle=0 max_tx_octets=251 max_tx_time=2120 max_rx_octets=251 max_rx_time=2120
I (47771) ble.c: 581: Event 15
I (47771) ble.c: 732: mtu update event; conn_handle=0 cid=4 mtu=517
I (48301) ble.c: 581: Event 14
I (48301) ble.c: 718: subscribe event; conn_handle=0 attr_handle=8 reason=1 prevn=0 curn=0 previ=0 curi=1
I (48311) ble.c: 581: Event 17
I (48311) ble.c: 738: Repeat pairing
I (48791) ble.c: 581: Event 11
I (48791) ble.c: 750: PASSKEY_ACTION_EVENT started: 4
I (48791) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (48791) ble.c: 212: 53:13:1d:24:1e:82
I (48791) ble.c: 219:  our_id_addr_type=1 our_id_addr=
I (48801) ble.c: 212: 53:13:1d:24:1e:82
I (48801) ble.c: 221:  peer_ota_addr_type=1 peer_ota_addr=
I (48811) ble.c: 212: 49:59:62:52:10:81
I (48811) ble.c: 223:  peer_id_addr_type=1 peer_id_addr=
I (48821) ble.c: 212: 49:59:62:52:10:81
I (48821) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=0 authenticated=0 bonded=0
I (48831) ble.c: 759: PASSKEY_ACTION_EVENT: NUMCMP
I (48831) ble.c: 761: Passkey on device's display: 216266
I (48841) ble.c: 767: Showing BLE confirm screen
I (53251) ble.c: 773: User pressed confirm
I (53701) ble.c: 581: Event 14
I (53701) ble.c: 718: subscribe event; conn_handle=0 attr_handle=16 reason=1 prevn=0 curn=0 previ=0 curi=1
I (53821) ble.c: 581: Event 27
I (53841) ble.c: 581: Event 16
I (53841) ble.c: 680: identity resolved;
I (53841) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (53841) ble.c: 212: 53:13:1d:24:1e:82
I (53841) ble.c: 219:  our_id_addr_type=1 our_id_addr=
I (53851) ble.c: 212: 53:13:1d:24:1e:82
I (53851) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (53851) ble.c: 212: f8:71:a6:34:07:ee
I (53861) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (53861) ble.c: 212: f8:71:a6:34:07:ee
I (53871) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=1 authenticated=1 bonded=1
I (53901) ble.c: 581: Event 10
I (53901) ble.c: 704: encryption change event; status=0
I (53901) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (53901) ble.c: 212: 53:13:1d:24:1e:82
I (53901) ble.c: 219:  our_id_addr_type=0 our_id_addr=
I (53911) ble.c: 212: 88:13:bf:fd:ae:41
I (53911) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (53921) ble.c: 212: f8:71:a6:34:07:ee
I (53921) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (53931) ble.c: 212: f8:71:a6:34:07:ee
I (53931) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=1 authenticated=1 bonded=1
I (55501) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (55501) ble.c: 90: Reading from ble device
I (55501) ble.c: 93: Reading 35 bytes
I (55511) NimBLE: GATT procedure initiated: indicate;
I (55511) NimBLE: att_handle=16

I (55511) dashboard.c: 2548: Main task stack HWM: 10004 free
I (55521) ble.c: 581: Event 13
I (55521) dashboard.c: 2549: DRAM block / free: 34816 / 58504
I (55521) ble.c: 688: notify tx received, notifying writer
I (55631) ble.c: 581: Event 13
I (55631) ble.c: 688: notify tx received, notifying writer
I (55631) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (55631) ble.c: 90: Reading from ble device
I (55631) ble.c: 93: Reading 35 bytes
I (55671) NimBLE: GATT procedure initiated: indicate;
I (55671) NimBLE: att_handle=16

I (55671) dashboard.c: 2548: Main task stack HWM: 10004 free
I (55671) ble.c: 581: Event 13
I (55671) dashboard.c: 2549: DRAM block / free: 34816 / 60192
I (55671) ble.c: 688: notify tx received, notifying writer
I (55751) ble.c: 581: Event 13
I (55751) ble.c: 688: notify tx received, notifying writer
I (55831) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (55831) ble.c: 90: Reading from ble device
I (55831) ble.c: 93: Reading 35 bytes
I (55841) NimBLE: GATT procedure initiated: indicate;
I (55841) NimBLE: att_handle=16

I (55841) dashboard.c: 2548: Main task stack HWM: 9972 free
I (55851) ble.c: 581: Event 13
I (55851) dashboard.c: 2549: DRAM block / free: 34816 / 60192
I (55851) ble.c: 688: notify tx received, notifying writer
I (55961) ble.c: 581: Event 13
I (55961) ble.c: 688: notify tx received, notifying writer
I (55961) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (55961) ble.c: 90: Reading from ble device
I (55961) ble.c: 93: Reading 35 bytes
I (56011) NimBLE: GATT procedure initiated: indicate;
I (56011) NimBLE: att_handle=16

I (56011) ble.c: 581: Event 13
I (56011) ble.c: 688: notify tx received, notifying writer
I (56011) dashboard.c: 2548: Main task stack HWM: 9972 free
I (56021) dashboard.c: 2549: DRAM block / free: 34816 / 60192
I (56131) ble.c: 581: Event 13
I (56131) ble.c: 688: notify tx received, notifying writer
I (56131) ble.c: 581: Event 14
I (56131) ble.c: 718: subscribe event; conn_handle=0 attr_handle=8 reason=2 prevn=0 curn=0 previ=1 curi=0
I (56141) ble.c: 581: Event 14
I (56141) ble.c: 718: subscribe event; conn_handle=0 attr_handle=16 reason=2 prevn=0 curn=0 previ=1 curi=0
I (56161) ble.c: 581: Event 1
I (56161) ble.c: 629: disconnect; reason=531
I (56161) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (56171) ble.c: 212: 53:13:1d:24:1e:82
I (56171) ble.c: 219:  our_id_addr_type=0 our_id_addr=
I (56171) ble.c: 212: 88:13:bf:fd:ae:41
I (56181) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (56181) ble.c: 212: f8:71:a6:34:07:ee
I (56191) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (56191) ble.c: 212: f8:71:a6:34:07:ee
I (56191) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=1 authenticated=1 bonded=1
I (56201) ble.c: 233: ble_start_advertising() - Starting ble advertising with own_addr_type: 1
I (56221) ble.c: 285: Advertised address type: 1
I (56221) NimBLE: GAP procedure initiated: advertise;
I (56221) NimBLE: disc_mode=2
I (56221) NimBLE:  adv_channel_map=0 own_addr_type=1 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0
I (56231) NimBLE:

I (56241) ble.c: 299: Advertising started, (type 1, nrpa 0) with address:
I (56241) ble.c: 212: 53:13:1d:24:1e:82
I (62541) idletimer.c: 127: Idle-timeout check - last-activity: 5526, timeout period: 60000, projected-timeout: 65526, checktime: 6183
I (62541) idletimer.c: 130: Idle task stack HWM: 508 free
I (62551) idletimer.c: 196: Next check in 6000
I (66171) ble.c: 581: Event 0
I (66171) ble.c: 587: connection established; status=0
I (66171) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (66171) ble.c: 212: 53:13:1d:24:1e:82
I (66171) ble.c: 219:  our_id_addr_type=0 our_id_addr=
I (66181) ble.c: 212: 88:13:bf:fd:ae:41
I (66181) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (66191) ble.c: 212: f8:71:a6:34:07:ee
I (66191) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (66191) ble.c: 212: f8:71:a6:34:07:ee
I (66201) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=0 authenticated=0 bonded=0
I (66271) ble.c: 581: Event 38
I (66721) ble.c: 581: Event 27
I (66721) ble.c: 581: Event 10
I (66721) ble.c: 704: encryption change event; status=0
I (66721) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (66731) ble.c: 212: 53:13:1d:24:1e:82
I (66731) ble.c: 219:  our_id_addr_type=0 our_id_addr=
I (66741) ble.c: 212: 88:13:bf:fd:ae:41
I (66741) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (66741) ble.c: 212: f8:71:a6:34:07:ee
I (66751) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (66751) ble.c: 212: f8:71:a6:34:07:ee
I (66761) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=1 authenticated=1 bonded=1
I (66771) ble.c: 581: Event 14
I (66771) ble.c: 718: subscribe event; conn_handle=0 attr_handle=8 reason=3 prevn=0 curn=0 previ=0 curi=1
I (66781) ble.c: 581: Event 14
I (66781) ble.c: 718: subscribe event; conn_handle=0 attr_handle=16 reason=3 prevn=0 curn=0 previ=0 curi=1
I (66811) ble.c: 581: Event 34
I (66811) ble.c: 711: data length change event; conn_handle=0 max_tx_octets=251 max_tx_time=2120 max_rx_octets=251 max_rx_time=2120
I (66821) ble.c: 581: Event 15
I (66821) ble.c: 732: mtu update event; conn_handle=0 cid=4 mtu=517
I (66961) ble.c: 581: Event 14
I (66961) ble.c: 718: subscribe event; conn_handle=0 attr_handle=16 reason=1 prevn=0 curn=0 previ=1 curi=0
I (67021) ble.c: 581: Event 14
I (67021) ble.c: 718: subscribe event; conn_handle=0 attr_handle=16 reason=1 prevn=0 curn=0 previ=0 curi=1
I (67081) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (67081) ble.c: 90: Reading from ble device
I (67081) ble.c: 93: Reading 35 bytes
I (67091) NimBLE: GATT procedure initiated: indicate;
I (67091) NimBLE: att_handle=16

I (67091) dashboard.c: 2548: Main task stack HWM: 9972 free
I (67101) ble.c: 581: Event 13
I (67101) dashboard.c: 2549: DRAM block / free: 34816 / 60192
I (67101) ble.c: 688: notify tx received, notifying writer
I (67271) ble.c: 581: Event 13
I (67271) ble.c: 688: notify tx received, notifying writer
I (67271) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (67271) ble.c: 90: Reading from ble device
I (67271) ble.c: 93: Reading 35 bytes
I (67281) NimBLE: GATT procedure initiated: indicate;
I (67281) NimBLE: att_handle=16

I (67281) dashboard.c: 2548: Main task stack HWM: 9972 free
I (67291) ble.c: 581: Event 13
I (67291) ble.c: 688: notify tx received, notifying writer
I (67291) dashboard.c: 2549: DRAM block / free: 34816 / 60192
I (67361) ble.c: 581: Event 13
I (67361) ble.c: 688: notify tx received, notifying writer
I (67361) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (67361) ble.c: 90: Reading from ble device
I (67371) ble.c: 93: Reading 35 bytes
I (67441) NimBLE: GATT procedure initiated: indicate;
I (67441) NimBLE: att_handle=16

I (67441) ble.c: 581: Event 13
I (67441) ble.c: 688: notify tx received, notifying writer
I (67441) dashboard.c: 2548: Main task stack HWM: 9908 free
I (67451) dashboard.c: 2549: DRAM block / free: 34816 / 60192
I (67571) ble.c: 581: Event 13
I (67571) ble.c: 688: notify tx received, notifying writer
I (67571) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (67571) ble.c: 90: Reading from ble device
I (67571) ble.c: 93: Reading 35 bytes
I (67591) NimBLE: GATT procedure initiated: indicate;
I (67591) NimBLE: att_handle=16

I (67591) ble.c: 581: Event 13
I (67591) ble.c: 688: notify tx received, notifying writer
I (67591) dashboard.c: 2548: Main task stack HWM: 9908 free
I (67601) dashboard.c: 2549: DRAM block / free: 34816 / 60192
I (67711) ble.c: 581: Event 13
I (67711) ble.c: 688: notify tx received, notifying writer
I (67711) ble.c: 581: Event 14
I (67711) ble.c: 718: subscribe event; conn_handle=0 attr_handle=8 reason=2 prevn=0 curn=0 previ=1 curi=0
I (67721) ble.c: 581: Event 14
I (67731) ble.c: 718: subscribe event; conn_handle=0 attr_handle=16 reason=2 prevn=0 curn=0 previ=1 curi=0
I (67741) ble.c: 581: Event 1
I (67741) ble.c: 629: disconnect; reason=531
I (67741) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (67751) ble.c: 212: 53:13:1d:24:1e:82
I (67751) ble.c: 219:  our_id_addr_type=0 our_id_addr=
I (67761) ble.c: 212: 88:13:bf:fd:ae:41
I (67761) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (67761) ble.c: 212: f8:71:a6:34:07:ee
I (67771) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (67771) ble.c: 212: f8:71:a6:34:07:ee
I (67781) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=1 authenticated=1 bonded=1
I (67791) ble.c: 233: ble_start_advertising() - Starting ble advertising with own_addr_type: 1
I (67801) ble.c: 285: Advertised address type: 1
I (67801) NimBLE: GAP procedure initiated: advertise;
I (67801) NimBLE: disc_mode=2
I (67811) NimBLE:  adv_channel_map=0 own_addr_type=1 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0
I (67811) NimBLE:

I (67821) ble.c: 299: Advertising started, (type 1, nrpa 0) with address:
I (67821) ble.c: 212: 53:13:1d:24:1e:82
I (67951) ble.c: 581: Event 0
I (67951) ble.c: 587: connection established; status=0
I (67951) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (67951) ble.c: 212: 53:13:1d:24:1e:82
I (67961) ble.c: 219:  our_id_addr_type=0 our_id_addr=
I (67961) ble.c: 212: 88:13:bf:fd:ae:41
I (67961) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (67971) ble.c: 212: f8:71:a6:34:07:ee
I (67971) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (67981) ble.c: 212: f8:71:a6:34:07:ee
I (67981) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=0 authenticated=0 bonded=0
I (68191) ble.c: 581: Event 27
I (68191) ble.c: 581: Event 10
I (68191) ble.c: 704: encryption change event; status=0
I (68191) ble.c: 217: handle=0 our_ota_addr_type=1 our_ota_addr=
I (68201) ble.c: 212: 53:13:1d:24:1e:82
I (68201) ble.c: 219:  our_id_addr_type=0 our_id_addr=
I (68211) ble.c: 212: 88:13:bf:fd:ae:41
I (68211) ble.c: 221:  peer_ota_addr_type=0 peer_ota_addr=
I (68211) ble.c: 212: f8:71:a6:34:07:ee
I (68221) ble.c: 223:  peer_id_addr_type=0 peer_id_addr=
I (68221) ble.c: 212: f8:71:a6:34:07:ee
I (68231) ble.c: 225:  conn_itvl=24 conn_latency=0 supervision_timeout=72 encrypted=1 authenticated=1 bonded=1
I (68241) ble.c: 581: Event 14
I (68241) ble.c: 718: subscribe event; conn_handle=0 attr_handle=8 reason=3 prevn=0 curn=0 previ=0 curi=1
I (68251) ble.c: 581: Event 14
I (68251) ble.c: 718: subscribe event; conn_handle=0 attr_handle=16 reason=3 prevn=0 curn=0 previ=0 curi=1
I (68281) ble.c: 581: Event 38
I (68311) ble.c: 581: Event 34
I (68311) ble.c: 711: data length change event; conn_handle=0 max_tx_octets=251 max_tx_time=2120 max_rx_octets=251 max_rx_time=2120
I (68351) ble.c: 581: Event 15
I (68351) ble.c: 732: mtu update event; conn_handle=0 cid=4 mtu=517
I (68551) ble.c: 581: Event 14
I (68551) ble.c: 718: subscribe event; conn_handle=0 attr_handle=16 reason=1 prevn=0 curn=0 previ=1 curi=0
I (68611) ble.c: 581: Event 14
I (68611) ble.c: 718: subscribe event; conn_handle=0 attr_handle=16 reason=1 prevn=0 curn=0 previ=0 curi=1
I (68701) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (68701) ble.c: 90: Reading from ble device
I (68701) ble.c: 93: Reading 35 bytes
I (68781) NimBLE: GATT procedure initiated: indicate;
I (68781) NimBLE: att_handle=16

I (68781) dashboard.c: 2548: Main task stack HWM: 9908 free
I (68781) ble.c: 581: Event 13
I (68781) dashboard.c: 2549: DRAM block / free: 34816 / 60192
I (68781) ble.c: 688: notify tx received, notifying writer
I (68861) ble.c: 581: Event 13
I (68861) ble.c: 688: notify tx received, notifying writer
I (68861) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (68861) ble.c: 90: Reading from ble device
I (68861) ble.c: 93: Reading 35 bytes
I (68931) NimBLE: GATT procedure initiated: indicate;
I (68931) NimBLE: att_handle=16

I (68931) dashboard.c: 2548: Main task stack HWM: 9908 free
I (68931) ble.c: 581: Event 13
I (68931) dashboard.c: 2549: DRAM block / free: 34816 / 60192
I (68931) ble.c: 688: notify tx received, notifying writer
I (69011) ble.c: 581: Event 13
I (69011) ble.c: 688: notify tx received, notifying writer
I (69091) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (69091) ble.c: 90: Reading from ble device
I (69091) ble.c: 93: Reading 35 bytes
I (69101) NimBLE: GATT procedure initiated: indicate;
I (69101) NimBLE: att_handle=16

I (69101) dashboard.c: 2548: Main task stack HWM: 9908 free
I (69111) ble.c: 581: Event 13
I (69111) dashboard.c: 2549: DRAM block / free: 34816 / 60192
I (69111) ble.c: 688: notify tx received, notifying writer
I (69191) ble.c: 581: Event 13
I (69191) ble.c: 688: notify tx received, notifying writer
I (69271) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (69271) ble.c: 90: Reading from ble device
I (69271) ble.c: 93: Reading 80 bytes
I (69281) NimBLE: GATT procedure initiated: indicate;
I (69281) NimBLE: att_handle=16

I (69281) dashboard.c: 2548: Main task stack HWM: 9844 free
I (69291) ble.c: 581: Event 13
I (69291) dashboard.c: 2549: DRAM block / free: 34816 / 60192
I (69291) ble.c: 688: notify tx received, notifying writer
I (69401) ble.c: 581: Event 13
I (69401) ble.c: 688: notify tx received, notifying writer
I (69401) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (69401) ble.c: 90: Reading from ble device
I (69401) ble.c: 93: Reading 35 bytes
I (69441) NimBLE: GATT procedure initiated: indicate;
I (69441) NimBLE: att_handle=16

I (69441) dashboard.c: 2548: Main task stack HWM: 9844 free
I (69441) ble.c: 581: Event 13
I (69441) dashboard.c: 2549: DRAM block / free: 34816 / 60192
I (69441) ble.c: 688: notify tx received, notifying writer
I (69521) ble.c: 581: Event 13
I (69521) ble.c: 688: notify tx received, notifying writer
I (74821) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (74821) ble.c: 90: Reading from ble device
I (74821) ble.c: 93: Reading 63 bytes
I (74931) auth_user.c: 349: Starting: 60124
I (74931) auth_user.c: 411: keychain locked for this source, requesting pin
W (75091) gui.c: 2464: gui task handled 7 jobs
W (78111) gui.c: 2464: gui task handled 8 jobs
W (79201) gui.c: 2464: gui task handled 8 jobs
W (80651) gui.c: 2464: gui task handled 8 jobs
W (81801) gui.c: 2464: gui task handled 8 jobs
W (83421) gui.c: 2464: gui task handled 8 jobs
I (106891) pinclient.c: 568: Fetching pinserver data
I (106931) storage.c: 186: nvs_get_blob() for pinsvrpubkey - not found
I (106941) pinclient.c: 474: Generating pinserver payload
I (107001) storage.c: 228: nvs_get_str() for pinsvrurlA - not found
I (107001) storage.c: 228: nvs_get_str() for pinsvrurlB - not found
I (107001) storage.c: 228: nvs_get_str() for pinsvrcert - not found
I (107031) NimBLE: GATT procedure initiated: indicate;
I (107031) NimBLE: att_handle=16

I (107031) ble.c: 581: Event 13
I (107031) ble.c: 688: notify tx received, notifying writer
W (107041) gui.c: 2464: gui task handled 5 jobs
I (107081) ble.c: 581: Event 13
I (107081) ble.c: 688: notify tx received, notifying writer
I (108241) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (108241) ble.c: 90: Reading from ble device
I (108241) ble.c: 93: Reading 128 bytes
I (108301) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (108301) ble.c: 90: Reading from ble device
I (108301) ble.c: 93: Reading 37 bytes
I (108331) pinclient.c: 505: Deriving final aes-key
I (108711) storage.c: 186: nvs_get_blob() for keyflags - not found
I (108711) storage.c: 186: nvs_get_blob() for keyflags - not found
I (108711) storage.c: 186: nvs_get_blob() for keyflags - not found
I (108721) auth_user.c: 290: Success
I (108721) NimBLE: GATT procedure initiated: indicate;
I (108721) auth_user.c: 447: Success
I (108721) NimBLE: att_handle=16

I (108731) dashboard.c: 2766: Connected and have wallet/keys - showing home screen/Active
I (108731) ble.c: 581: Event 13
I (108741) dashboard.c: 2548: Main task stack HWM: 1284 free
I (108741) ble.c: 688: notify tx received, notifying writer
I (108751) dashboard.c: 2549: DRAM block / free: 34816 / 52424
I (108821) ble.c: 581: Event 13
I (108821) ble.c: 688: notify tx received, notifying writer
I (108871) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (108871) ble.c: 90: Reading from ble device
I (108871) ble.c: 93: Reading 66 bytes
I (108941) get_master_blinding_key.c: 12: Starting: 60028
I (108941) get_master_blinding_key.c: 48: Success
I (108941) dashboard.c: 2548: Main task stack HWM: 1284 free
I (108941) NimBLE: GATT procedure initiated: indicate;
I (108941) dashboard.c: 2549: DRAM block / free: 34816 / 60100
I (108941) NimBLE: att_handle=16

I (108971) ble.c: 581: Event 13
I (108971) ble.c: 688: notify tx received, notifying writer
I (109061) ble.c: 581: Event 13
I (109061) ble.c: 688: notify tx received, notifying writer
I (109061) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (109061) ble.c: 90: Reading from ble device
I (109071) ble.c: 93: Reading 35 bytes
I (109171) NimBLE: GATT procedure initiated: indicate;
I (109171) dashboard.c: 2548: Main task stack HWM: 1284 free
I (109171) NimBLE: att_handle=16

I (109171) dashboard.c: 2549: DRAM block / free: 34816 / 60032
I (109181) ble.c: 581: Event 13
I (109181) ble.c: 688: notify tx received, notifying writer
I (109271) ble.c: 581: Event 13
I (109271) ble.c: 688: notify tx received, notifying writer
I (109271) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (109271) ble.c: 90: Reading from ble device
I (109271) ble.c: 93: Reading 35 bytes
I (109331) NimBLE: GATT procedure initiated: indicate;
I (109331) NimBLE: att_handle=16

I (109331) dashboard.c: 2548: Main task stack HWM: 1284 free
I (109331) ble.c: 581: Event 13
I (109331) dashboard.c: 2549: DRAM block / free: 34816 / 60032
I (109331) ble.c: 688: notify tx received, notifying writer
I (109421) ble.c: 581: Event 13
I (109421) ble.c: 688: notify tx received, notifying writer
I (109421) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (109421) ble.c: 90: Reading from ble device
I (109421) ble.c: 93: Reading 57 bytes
I (109501) get_xpubs.c: 13: Starting: 59964
I (109501) get_xpubs.c: 42: Success
I (109501) NimBLE: GATT procedure initiated: indicate;
I (109501) NimBLE: att_handle=16

I (109501) dashboard.c: 2548: Main task stack HWM: 1284 free
I (109511) ble.c: 581: Event 13
I (109511) dashboard.c: 2549: DRAM block / free: 34816 / 60032
I (109511) ble.c: 688: notify tx received, notifying writer
I (109631) ble.c: 581: Event 13
I (109631) ble.c: 688: notify tx received, notifying writer
I (110131) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (110131) ble.c: 90: Reading from ble device
I (110131) ble.c: 93: Reading 56 bytes
I (110241) get_xpubs.c: 13: Starting: 59964
I (110241) get_xpubs.c: 42: Success
I (110241) NimBLE: GATT procedure initiated: indicate;
I (110241) NimBLE: att_handle=16

I (110241) dashboard.c: 2548: Main task stack HWM: 1284 free
I (110251) ble.c: 581: Event 13
I (110251) dashboard.c: 2549: DRAM block / free: 34816 / 60032
I (110251) ble.c: 688: notify tx received, notifying writer
I (110381) ble.c: 581: Event 13
I (110381) ble.c: 688: notify tx received, notifying writer
I (110381) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (110381) ble.c: 90: Reading from ble device
I (110381) ble.c: 93: Reading 61 bytes
I (110431) get_xpubs.c: 13: Starting: 59964
I (110451) NimBLE: GATT procedure initiated: indicate;
I (110451) get_xpubs.c: 42: Success
I (110451) NimBLE: att_handle=16

I (110461) dashboard.c: 2548: Main task stack HWM: 1284 free
I (110461) ble.c: 581: Event 13
I (110461) ble.c: 688: notify tx received, notifying writer
I (110461) dashboard.c: 2549: DRAM block / free: 34816 / 60032
I (110561) ble.c: 581: Event 13
I (110561) ble.c: 688: notify tx received, notifying writer
I (110561) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (110561) ble.c: 90: Reading from ble device
I (110561) ble.c: 93: Reading 57 bytes
I (110631) get_xpubs.c: 13: Starting: 59964
I (110641) get_xpubs.c: 42: Success
I (110641) NimBLE: GATT procedure initiated: indicate;
I (110641) NimBLE: att_handle=16

I (110641) dashboard.c: 2548: Main task stack HWM: 1284 free
I (110641) ble.c: 581: Event 13
I (110641) dashboard.c: 2549: DRAM block / free: 34816 / 60032
I (110641) ble.c: 688: notify tx received, notifying writer
I (110741) ble.c: 581: Event 13
I (110741) ble.c: 688: notify tx received, notifying writer
I (110741) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (110741) ble.c: 90: Reading from ble device
I (110751) ble.c: 93: Reading 62 bytes
I (110811) get_xpubs.c: 13: Starting: 59964
I (110841) NimBLE: GATT procedure initiated: indicate;
I (110841) NimBLE: att_handle=16

... 

I (112551) get_xpubs.c: 42: Success
I (112551) dashboard.c: 2548: Main task stack HWM: 1284 free
I (112551) ble.c: 581: Event 13
I (112561) dashboard.c: 2549: DRAM block / free: 34816 / 60032
I (112561) ble.c: 688: notify tx received, notifying writer
I (112751) ble.c: 581: Event 13
I (112751) ble.c: 688: notify tx received, notifying writer
I (113101) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (113101) ble.c: 90: Reading from ble device
I (113101) ble.c: 93: Reading 57 bytes
I (113151) get_xpubs.c: 13: Starting: 59964
I (113151) get_xpubs.c: 42: Success
I (113151) NimBLE: GATT procedure initiated: indicate;
I (113151) NimBLE: att_handle=16

I (113151) dashboard.c: 2548: Main task stack HWM: 1284 free
I (113161) ble.c: 581: Event 13
I (113161) ble.c: 688: notify tx received, notifying writer
I (113161) dashboard.c: 2549: DRAM block / free: 34816 / 60032
I (113231) ble.c: 581: Event 13
I (113231) ble.c: 688: notify tx received, notifying writer
I (113231) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (113231) ble.c: 90: Reading from ble device
I (113231) ble.c: 93: Reading 62 bytes
I (113331) get_xpubs.c: 13: Starting: 59964
I (113361) NimBLE: GATT procedure initiated: indicate;
I (113361) NimBLE: att_handle=16

...

I (146911) ble.c: 581: Event 13
I (146911) ble.c: 688: notify tx received, notifying writer
I (146911) dashboard.c: 2548: Main task stack HWM: 1284 free
I (146921) dashboard.c: 2549: DRAM block / free: 34816 / 60004
I (147011) ble.c: 581: Event 13
I (147011) ble.c: 688: notify tx received, notifying writer
I (148141) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (148141) ble.c: 90: Reading from ble device
I (148141) ble.c: 93: Reading 63 bytes
I (148201) auth_user.c: 349: Starting: 59936
I (148201) auth_user.c: 411: keychain locked for this source, requesting pin
W (148381) gui.c: 2464: gui task handled 7 jobs
W (155471) gui.c: 2464: gui task handled 8 jobs
W (159361) gui.c: 2464: gui task handled 8 jobs
W (161111) gui.c: 2464: gui task handled 8 jobs
W (162611) gui.c: 2464: gui task handled 8 jobs
W (163311) gui.c: 2464: gui task handled 8 jobs
W (166021) gui.c: 2464: gui task handled 8 jobs
I (169441) pinclient.c: 568: Fetching pinserver data
I (169471) storage.c: 186: nvs_get_blob() for pinsvrpubkey - not found
I (169491) pinclient.c: 474: Generating pinserver payload
I (169541) storage.c: 228: nvs_get_str() for pinsvrurlA - not found
I (169541) storage.c: 228: nvs_get_str() for pinsvrurlB - not found
I (169551) storage.c: 228: nvs_get_str() for pinsvrcert - not found
I (169581) NimBLE: GATT procedure initiated: indicate;
I (169581) NimBLE: att_handle=16

...

I (260481) dashboard.c: 2548: Main task stack HWM: 1284 free
I (260481) ble.c: 581: Event 13
I (260481) dashboard.c: 2549: DRAM block / free: 34816 / 60020
I (260481) ble.c: 688: notify tx received, notifying writer
I (260561) ble.c: 581: Event 13
I (260561) ble.c: 688: notify tx received, notifying writer
I (260581) ble.c: 85: Entering gatt_chr_event op: 1 for attr: 19
I (260581) ble.c: 90: Reading from ble device
I (260581) ble.c: 93: Reading 109 bytes
I (260651) get_receive_address.c: 27: Starting: 59904
I (264101) get_receive_address.c: 271: Success
I (264101) NimBLE: GATT procedure initiated: indicate;
I (264111) NimBLE: att_handle=16

I (264111) dashboard.c: 2548: Main task stack HWM: 1284 free
I (264111) ble.c: 581: Event 13
I (264111) dashboard.c: 2549: DRAM block / free: 34816 / 58744
I (264111) ble.c: 688: notify tx received, notifying writer
I (264221) ble.c: 581: Event 13
I (264221) ble.c: 688: notify tx received, notifying writer
I (302581) idletimer.c: 127: Idle-timeout check - last-activity: 26339, timeout period: 60000, projected-timeout: 86339, checktime: 30187
I (302581) idletimer.c: 130: Idle task stack HWM: 460 free
I (302591) idletimer.c: 196: Next check in 6000
I (362591) idletimer.c: 127: Idle-timeout check - last-activity: 26339, timeout period: 60000, projected-timeout: 86339, checktime: 36188
I (362591) idletimer.c: 130: Idle task stack HWM: 460 free
W (362601) idletimer.c: 184: Idle-timeout - dimming screen
I (362601) idletimer.c: 196: Next check in 6000
I (422601) idletimer.c: 127: Idle-timeout check - last-activity: 26339, timeout period: 60000, projected-timeout: 86339, checktime: 42189
I (422601) idletimer.c: 130: Idle task stack HWM: 460 free
I (422611) idletimer.c: 196: Next check in 6000

Suggested Fix

Add an .unknown case with a custom Decodable initializer to gracefully handle unrecognized board types:

public enum JadeBoardType: String, CaseIterable, Codable {
    case v1 = "JADE"
    case v1_1 = "JADE_V1.1"
    case v2 = "JADE_V2"
    case unknown

    public init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let raw = try container.decode(String.self)
        self = JadeBoardType(rawValue: raw) ?? .unknown
    }
}

This preserves backward compatibility while allowing any DIY board type to pass through without breaking the entire JadeVersionInfo decode.

Note: JADE_V2C (Jade Core) defined in the firmware's ota_defines.h is also not in this enum — it may be affected as well.

Secondary Issue: ping() Error Masking

In BleJadeManager.swift, the ping() function catches the decode error and re-throws it as a misleading timeout message:

func ping() async throws -> JadeVersionInfo {
    let versionTask = Task {
        try await self.version()
    }
    let timeoutTask = Task {
        try await Task.sleep(nanoseconds: 3 * 1_000_000_000) // 3 seconds
        versionTask.cancel()
    }
    do {
        let version = try await versionTask.value
        timeoutTask.cancel()
        return version
    } catch {
        // This masks the real CBOR decode error as a timeout
        throw BLEManagerError.timeoutErr(txt: "id_something_went_wrong_when".localized)
    }
}

Two issues here:

  1. Error masking: The catch block discards the actual error (CBOR decode failure) and replaces it with a generic timeout message, making this very difficult to debug.
  2. Timeout too short for pairing: The 3-second timeout races against BLE pairing, which requires user interaction (PASSKEY confirmation, typically 5-6 seconds). On the first connection, the timeout always fires before pairing completes, producing a spurious error even when everything is working correctly.

Suggested improvements:

func ping() async throws -> JadeVersionInfo {
    let versionTask = Task {
        try await self.version()
    }
    let timeoutTask = Task {
        try await Task.sleep(nanoseconds: 10 * 1_000_000_000) // 10s for pairing
        versionTask.cancel()
    }
    do {
        let version = try await versionTask.value
        timeoutTask.cancel()
        return version
    } catch {
        // Propagate the actual error for debugging
        throw error
    }
}

Affected Hardware

All Jade DIY board types defined in ota_defines.h that are not in the JadeBoardType enum:

Board Type String Hardware
TTGO_TDISPLAY TTGO T-Display
TTGO_TDISPLAYS3 TTGO T-Display S3
TTGO_TDISPLAYS3PROCAMERA T-Display S3 Pro + Camera
M5FIRE M5Stack Fire
M5BLACKGRAY M5Stack Black/Gray
M5STICKCPLUS M5StickC Plus
M5STICKCPLUS2 M5StickC Plus 2
M5CORES3 M5Stack Core S3
M5CORE2 M5Stack Core 2
WAVESHARE_TOUCH_LCD2 Waveshare Touch LCD 2"
JADE_V2C Jade Core (official?)

Verified Firmware-Side Fix (for DIY Builders)

Until the app is updated, firmware builders can fix this by decoupling the OTA board type from the app-facing board type.

Modify versioninfo.c to send "JADE" to the app (satisfying the enum) while keeping JADE_OTA_BOARD_TYPE intact for internal OTA validation:

    // Board type - Green iOS JadeBoardType enum only accepts "JADE", "JADE_V1.1", "JADE_V2".
    // DIY boards must report "JADE" to avoid CBOR deserialization failure in the app.
    // The real board type (JADE_OTA_BOARD_TYPE) is preserved for OTA validation.
#ifdef CONFIG_BOARD_TYPE_JADE_ANY
    add_string_to_map(&map_encoder, "BOARD_TYPE", JADE_OTA_BOARD_TYPE);
#else
    add_string_to_map(&map_encoder, "BOARD_TYPE", "JADE");
#endif

This solution has been tested and confirmed to work on TTGO T-Display, T-Display S3 and Waveshare Touch LCD 2 S3 hardware with Green iOS v5.1.6+.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions