Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions generated/Kconfig.rpc_commands
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,18 @@ config INFUSE_RPC_COMMAND_BT_FILE_COPY_COAP_REQUIRED_AUTH
depends on INFUSE_RPC_COMMAND_BT_FILE_COPY_COAP
default 2

config INFUSE_RPC_COMMAND_BT_MCUMGR_REBOOT
bool "Enable RPC bt_mcumgr_reboot"
depends on BT_GATT_CLIENT
default y if INFUSE_SDK
help
Connect to a Bluetooth device and run the MCUMGR reboot command

config INFUSE_RPC_COMMAND_BT_MCUMGR_REBOOT_REQUIRED_AUTH
int "Required authorisation level to run bt_mcumgr_reboot"
depends on INFUSE_RPC_COMMAND_BT_MCUMGR_REBOOT
default 2

config INFUSE_RPC_COMMAND_GRAVITY_REFERENCE_UPDATE
bool "Enable RPC gravity_reference_update"
depends on INFUSE_ZBUS_CHAN_IMU && KV_STORE_KEY_GRAVITY_REFERENCE && ZBUS_RUNTIME_OBSERVERS
Expand Down
9 changes: 9 additions & 0 deletions generated/include/infuse/rpc/commands_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,15 @@ struct net_buf *rpc_command_bt_file_copy_basic(struct net_buf *request);
*/
struct net_buf *rpc_command_bt_file_copy_coap(struct net_buf *request);

/**
* @brief Run bt_mcumgr_reboot RPC
*
* @param request @ref INFUSE_RPC_CMD packet to respond to
*
* @return struct net_buf* @ref INFUSE_RPC_RSP packet buffer
*/
struct net_buf *rpc_command_bt_mcumgr_reboot(struct net_buf *request);

/**
* @brief Run gravity_reference_update RPC
*
Expand Down
15 changes: 15 additions & 0 deletions generated/include/infuse/rpc/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,8 @@ enum rpc_builtin_id {
RPC_ID_BT_FILE_COPY_BASIC = 52,
/** Copy a file fetched from COAP to a remote device over Bluetooth */
RPC_ID_BT_FILE_COPY_COAP = 53,
/** Connect to a Bluetooth device and run the MCUMGR reboot command */
RPC_ID_BT_MCUMGR_REBOOT = 54,
/** Store the current accelerometer vector as the gravity reference */
RPC_ID_GRAVITY_REFERENCE_UPDATE = 60,
/** Query current security state and validate identity */
Expand Down Expand Up @@ -969,6 +971,19 @@ struct rpc_bt_file_copy_coap_response {
uint32_t resource_crc;
} __packed;

/** Connect to a Bluetooth device and run the MCUMGR reboot command */
struct rpc_bt_mcumgr_reboot_request {
struct infuse_rpc_req_header header;
/** Bluetooth LE device to run reboot on */
struct rpc_struct_bt_addr_le peer;
/** Connection timeout in milliseconds */
uint16_t conn_timeout_ms;
} __packed;

struct rpc_bt_mcumgr_reboot_response {
struct infuse_rpc_rsp_header header;
} __packed;

