From 7b508f6c65d1f445f6082a85801ad396c4e8b505 Mon Sep 17 00:00:00 2001 From: "Jamie C. Driver" Date: Fri, 12 May 2023 10:14:28 +0100 Subject: [PATCH] messaging: handle a non-blocking 'ping' message to check Jade powered Handle a 'ping' message immediately in the messaging task to verify the connection and that Jade is powered and receiving data, which returns whether the main thread is currently busy handling a message, handling user menu navigation, or is idle. NOTE: this message is not queued for processing in fifo order, but is handled immediately, even if the main task is busy. This means if this message is sent while jade is processing other messages, the replies may be out of order (although the 'id' field will still be correct). Use with caution. NOTE: also added experimental version of 'get_version_info' which is also handled immediately. --- configs/sdkconfig_display.defaults | 1 + .../sdkconfig_display_m5blackgray.defaults | 1 + configs/sdkconfig_display_m5fire.defaults | 1 + .../sdkconfig_display_m5stickcplus.defaults | 1 + .../sdkconfig_display_ttgo_tdisplay.defaults | 1 + configs/sdkconfig_jade.defaults | 1 + configs/sdkconfig_jade_ci.defaults | 1 + configs/sdkconfig_jade_ndebug.defaults | 1 + configs/sdkconfig_jade_v1_1.defaults | 1 + configs/sdkconfig_jade_v1_1_ci.defaults | 1 + configs/sdkconfig_jade_v1_1_ndebug.defaults | 1 + docs/index.rst | 34 ++++++++++++ jadepy/jade.py | 29 +++++++++- main/ble/ble.c | 2 +- main/process/dashboard.c | 13 ++++- main/qemu/qemu_tcp.c | 2 +- main/serial.c | 2 +- main/wire.c | 46 +++++++++++++++- main/wire.h | 3 +- production/sdkconfig_jade_prod.defaults | 1 + production/sdkconfig_jade_v1_1_prod.defaults | 1 + test_jade.py | 55 +++++++++++++++++++ 22 files changed, 191 insertions(+), 8 deletions(-) diff --git a/configs/sdkconfig_display.defaults b/configs/sdkconfig_display.defaults index 2adf82a7..95a388d0 100644 --- a/configs/sdkconfig_display.defaults +++ b/configs/sdkconfig_display.defaults @@ -17,6 +17,7 @@ CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 # CONFIG_BT_NIMBLE_ROLE_CENTRAL is not set # CONFIG_BT_NIMBLE_ROLE_BROADCASTER is not set # CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set diff --git a/configs/sdkconfig_display_m5blackgray.defaults b/configs/sdkconfig_display_m5blackgray.defaults index ddcc590d..6b1b5291 100644 --- a/configs/sdkconfig_display_m5blackgray.defaults +++ b/configs/sdkconfig_display_m5blackgray.defaults @@ -16,6 +16,7 @@ CONFIG_COMPILER_WARN_WRITE_STRINGS=y CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 # CONFIG_BT_NIMBLE_ROLE_CENTRAL is not set # CONFIG_BT_NIMBLE_ROLE_BROADCASTER is not set # CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set diff --git a/configs/sdkconfig_display_m5fire.defaults b/configs/sdkconfig_display_m5fire.defaults index 8faf6da0..f382d675 100644 --- a/configs/sdkconfig_display_m5fire.defaults +++ b/configs/sdkconfig_display_m5fire.defaults @@ -17,6 +17,7 @@ CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 # CONFIG_BT_NIMBLE_ROLE_CENTRAL is not set # CONFIG_BT_NIMBLE_ROLE_BROADCASTER is not set # CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set diff --git a/configs/sdkconfig_display_m5stickcplus.defaults b/configs/sdkconfig_display_m5stickcplus.defaults index 32030d08..f80d1b58 100644 --- a/configs/sdkconfig_display_m5stickcplus.defaults +++ b/configs/sdkconfig_display_m5stickcplus.defaults @@ -17,6 +17,7 @@ CONFIG_COMPILER_WARN_WRITE_STRINGS=y CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 # CONFIG_BT_NIMBLE_ROLE_CENTRAL is not set # CONFIG_BT_NIMBLE_ROLE_BROADCASTER is not set # CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set diff --git a/configs/sdkconfig_display_ttgo_tdisplay.defaults b/configs/sdkconfig_display_ttgo_tdisplay.defaults index 42a2f9c1..a147eda2 100644 --- a/configs/sdkconfig_display_ttgo_tdisplay.defaults +++ b/configs/sdkconfig_display_ttgo_tdisplay.defaults @@ -16,6 +16,7 @@ CONFIG_COMPILER_WARN_WRITE_STRINGS=y CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 # CONFIG_BT_NIMBLE_ROLE_CENTRAL is not set # CONFIG_BT_NIMBLE_ROLE_BROADCASTER is not set # CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set diff --git a/configs/sdkconfig_jade.defaults b/configs/sdkconfig_jade.defaults index 30191135..f8fbe8df 100644 --- a/configs/sdkconfig_jade.defaults +++ b/configs/sdkconfig_jade.defaults @@ -16,6 +16,7 @@ CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 # CONFIG_BT_NIMBLE_ROLE_CENTRAL is not set # CONFIG_BT_NIMBLE_ROLE_BROADCASTER is not set # CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set diff --git a/configs/sdkconfig_jade_ci.defaults b/configs/sdkconfig_jade_ci.defaults index 46873040..bbfafab3 100644 --- a/configs/sdkconfig_jade_ci.defaults +++ b/configs/sdkconfig_jade_ci.defaults @@ -17,6 +17,7 @@ CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 # CONFIG_BT_NIMBLE_ROLE_CENTRAL is not set # CONFIG_BT_NIMBLE_ROLE_BROADCASTER is not set # CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set diff --git a/configs/sdkconfig_jade_ndebug.defaults b/configs/sdkconfig_jade_ndebug.defaults index 06acff4b..56d8e8f2 100644 --- a/configs/sdkconfig_jade_ndebug.defaults +++ b/configs/sdkconfig_jade_ndebug.defaults @@ -15,6 +15,7 @@ CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 # CONFIG_BT_NIMBLE_ROLE_CENTRAL is not set # CONFIG_BT_NIMBLE_ROLE_BROADCASTER is not set # CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set diff --git a/configs/sdkconfig_jade_v1_1.defaults b/configs/sdkconfig_jade_v1_1.defaults index 5c4755ba..3366a53c 100644 --- a/configs/sdkconfig_jade_v1_1.defaults +++ b/configs/sdkconfig_jade_v1_1.defaults @@ -17,6 +17,7 @@ CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 # CONFIG_BT_NIMBLE_ROLE_CENTRAL is not set # CONFIG_BT_NIMBLE_ROLE_BROADCASTER is not set # CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set diff --git a/configs/sdkconfig_jade_v1_1_ci.defaults b/configs/sdkconfig_jade_v1_1_ci.defaults index ae930c59..9dd3b741 100644 --- a/configs/sdkconfig_jade_v1_1_ci.defaults +++ b/configs/sdkconfig_jade_v1_1_ci.defaults @@ -18,6 +18,7 @@ CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 # CONFIG_BT_NIMBLE_ROLE_CENTRAL is not set # CONFIG_BT_NIMBLE_ROLE_BROADCASTER is not set # CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set diff --git a/configs/sdkconfig_jade_v1_1_ndebug.defaults b/configs/sdkconfig_jade_v1_1_ndebug.defaults index 194de85b..7ebc9268 100644 --- a/configs/sdkconfig_jade_v1_1_ndebug.defaults +++ b/configs/sdkconfig_jade_v1_1_ndebug.defaults @@ -16,6 +16,7 @@ CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 # CONFIG_BT_NIMBLE_ROLE_CENTRAL is not set # CONFIG_BT_NIMBLE_ROLE_BROADCASTER is not set # CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set diff --git a/docs/index.rst b/docs/index.rst index 67e9fc6a..53c03897 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -83,6 +83,40 @@ get_extended_data reply * The content of the message will be dependent on the original message whose reply data is being split over multiple messages. +.. _ping_request: + +ping request +------------ + +Used to test the connection to Jade and that Jade is powered on and receiving data, which returns whether the main task is currently handling a client message, handling user ui menu navigation, or is idle. + +NOTE: unlike all other calls this is not queued and handled in fifo order - this message is handled immediately and the response sent as quickly as possible. +This call does not block. +If this call is made in parallel with Jade processing other messages, the replies may be out of order (although the message 'id' should still be correct). +Use with caution. + +.. code-block:: cbor + + { + "id": "2712", + "method": "ping" + } + +.. _ping_reply: + +ping reply +---------- + +.. code-block:: cbor + + { + "id": "2712", + "result": true + } + +* The result is 0 if the main jade task is idle, 1 if handling a client message, or 2 if handling ui menu navigation. +* If used with a short timeout this message is ideal for detecting whether Jade is powered/active. + .. _get_version_info_request: get_version_info request diff --git a/jadepy/jade.py b/jadepy/jade.py index b8a30bc3..b2fc7a9d 100644 --- a/jadepy/jade.py +++ b/jadepy/jade.py @@ -337,16 +337,41 @@ def _jadeRpc(self, method, params=None, inputid=None, http_request_fn=None, long return result - def get_version_info(self): + def ping(self): + """ + RPC call to test the connection to Jade and that Jade is powered on and receiving data, and + return whether the main task is currently handling a message, handling user menu navigation + or is idle. + + NOTE: unlike all other calls this is not queued and handled in fifo order - this message is + handled immediately and the response sent as quickly as possible. This call does not block. + If this call is made in parallel with Jade processing other messages, the replies may be + out of order (although the message 'id' should still be correct). Use with caution. + + Returns + ------- + 0 if the main task is currently idle + 1 if the main task is handling a client message + 2 if the main task is handling user ui menu navigation + """ + return self._jadeRpc('ping') + + def get_version_info(self, nonblocking=False): """ RPC call to fetch summary details pertaining to the hardware unit and running firmware. + Parameters + ---------- + nonblocking : bool + If True message will be handled immediately (see also ping()) *experimental feature* + Returns ------- dict Contains keys for various info describing the hw and running fw """ - return self._jadeRpc('get_version_info') + params = {'nonblocking': True} if nonblocking else None + return self._jadeRpc('get_version_info', params) def add_entropy(self, entropy): """ diff --git a/main/ble/ble.c b/main/ble/ble.c index 3b63964f..83aae1b6 100644 --- a/main/ble/ble.c +++ b/main/ble/ble.c @@ -448,7 +448,7 @@ bool ble_init(TaskHandle_t* ble_handle) ble_data_out = JADE_MALLOC_PREFER_SPIRAM(MAX_OUTPUT_MSG_SIZE); const BaseType_t retval = xTaskCreatePinnedToCore( - &ble_writer, "ble_writer", 2 * 1024, NULL, JADE_TASK_PRIO_WRITER, ble_handle, JADE_CORE_SECONDARY); + &ble_writer, "ble_writer", 2 * 1024 + 512, NULL, JADE_TASK_PRIO_WRITER, ble_handle, JADE_CORE_SECONDARY); JADE_ASSERT_MSG( retval == pdPASS, "Failed to create ble_writer task, xTaskCreatePinnedToCore() returned %d", retval); diff --git a/main/process/dashboard.c b/main/process/dashboard.c index a265e669..b7c731f7 100644 --- a/main/process/dashboard.c +++ b/main/process/dashboard.c @@ -96,6 +96,12 @@ static const char* device_name; extern esp_app_desc_t running_app_info; extern uint8_t macid[6]; +// Flag set when main thread is busy processing a message or awaiting user menu navigation +#define MAIN_THREAD_ACTIVITY_NONE 0 +#define MAIN_THREAD_ACTIVITY_MESSAGE 1 +#define MAIN_THREAD_ACTIVITY_UI_MENU 2 +uint32_t main_thread_action = MAIN_THREAD_ACTIVITY_NONE; + // Functional actions void register_otp_process(void* process_ptr); void get_otp_code_process(void* process_ptr); @@ -2090,6 +2096,7 @@ static void do_dashboard(jade_process_t* process, const keychain_t* const initia // 1. Process any message if available (do not block if no message available) jade_process_load_in_message(process, false); if (process->ctx.cbor) { + main_thread_action = MAIN_THREAD_ACTIVITY_MESSAGE; dispatch_message(process); acted = true; } @@ -2102,6 +2109,7 @@ static void do_dashboard(jade_process_t* process, const keychain_t* const initia if (show_connect_screen && ev_base == GUI_BUTTON_EVENT) { // Normal button press from some other home-like screen // (eg. connect/connect-to screens etc) + main_thread_action = MAIN_THREAD_ACTIVITY_UI_MENU; handle_btn(ev_id); acted = true; } else if (ev_base == GUI_EVENT) { @@ -2124,6 +2132,7 @@ static void do_dashboard(jade_process_t* process, const keychain_t* const initia update_home_screen_menu(); } else if (ev_id == gui_get_click_event()) { // Click - handle the current button's event + main_thread_action = MAIN_THREAD_ACTIVITY_UI_MENU; menu_item = get_selected_home_screen_menu_item(); handle_btn(menu_item->btn_id); acted = true; @@ -2132,13 +2141,15 @@ static void do_dashboard(jade_process_t* process, const keychain_t* const initia } } - // If we did some action this loop, run housekeeping if (acted) { // Cleanup anything attached to the dashboard process cleanup_jade_process(process); // Assert all sensitive memory was zero'd sensitive_assert_empty(); + + // Set activity flag back to idle + main_thread_action = MAIN_THREAD_ACTIVITY_NONE; } // Ensure to clear any decrypted keychain if ble- or usb- connection status changes. diff --git a/main/qemu/qemu_tcp.c b/main/qemu/qemu_tcp.c index 0f55e414..b0b9231a 100644 --- a/main/qemu/qemu_tcp.c +++ b/main/qemu/qemu_tcp.c @@ -240,7 +240,7 @@ bool qemu_tcp_init(TaskHandle_t* qemu_tcp_handle) qemu_tcp_data_out = JADE_MALLOC_PREFER_SPIRAM(MAX_OUTPUT_MSG_SIZE); BaseType_t retval = xTaskCreatePinnedToCore( - &qemu_tcp_reader, "qemu_tcp_reader", 2 * 1024, NULL, JADE_TASK_PRIO_READER, NULL, JADE_CORE_SECONDARY); + &qemu_tcp_reader, "qemu_tcp_reader", 5 * 1024, NULL, JADE_TASK_PRIO_READER, NULL, JADE_CORE_SECONDARY); JADE_ASSERT_MSG( retval == pdPASS, "Failed to create qemu_tcp_reader task, xTaskCreatePinnedToCore() returned %d", retval); diff --git a/main/serial.c b/main/serial.c index a56d8c50..71473cd0 100644 --- a/main/serial.c +++ b/main/serial.c @@ -121,7 +121,7 @@ bool serial_init(TaskHandle_t* serial_handle) } BaseType_t retval = xTaskCreatePinnedToCore( - &serial_reader, "serial_reader", 2 * 1024, NULL, JADE_TASK_PRIO_READER, NULL, JADE_CORE_SECONDARY); + &serial_reader, "serial_reader", 5 * 1024, NULL, JADE_TASK_PRIO_READER, NULL, JADE_CORE_SECONDARY); JADE_ASSERT_MSG( retval == pdPASS, "Failed to create serial_reader task, xTaskCreatePinnedToCore() returned %d", retval); diff --git a/main/wire.c b/main/wire.c index 54dab8bc..d232e4c3 100644 --- a/main/wire.c +++ b/main/wire.c @@ -10,9 +10,16 @@ #include "idletimer.h" #include "jade_assert.h" #include "keychain.h" +#include "process.h" #include "random.h" #include "utils/cbor_rpc.h" +// Version info reply +void build_version_info_reply(const void* ctx, CborEncoder* container); + +// Flag set when main thread is busy processing a message or awaiting user menu navigation +extern uint32_t main_thread_action; + // 2s 'no activity' stale message timeout static const TickType_t TIMEOUT_TICKS = 2000 / portTICK_PERIOD_MS; @@ -25,6 +32,40 @@ static const TickType_t TIMEOUT_TICKS = 2000 / portTICK_PERIOD_MS; jade_process_reject_message_ex(ctx, code, msg, (uint8_t*)lenstr, ret, data_out, MAX_OUTPUT_MSG_SIZE); \ } while (false) +// Some messages we handle immediately in this task +static const char PING[] = { 'p', 'i', 'n', 'g' }; +static const char VERINFO[] = { 'g', 'e', 't', '_', 'v', 'e', 'r', 's', 'i', 'o', 'n', '_', 'i', 'n', 'f', 'o' }; + +static bool handleImmediateMessage(cbor_msg_t* ctx) +{ + JADE_ASSERT(ctx); + + size_t method_len = 0; + const char* method = NULL; + rpc_get_method(&ctx->value, &method, &method_len); + + if (method) { + if (method_len == sizeof(PING) && !strncmp(method, PING, method_len)) { + // Simple ping message + JADE_LOGI("Ping message, replying immediately"); + const uint64_t jade_task_current_action = main_thread_action; + jade_process_reply_to_message_result(*ctx, &jade_task_current_action, cbor_result_uint64_cb); + return true; + } else if (method_len == sizeof(VERINFO) && !strncmp(method, VERINFO, method_len)) { + // Version-info message - reply immediately if it contains the 'nonblocking' flag + CborValue params; + bool nonblocking; + if (rpc_get_map("params", &ctx->value, ¶ms) && rpc_get_boolean("nonblocking", ¶ms, &nonblocking) + && nonblocking) { + JADE_LOGI("VerInfoEx message, replying immediately"); + jade_process_reply_to_message_result(*ctx, &ctx->source, build_version_info_reply); + return true; + } + } + } + return false; +} + // Handle bytes in receive buffer // NOTE: assumes sizes of input and output buffers - could be passed sizes if preferred static void handle_data_impl( @@ -75,8 +116,11 @@ static void handle_data_impl( // bad message - expect all inputs to be cbor with a root map with an id and a method strings keys values JADE_LOGW("Invalid request, length %u", msg_len); SEND_REJECT_MSG(CBOR_RPC_INVALID_REQUEST, "Invalid RPC Request message", msg_len); + } else if (handleImmediateMessage(&ctx)) { + JADE_LOGI("Message handled, not passing to main task"); + idletimer_register_activity(false); } else { - // Push to task queue for dashboard to handle + // Push to task queue for main task to handle if (jade_process_push_in_message(full_data_in, msg_len + 1)) { // Valid message arrival counts as 'activity' against idle timeout // (but not as 'UI' activity - ie. keep jade on but do not stop the screen from turning off) diff --git a/main/wire.h b/main/wire.h index 07722fb5..1ae83757 100644 --- a/main/wire.h +++ b/main/wire.h @@ -1,7 +1,8 @@ #ifndef WIRE_H_ #define WIRE_H_ -#include "process.h" +#include "freertos/FreeRTOS.h" +#include #include void handle_data(uint8_t* full_data_in, size_t* read_ptr, size_t new_data_len, TickType_t* last_processing_time, diff --git a/production/sdkconfig_jade_prod.defaults b/production/sdkconfig_jade_prod.defaults index 3f6b5b60..63df6564 100644 --- a/production/sdkconfig_jade_prod.defaults +++ b/production/sdkconfig_jade_prod.defaults @@ -20,6 +20,7 @@ CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 # CONFIG_BT_NIMBLE_ROLE_CENTRAL is not set # CONFIG_BT_NIMBLE_ROLE_BROADCASTER is not set # CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set diff --git a/production/sdkconfig_jade_v1_1_prod.defaults b/production/sdkconfig_jade_v1_1_prod.defaults index c466f137..3a48180d 100644 --- a/production/sdkconfig_jade_v1_1_prod.defaults +++ b/production/sdkconfig_jade_v1_1_prod.defaults @@ -21,6 +21,7 @@ CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 # CONFIG_BT_NIMBLE_ROLE_CENTRAL is not set # CONFIG_BT_NIMBLE_ROLE_BROADCASTER is not set # CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set diff --git a/test_jade.py b/test_jade.py index 3445bc7e..7ebc55bb 100644 --- a/test_jade.py +++ b/test_jade.py @@ -2854,17 +2854,53 @@ def test_totp_ex(jadeapi): assert rslt == expected +def test_ping_protocol(jade): + # Random ae data as irrelevant, so long as same in both cases + signmsg = jade.build_request('signABC', 'sign_message', + {'path': [0, 16], + 'message': 'TestABC', + 'ae_host_commitment': os.urandom(32)}) + getsig = jade.build_request('getsigABC', 'get_signature', + {'ae_host_entropy': os.urandom(32)}) + + # Uninterrupted flow + commitABC1 = jade.make_rpc_call(signmsg)['result'] + sigABC1 = jade.make_rpc_call(getsig)['result'] + + # Same messages but with a 'ping' packet between protocol messages + commitABC2 = jade.make_rpc_call(signmsg)['result'] + assert commitABC2 == commitABC1 + + jade_is_busy = jade.make_rpc_call(jade.build_request('pingNOW', 'ping'))['result'] + assert jade_is_busy == 1 # handling a message (the sign-msg sent above) + + verinfo = jade.make_rpc_call(jade.build_request('verInfoNOW', 'get_version_info', + {'nonblocking': True}))['result'] + assert len(verinfo) == NUM_VALUES_VERINFO + + sigABC2 = jade.make_rpc_call(getsig)['result'] + assert sigABC2 == sigABC1 + + jade_is_busy = jade.make_rpc_call(jade.build_request('pingAGAIN', 'ping'))['result'] + assert jade_is_busy == 0 # idle + + def run_api_tests(jadeapi, isble, qemu, authuser=False): rslt = jadeapi.clean_reset() assert rslt is True + rslt = jadeapi.ping() + assert rslt == 0 # idle + # On connection, a companion app should: # a) get the version info and check is compatible, needs update, etc. # b) if firmware ok, optionally send in some entropy for the rng # c) optionally set the epcoh time (required to use TOTP) # d) tell the jade to authenticate the user (eg. pin entry) # - here we use 'set_mnemonic' instead to replace hw authentication + rslt = jadeapi.get_version_info(nonblocking=True) + assert len(rslt) == NUM_VALUES_VERINFO rslt = jadeapi.get_version_info() assert len(rslt) == NUM_VALUES_VERINFO @@ -2884,6 +2920,9 @@ def run_api_tests(jadeapi, isble, qemu, authuser=False): rslt = jadeapi.set_mnemonic(TEST_MNEMONIC) assert rslt is True + rslt = jadeapi.ping() + assert rslt == 0 # idle + startinfo = jadeapi.get_version_info() assert len(startinfo) == NUM_VALUES_VERINFO has_psram = startinfo['JADE_FREE_SPIRAM'] > 0 @@ -2982,14 +3021,27 @@ def run_interface_tests(jadeapi, rslt = jadeapi.clean_reset() assert rslt is True + rslt = jadeapi.ping() + assert rslt == 0 # idle + rslt = jadeapi.set_mnemonic(TEST_MNEMONIC) assert rslt is True + rslt = jadeapi.ping() + assert rslt == 0 # idle + startinfo = jadeapi.get_version_info() assert len(startinfo) == NUM_VALUES_VERINFO has_psram = startinfo['JADE_FREE_SPIRAM'] > 0 has_ble = startinfo['JADE_CONFIG'] == 'BLE' + rslt = jadeapi.get_version_info(nonblocking=True) + assert len(rslt) == NUM_VALUES_VERINFO + assert rslt['EFUSEMAC'] == startinfo['EFUSEMAC'] + assert rslt['JADE_CONFIG'] == startinfo['JADE_CONFIG'] + assert rslt['JADE_VERSION'] == startinfo['JADE_VERSION'] + assert rslt['JADE_STATE'] == startinfo['JADE_STATE'] + # Smoke tests if smoke: logger.info("Smoke tests") @@ -3011,6 +3063,9 @@ def run_interface_tests(jadeapi, # Test mnemonic-with-passphrase test_passphrase(jadeapi.jade) + # Test ping doesn't break signing protocol + test_ping_protocol(jadeapi.jade) + # 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']: test_scan_qr(jadeapi)