Skip to content

Commit c3845fa

Browse files
committed
nrf_rpc: call bound_handler after init reply
1. Ensure that the group's bound_handler is called after sending the init reply. This is to make sure that the remote knows our group ID and is able to process incoming commands when the handler is called. 2. Similarly, signal groups_init_event after sending the init reply. Signed-off-by: Damian Krolik <[email protected]>
1 parent 0e033d9 commit c3845fa

File tree

1 file changed

+37
-19
lines changed

1 file changed

+37
-19
lines changed

nrf_rpc/nrf_rpc.c

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ struct internal_task {
9696
union {
9797
struct {
9898
const struct nrf_rpc_group *group;
99+
bool send_reply;
100+
bool signal_groups_init_event;
99101
} group_init;
100102

101103
struct {
@@ -377,10 +379,19 @@ static void internal_tx_handler(void)
377379
case NRF_RPC_TASK_GROUP_INIT: {
378380
const struct nrf_rpc_group *group = task.group_init.group;
379381

380-
if (group_init_send(group)) {
382+
if (task.group_init.send_reply && group_init_send(group)) {
381383
NRF_RPC_ERR("Failed to send group init packet for group id: %d strid: %s",
382384
group->data->src_group_id, group->strid);
383385
}
386+
387+
if (group->bound_handler != NULL) {
388+
group->bound_handler(group);
389+
}
390+
391+
if (task.group_init.signal_groups_init_event) {
392+
nrf_rpc_os_event_set(&groups_init_event);
393+
}
394+
384395
break;
385396
}
386397
case NRF_RPC_TASK_RECV_ERROR:
@@ -633,7 +644,8 @@ static int init_packet_handle(struct header *hdr, const struct nrf_rpc_group **g
633644
struct init_packet_data init_data = {0};
634645
struct nrf_rpc_group_data *group_data;
635646
bool first_init;
636-
bool wait_on_init;
647+
bool signal_groups_init_event = false;
648+
bool send_reply;
637649

638650
*group = NULL;
639651

@@ -663,32 +675,38 @@ static int init_packet_handle(struct header *hdr, const struct nrf_rpc_group **g
663675
group_data = (*group)->data;
664676
first_init = group_data->dst_group_id == NRF_RPC_ID_UNKNOWN;
665677
group_data->dst_group_id = hdr->src_group_id;
666-
wait_on_init = (*group)->flags & NRF_RPC_FLAGS_WAIT_ON_INIT;
667-
nrf_rpc_group_bound_handler_t bound_handler = (*group)->bound_handler;
668678

669679
NRF_RPC_DBG("Found corresponding local group. Remote id: %d, Local id: %d",
670-
hdr->src_group_id, group_data->src_group_id);
671-
672-
if (bound_handler != NULL) {
673-
bound_handler(*group);
674-
}
680+
group_data->dst_group_id, group_data->src_group_id);
675681

676-
if (first_init && wait_on_init) {
682+
if (first_init && (*group)->flags & NRF_RPC_FLAGS_WAIT_ON_INIT) {
677683
++initialized_group_count;
678684

679-
if (initialized_group_count == waiting_group_count) {
680-
/* All groups are initialized. */
681-
nrf_rpc_os_event_set(&groups_init_event);
682-
}
683-
}
684-
685-
if (hdr->dst_group_id == NRF_RPC_ID_UNKNOWN && (*group)->data->transport_initialized) {
686685
/*
687-
* If remote processor does not know our group id, send an init packet back,
688-
* since it might have missed our original init packet.
686+
* If this is the last group that nrf_rpc_init() is waiting for, use the async task
687+
* to signal the corresponding event and unblock the waiting thread.
689688
*/
689+
signal_groups_init_event = (initialized_group_count == waiting_group_count);
690+
}
691+
692+
/*
693+
* If the remote processor does not know our group id, send an init packet back as
694+
* either we are not an initiator, which is indicated by NRF_RPC_FLAGS_INITIATOR
695+
* flag, or the remote has missed our init packet.
696+
*/
697+
send_reply = (hdr->dst_group_id == NRF_RPC_ID_UNKNOWN) && group_data->transport_initialized;
698+
699+
/*
700+
* Spawn the async task only if necessary. The async task is used to avoid sending the init
701+
* reply in the transport receive thread. The application is also notified about the group
702+
* initialization from within the task to ensure that when this happens the init reply has
703+
* already been sent and the remote is ready to receive nRF RPC commands.
704+
*/
705+
if (((*group)->bound_handler != NULL) || send_reply || signal_groups_init_event) {
690706
internal_task.type = NRF_RPC_TASK_GROUP_INIT;
691707
internal_task.group_init.group = *group;
708+
internal_task.group_init.send_reply = send_reply;
709+
internal_task.group_init.signal_groups_init_event = signal_groups_init_event;
692710
nrf_rpc_os_thread_pool_send((const uint8_t *)&internal_task, sizeof(internal_task));
693711
nrf_rpc_os_event_wait(&internal_task_consumed, NRF_RPC_OS_WAIT_FOREVER);
694712
}

0 commit comments

Comments
 (0)