/** Store the current accelerometer vector as the gravity reference */
struct rpc_gravity_reference_update_request {
struct infuse_rpc_req_header header;
Expand Down
7 changes: 7 additions & 0 deletions generated/rpc_command_runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,13 @@ void rpc_command_runner(struct net_buf *request)
}
break;
#endif /* CONFIG_INFUSE_RPC_COMMAND_BT_FILE_COPY_COAP */
#ifdef CONFIG_INFUSE_RPC_COMMAND_BT_MCUMGR_REBOOT
case RPC_ID_BT_MCUMGR_REBOOT:
if (AUTHORISED(auth, BT_MCUMGR_REBOOT)) { /* GCOVR_EXCL_BR_LINE */
response = rpc_command_bt_mcumgr_reboot(request);
}
break;
#endif /* CONFIG_INFUSE_RPC_COMMAND_BT_MCUMGR_REBOOT */
#ifdef CONFIG_INFUSE_RPC_COMMAND_GRAVITY_REFERENCE_UPDATE
case RPC_ID_GRAVITY_REFERENCE_UPDATE:
if (AUTHORISED(auth, GRAVITY_REFERENCE_UPDATE)) { /* GCOVR_EXCL_BR_LINE */
Expand Down
2 changes: 1 addition & 1 deletion kconfig/Kconfig.defaults.ztest
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ config INFUSE_TEST_ID

config INFUSE_REBOOT_RETURN
bool "Disable FUNC_NOTRETURN on `infuse_reboot`"
depends on ZTEST
depends on ZTEST || SOC_SERIES_BSIM_NRFXX

if INFUSE_SECURITY || MBEDTLS

Expand Down
13 changes: 13 additions & 0 deletions scripts/west_commands/cloud_definitions/rpc.json
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,19 @@
{"name": "resource_crc", "type": "uint32_t", "description": "CRC of resource downloaded from COAP"}
]
},
"54": {
"name": "bt_mcumgr_reboot",
"description": "Connect to a Bluetooth device and run the MCUMGR reboot command",
"depends_on": "BT_GATT_CLIENT",
"default": "y if INFUSE_SDK",
"default_auth": "EPACKET_AUTH_DEVICE",
"request_params": [
{"name": "peer", "type": "struct rpc_struct_bt_addr_le", "description": "Bluetooth LE device to run reboot on"},
{"name": "conn_timeout_ms", "type": "uint16_t", "description": "Connection timeout in milliseconds"}
],
"response_params": [
]
},
"60": {
"name": "gravity_reference_update",
"description": "Store the current accelerometer vector as the gravity reference",
Expand Down
9 changes: 9 additions & 0 deletions subsys/epacket/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ config EPACKET_INFUSE_WATCHDOG
depends on INFUSE_WATCHDOG
default y

config EPACKET_BUFFER_EXHAUSTION_TIMEOUT
int "Timeout for detecting ePacket buffer exhaustion"
default 60
help
If all buffers (TX or RX) have been claimed from the pool, require that
at least one buffer is returned within this duration. This detects all
buffers being held by contexts that wouldn't otherwise trigger a watchdog
timeout.

config EPACKET_BUFFERS_TX
int "Number of ePacket buffers for TX"
range 1 16
Expand Down
69 changes: 61 additions & 8 deletions subsys/epacket/epacket.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <infuse/epacket/interface.h>
#include <infuse/epacket/interface/epacket_serial.h>
#include <infuse/work_q.h>
#include <infuse/reboot.h>

#ifdef CONFIG_INFUSE_SECURITY
#include <infuse/security.h>
Expand All @@ -29,11 +30,19 @@
*/
#define BUFFER_ROUNDED ROUND_UP(CONFIG_EPACKET_PACKET_SIZE_MAX, sizeof(void *))

#define EXHAUST_TIMEOUT K_SECONDS(CONFIG_EPACKET_BUFFER_EXHAUSTION_TIMEOUT)

static void tx_destroy(struct net_buf *buf);
static void rx_destroy(struct net_buf *buf);
static void buffer_exhaustion_timeout(struct k_work *work);
static K_WORK_DELAYABLE_DEFINE(tx_exhausted, buffer_exhaustion_timeout);
static K_WORK_DELAYABLE_DEFINE(rx_exhausted, buffer_exhaustion_timeout);

NET_BUF_POOL_DEFINE(epacket_scratch, SCRATCH_BUFFERS, BUFFER_ROUNDED, 0, NULL);
NET_BUF_POOL_DEFINE(epacket_pool_tx, CONFIG_EPACKET_BUFFERS_TX, BUFFER_ROUNDED,
sizeof(struct epacket_tx_metadata), NULL);
sizeof(struct epacket_tx_metadata), tx_destroy);
NET_BUF_POOL_DEFINE(epacket_pool_rx, CONFIG_EPACKET_BUFFERS_RX, BUFFER_ROUNDED,
sizeof(struct epacket_rx_metadata), NULL);
sizeof(struct epacket_rx_metadata), rx_destroy);

