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
10 changes: 10 additions & 0 deletions nrf_rpc/include/nrf_rpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,16 @@ struct nrf_rpc_err_report {
#define NRF_RPC_GROUP_STATUS(_group) \
(_group.data->transport_initialized && (_group.data->dst_group_id != NRF_RPC_ID_UNKNOWN))

/** @brief Register a global bound handler.
*
* Registers a global handler that is called each time the remote peer binds to a local group.
* This can be used by the application to detect that the peer has restarted, to reset any local
* state associated with the peer.
*
* @param bound_handler Bound handler.
*/
void nrf_rpc_set_bound_handler(nrf_rpc_group_bound_handler_t bound_handler);

/** @brief Initialize the nRF RPC
*
* @param err_handler Error handler that will be called to report error in
Expand Down
32 changes: 24 additions & 8 deletions nrf_rpc/nrf_rpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ struct internal_task {
union {
struct {
const struct nrf_rpc_group *group;
bool send_reply;
bool first_init;
bool needs_reply;
bool signal_groups_init_event;
} group_init;

Expand Down Expand Up @@ -126,6 +127,9 @@ static bool is_initialized;
/* Error handler provided to the init function. */
static nrf_rpc_err_handler_t global_err_handler;

/* Bound group handler provided to the init function. */
static nrf_rpc_group_bound_handler_t global_bound_handler;

static struct internal_task internal_task;
static struct nrf_rpc_os_event internal_task_consumed;

Expand Down Expand Up @@ -379,13 +383,19 @@ static void internal_tx_handler(void)
case NRF_RPC_TASK_GROUP_INIT: {
const struct nrf_rpc_group *group = task.group_init.group;

if (task.group_init.send_reply && group_init_send(group)) {
if (task.group_init.needs_reply && group_init_send(group)) {
NRF_RPC_ERR("Failed to send group init packet for group id: %d strid: %s",
group->data->src_group_id, group->strid);
}

if (group->bound_handler != NULL) {
group->bound_handler(group);
if (task.group_init.first_init || task.group_init.needs_reply) {
if (group->bound_handler != NULL) {
group->bound_handler(group);
}

if (global_bound_handler != NULL) {
global_bound_handler(group);
}
}

if (task.group_init.signal_groups_init_event) {
Expand Down Expand Up @@ -648,7 +658,7 @@ static int init_packet_handle(struct header *hdr, const struct nrf_rpc_group **g
struct nrf_rpc_group_data *group_data;
bool first_init;
bool signal_groups_init_event = false;
bool send_reply;
bool needs_reply;

*group = NULL;

Expand Down Expand Up @@ -697,18 +707,19 @@ static int init_packet_handle(struct header *hdr, const struct nrf_rpc_group **g
* either we are not an initiator, which is indicated by NRF_RPC_FLAGS_INITIATOR
* flag, or the remote has missed our init packet.
*/
send_reply = (hdr->dst_group_id == NRF_RPC_ID_UNKNOWN);
needs_reply = (hdr->dst_group_id == NRF_RPC_ID_UNKNOWN);

/*
* Spawn the async task only if necessary. The async task is used to avoid sending the init
* reply in the transport receive thread. The application is also notified about the group
* initialization from within the task to ensure that when this happens the init reply has
* already been sent and the remote is ready to receive nRF RPC commands.
*/
if (((*group)->bound_handler != NULL) || send_reply || signal_groups_init_event) {
if (first_init || needs_reply || signal_groups_init_event) {
internal_task.type = NRF_RPC_TASK_GROUP_INIT;
internal_task.group_init.group = *group;
internal_task.group_init.send_reply = send_reply;
internal_task.group_init.first_init = first_init;
internal_task.group_init.needs_reply = needs_reply;
internal_task.group_init.signal_groups_init_event = signal_groups_init_event;
nrf_rpc_os_thread_pool_send((const uint8_t *)&internal_task, sizeof(internal_task));
nrf_rpc_os_event_wait(&internal_task_consumed, NRF_RPC_OS_WAIT_FOREVER);
Expand Down Expand Up @@ -1075,6 +1086,11 @@ void nrf_rpc_rsp_no_err(const struct nrf_rpc_group *group, uint8_t *packet, size

/* ======================== Common API functions ======================== */

void nrf_rpc_set_bound_handler(nrf_rpc_group_bound_handler_t bound_handler)
{
global_bound_handler = bound_handler;
}

int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
{
int err;
Expand Down
Loading