Skip to content

Commit

Permalink
messaging: handle a non-blocking 'ping' message to check Jade powered
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
JamieDriver committed Jul 31, 2023
1 parent 47844f6 commit 7b508f6
Show file tree
Hide file tree
Showing 22 changed files with 191 additions and 8 deletions.
1 change: 1 addition & 0 deletions configs/sdkconfig_display.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions configs/sdkconfig_display_m5blackgray.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions configs/sdkconfig_display_m5fire.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions configs/sdkconfig_display_m5stickcplus.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions configs/sdkconfig_display_ttgo_tdisplay.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions configs/sdkconfig_jade.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions configs/sdkconfig_jade_ci.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions configs/sdkconfig_jade_ndebug.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions configs/sdkconfig_jade_v1_1.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions configs/sdkconfig_jade_v1_1_ci.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions configs/sdkconfig_jade_v1_1_ndebug.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 34 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
29 changes: 27 additions & 2 deletions jadepy/jade.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
"""
Expand Down
2 changes: 1 addition & 1 deletion main/ble/ble.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
13 changes: 12 additions & 1 deletion main/process/dashboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand All @@ -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) {
Expand All @@ -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;
Expand All @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion main/qemu/qemu_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion main/serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
46 changes: 45 additions & 1 deletion main/wire.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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, &params) && rpc_get_boolean("nonblocking", &params, &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(
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion main/wire.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#ifndef WIRE_H_
#define WIRE_H_

#include "process.h"
#include "freertos/FreeRTOS.h"
#include <stddef.h>
#include <stdint.h>

void handle_data(uint8_t* full_data_in, size_t* read_ptr, size_t new_data_len, TickType_t* last_processing_time,
Expand Down
1 change: 1 addition & 0 deletions production/sdkconfig_jade_prod.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions production/sdkconfig_jade_v1_1_prod.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 7b508f6

Please sign in to comment.