K_THREAD_STACK_DEFINE(epacket_stack_area, CONFIG_EPACKET_PROCESS_THREAD_STACK_SIZE);
static struct k_thread epacket_process_thread;
Expand All @@ -43,7 +52,9 @@ k_tid_t epacket_processor_thread;
#ifdef CONFIG_EPACKET_PROCESS_THREAD_SPLIT
K_THREAD_STACK_DEFINE(epacket_rx_stack_area, CONFIG_EPACKET_PROCESS_THREAD_STACK_SIZE);
static struct k_thread epacket_rx_process_thread;
static k_timeout_t loop_period_rx = K_FOREVER;
static int wdog_channel_rx;
k_tid_t epacket_rx_processor_thread;
#endif /* CONFIG_EPACKET_PROCESS_THREAD_SPLIT */

static K_FIFO_DEFINE(epacket_rx_queue);
Expand Down Expand Up @@ -108,9 +119,44 @@ int epacket_num_buffers_free_rx(void)
return net_buf_num_free(&epacket_pool_rx);
}

static void buffer_exhaustion_timeout(struct k_work *work)
{
struct k_work_delayable *dwork = k_work_delayable_from_work(work);

LOG_ERR("%s pool exhausted", dwork == &tx_exhausted ? "TX" : "RX");
#ifdef CONFIG_INFUSE_REBOOT
/* Trigger a reboot, referenced to the worker so we can determine
* which buffer was the problem.
*/
infuse_reboot_delayed(INFUSE_REBOOT_SW_WATCHDOG, (uintptr_t)dwork,
CONFIG_EPACKET_BUFFER_EXHAUSTION_TIMEOUT, K_SECONDS(2));
#else
k_oops();
#endif /* CONFIG_INFUSE_REBOOT */
}

static void tx_destroy(struct net_buf *buf)
{
k_work_cancel_delayable(&tx_exhausted);
net_buf_destroy(buf);
}

static void rx_destroy(struct net_buf *buf)
{
k_work_cancel_delayable(&rx_exhausted);
net_buf_destroy(buf);
}

struct net_buf *epacket_alloc_tx(k_timeout_t timeout)
{
return net_buf_alloc(&epacket_pool_tx, timeout);
struct net_buf *buf = net_buf_alloc(&epacket_pool_tx, timeout);

if ((buf != NULL) && (epacket_num_buffers_free_tx() == 0)) {
/* No TX buffers remaining, start exhaustion timer */
LOG_DBG("%s pool empty", "TX");
k_work_schedule(&tx_exhausted, EXHAUST_TIMEOUT);
}
return buf;
}

struct net_buf *epacket_alloc_rx(k_timeout_t timeout)
Expand All @@ -121,6 +167,12 @@ struct net_buf *epacket_alloc_rx(k_timeout_t timeout)
struct epacket_rx_metadata *meta = net_buf_user_data(buf);
/* Default authorisation state is failure */
meta->auth = EPACKET_AUTH_FAILURE;

if (epacket_num_buffers_free_rx() == 0) {
/* No RX buffers remaining, start exhaustion timer */
LOG_DBG("%s pool empty", "RX");
k_work_schedule(&rx_exhausted, EXHAUST_TIMEOUT);
}
}
return buf;
}
Expand Down Expand Up @@ -462,7 +514,7 @@ static void epacket_processor_rx(void *a, void *b, void *c)
k_thread_name_set(NULL, "epacket_proc_rx");
infuse_watchdog_thread_register(wdog_channel_rx, _current);
while (true) {
rc = k_poll(events, ARRAY_SIZE(events), loop_period);
rc = k_poll(events, ARRAY_SIZE(events), loop_period_rx);
infuse_watchdog_feed(wdog_channel_rx);
if (rc == -EAGAIN) {
/* Only woke to feed the watchdog */
Expand Down Expand Up @@ -495,12 +547,13 @@ static int epacket_boot(void)

#ifdef CONFIG_EPACKET_PROCESS_THREAD_SPLIT
wdog_channel_rx = IS_ENABLED(CONFIG_EPACKET_INFUSE_WATCHDOG)
? infuse_watchdog_install(&loop_period)
? infuse_watchdog_install(&loop_period_rx)
: -ENODEV;

k_thread_create(&epacket_rx_process_thread, epacket_rx_stack_area,
K_THREAD_STACK_SIZEOF(epacket_rx_stack_area), epacket_processor_rx, NULL,
NULL, NULL, 0, K_ESSENTIAL, K_NO_WAIT);
epacket_rx_processor_thread =
k_thread_create(&epacket_rx_process_thread, epacket_rx_stack_area,
K_THREAD_STACK_SIZEOF(epacket_rx_stack_area), epacket_processor_rx,
NULL, NULL, NULL, 0, K_ESSENTIAL, K_NO_WAIT);
#endif /* CONFIG_EPACKET_PROCESS_THREAD_SPLIT */
return 0;
}
Expand Down
15 changes: 14 additions & 1 deletion subsys/epacket/forwarding.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <infuse/states.h>
#include <infuse/types.h>
#include <infuse/drivers/watchdog.h>
#include <infuse/epacket/interface.h>
#include <infuse/epacket/packet.h>
#include <infuse/epacket/interface/epacket_bt_central.h>
Expand Down Expand Up @@ -260,6 +261,8 @@ static void forward_auto_conn_processor(void *a, void *b, void *c)
struct epacket_rx_metadata *meta;
struct net_buf *buf;
struct net_buf *tx;
k_timeout_t loop_period = K_FOREVER;
int wdog_channel;
int rc;

k_thread_name_set(NULL, "auto_conn_forward");
Expand All @@ -270,8 +273,18 @@ static void forward_auto_conn_processor(void *a, void *b, void *c)
bt_central_cb.packet_received = bt_central_packet_received;
epacket_register_callback(bt_central, &bt_central_cb);

/* Setup watchdog */
wdog_channel = IS_ENABLED(CONFIG_EPACKET_INFUSE_WATCHDOG)
? infuse_watchdog_install(&loop_period)
: -ENODEV;
infuse_watchdog_thread_register(wdog_channel, _current);

for (;;) {
buf = k_fifo_get(&packet_queue, K_FOREVER);
buf = k_fifo_get(&packet_queue, loop_period);
infuse_watchdog_feed(wdog_channel);
if (buf == NULL) {
continue;
}
meta = net_buf_user_data(buf);
hdr = net_buf_pull_mem(buf, sizeof(struct epacket_forward_auto_conn_header));

Expand Down
1 change: 1 addition & 0 deletions subsys/rpc/commands/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ zephyr_library_sources_ifdef(CONFIG_INFUSE_RPC_COMMAND_BT_CONNECT_INFUSE bt_conn
zephyr_library_sources_ifdef(CONFIG_INFUSE_RPC_COMMAND_BT_DISCONNECT bt_disconnect.c)
zephyr_library_sources_ifdef(CONFIG_INFUSE_RPC_COMMAND_BT_FILE_COPY_BASIC bt_file_copy_basic.c)
zephyr_library_sources_ifdef(CONFIG_INFUSE_RPC_COMMAND_BT_FILE_COPY_COAP bt_file_copy_coap.c)
zephyr_library_sources_ifdef(CONFIG_INFUSE_RPC_COMMAND_BT_MCUMGR_REBOOT bt_mcumgr_reboot.c)
zephyr_library_sources_ifdef(CONFIG_INFUSE_RPC_COMMAND_GRAVITY_REFERENCE_UPDATE gravity_reference_update.c)
zephyr_library_sources_ifdef(CONFIG_INFUSE_RPC_COMMAND_SECURITY_STATE security_state.c)
zephyr_library_sources_ifdef(CONFIG_INFUSE_RPC_COMMAND_ECHO echo.c)
Expand Down
Loading