Skip to content

Commit 60aceae

Browse files
committed
nrf_rpc: add nrf_rpc_setup, nrf_rpc_bind and nrf_rpc_unbind
1. Add nrf_rpc_setup() and nrf_rpc_bind() experimental APIs that behave together like existing nrf_rpc_init(). 2. Add nrf_rpc_unbind() which clears the effects of former calling nrf_rpc_bind(). These are needed to support re-connecting to the peer, for example after noticing that a peer has been reset, and the peer is not a group initiator (thus, it does not send an nRF RPC initialization packet automatically at startup). Signed-off-by: Damian Krolik <[email protected]>
1 parent 73f4070 commit 60aceae

File tree

2 files changed

+125
-52
lines changed

2 files changed

+125
-52
lines changed

nrf_rpc/include/nrf_rpc.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,8 @@ struct nrf_rpc_err_report {
349349
void nrf_rpc_set_bound_handler(nrf_rpc_group_bound_handler_t bound_handler);
350350

351351
/** @brief Initialize the nRF RPC
352+
*
353+
* Calling this function is equivalent to calling both @ref nrf_rpc_setup and @ref nrf_rpc_bind.
352354
*
353355
* @param err_handler Error handler that will be called to report error in
354356
* nRF RPC.
@@ -357,6 +359,53 @@ void nrf_rpc_set_bound_handler(nrf_rpc_group_bound_handler_t bound_handler);
357359
*/
358360
int nrf_rpc_init(nrf_rpc_err_handler_t err_handler);
359361

362+
/** @brief Initialize the nRF RPC internal state.
363+
*
364+
* Sets up all variables related to nRF RPC, including contexts, groups, and transports.
365+
* It does not initiate any communication with the peer.
366+
*
367+
* @note This function can be invoked multiple times; however, only the first call has an effect.
368+
* @note This function is not thread-safe and should not be called concurrently from multiple
369+
* threads.
370+
*
371+
* @warning This function is experimental and subject to change or removal without prior notice.
372+
*
373+
* @param err_handler Error handler that will be called to report an error in the nRF RPC.
374+
* @param bound_handler Bound handler that will be called when a group is bound with the peer.
375+
*
376+
* @return 0 on success or negative error code.
377+
*/
378+
int nrf_rpc_setup(nrf_rpc_err_handler_t err_handler, nrf_rpc_group_bound_handler_t bound_handler);
379+
380+
/** @brief Binds the nRF RPC groups.
381+
*
382+
* Sends an initializaton packet to the peer for each group defined with the @ref
383+
* NRF_RPC_FLAGS_INITIATOR flag. It then waits until all groups defined with the @ref
384+
* NRF_RPC_FLAGS_WAIT_ON_INIT flag have been bound.
385+
*
386+
* A group is considered bound when an initialization packet for that group is received from the
387+
* peer, indicating the numerical identifier assigned to the group by the peer.
388+
*
389+
* The function may time out if some groups are not bound within the duration specified by the
390+
* CONFIG_NRF_RPC_GROUP_INIT_WAIT_TIME Kconfig option.
391+
*
392+
* @note This function is not thread-safe; should not be called concurrently from multiple threads.
393+
*
394+
* @warning This function is experimental and subject to change or removal without prior notice.
395+
*
396+
* @return 0 on success or negative error code.
397+
*/
398+
int nrf_rpc_bind(void);
399+
400+
/** @brief Unbinds the nRF RPC groups.
401+
*
402+
* Resets the effect of @ref nrf_rpc_bind so that no groups are considered bound after returning
403+
* from this function.
404+
*
405+
* @warning This function is experimental and subject to change or removal without prior notice.
406+
*/
407+
void nrf_rpc_unbind(void);
408+
360409
/** @brief Send a command and provide callback to handle response.
361410
*
362411
* @param group Group that command belongs to.

nrf_rpc/nrf_rpc.c

Lines changed: 76 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -415,48 +415,6 @@ static void internal_tx_handler(void)
415415
}
416416
}
417417

418-
static int transport_init(nrf_rpc_tr_receive_handler_t receive_cb)
419-
{
420-
int err = 0;
421-
void *iter;
422-
const struct nrf_rpc_group *group;
423-
424-
for (NRF_RPC_AUTO_ARR_FOR(iter, group, &nrf_rpc_groups_array,
425-
const struct nrf_rpc_group)) {
426-
const struct nrf_rpc_tr *transport = group->transport;
427-
struct nrf_rpc_group_data *data = group->data;
428-
429-
err = transport->api->init(transport, receive_cb, NULL);
430-
if (err) {
431-
NRF_RPC_ERR("Failed to initialize transport, err: %d", err);
432-
continue;
433-
}
434-
435-
group->data->transport_initialized = true;
436-
437-
if (group->flags & NRF_RPC_FLAGS_INITIATOR) {
438-
err = group_init_send(group);
439-
if (err) {
440-
NRF_RPC_ERR("Failed to send group init packet for group id: %d strid: %s err: %d",
441-
data->src_group_id, group->strid, err);
442-
continue;
443-
}
444-
}
445-
}
446-
447-
/* Group initialization errors are not propagated to the caller. */
448-
err = 0;
449-
450-
if (waiting_group_count > 0) {
451-
err = nrf_rpc_os_event_wait(&groups_init_event, CONFIG_NRF_RPC_GROUP_INIT_WAIT_TIME);
452-
if (err) {
453-
NRF_RPC_ERR("Not all groups are ready to use.");
454-
}
455-
}
456-
457-
return err;
458-
}
459-
460418
/* ======================== Receiving Packets ======================== */
461419

462420
/* Find in array and execute command or event handler */
@@ -1106,10 +1064,9 @@ void nrf_rpc_set_bound_handler(nrf_rpc_group_bound_handler_t bound_handler)
11061064
global_bound_handler = bound_handler;
11071065
}
11081066

1109-
int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
1067+
int nrf_rpc_setup(nrf_rpc_err_handler_t err_handler, nrf_rpc_group_bound_handler_t bound_handler)
11101068
{
11111069
int err;
1112-
int i;
11131070
void *iter;
11141071
const struct nrf_rpc_group *group;
11151072
uint8_t group_id = 0;
@@ -1122,6 +1079,7 @@ int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
11221079
}
11231080

11241081
global_err_handler = err_handler;
1082+
global_bound_handler = bound_handler;
11251083

11261084
for (NRF_RPC_AUTO_ARR_FOR(iter, group, &nrf_rpc_groups_array,
11271085
const struct nrf_rpc_group)) {
@@ -1155,8 +1113,6 @@ int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
11551113
group_count = group_id;
11561114
waiting_group_count = wait_count;
11571115

1158-
memset(&cmd_ctx_pool, 0, sizeof(cmd_ctx_pool));
1159-
11601116
err = nrf_rpc_os_init(execute_packet);
11611117
if (err < 0) {
11621118
return err;
@@ -1172,7 +1128,7 @@ int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
11721128
return err;
11731129
}
11741130

1175-
for (i = 0; i < CONFIG_NRF_RPC_CMD_CTX_POOL_SIZE; i++) {
1131+
for (int i = 0; i < CONFIG_NRF_RPC_CMD_CTX_POOL_SIZE; i++) {
11761132
cmd_ctx_pool[i].id = i;
11771133
err = nrf_rpc_os_mutex_init(&cmd_ctx_pool[i].mutex);
11781134
if (err < 0) {
@@ -1184,17 +1140,85 @@ int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
11841140
}
11851141
}
11861142

1187-
err = transport_init(receive_handler);
1188-
if (err < 0) {
1189-
return err;
1190-
}
1191-
11921143
is_initialized = true;
11931144
NRF_RPC_DBG("Done initializing nRF RPC module");
11941145

11951146
return err;
11961147
}
11971148

1149+
int nrf_rpc_bind(void)
1150+
{
1151+
int err;
1152+
void *iter;
1153+
const struct nrf_rpc_group *group;
1154+
1155+
for (NRF_RPC_AUTO_ARR_FOR(iter, group, &nrf_rpc_groups_array, const struct nrf_rpc_group)) {
1156+
const struct nrf_rpc_tr *transport = group->transport;
1157+
struct nrf_rpc_group_data *data = group->data;
1158+
1159+
if (!group->data->transport_initialized) {
1160+
err = transport->api->init(transport, receive_handler, NULL);
1161+
if (err) {
1162+
NRF_RPC_ERR("Failed to initialize transport, err: %d", err);
1163+
continue;
1164+
}
1165+
1166+
group->data->transport_initialized = true;
1167+
}
1168+
1169+
if (group->flags & NRF_RPC_FLAGS_INITIATOR) {
1170+
err = group_init_send(group);
1171+
if (err) {
1172+
NRF_RPC_ERR("Failed to send group init packet for group id: %d "
1173+
"strid: %s err: %d",
1174+
data->src_group_id, group->strid, err);
1175+
continue;
1176+
}
1177+
}
1178+
}
1179+
1180+
/* Group initialization errors are not propagated to the caller. */
1181+
err = 0;
1182+
1183+
if (waiting_group_count > 0) {
1184+
err = nrf_rpc_os_event_wait(&groups_init_event,
1185+
CONFIG_NRF_RPC_GROUP_INIT_WAIT_TIME);
1186+
if (err) {
1187+
NRF_RPC_ERR("Not all groups are ready to use.");
1188+
}
1189+
}
1190+
1191+
return err;
1192+
}
1193+
1194+
void nrf_rpc_unbind(void)
1195+
{
1196+
void *iter;
1197+
const struct nrf_rpc_group *group;
1198+
1199+
initialized_group_count = 0;
1200+
1201+
for (NRF_RPC_AUTO_ARR_FOR(iter, group, &nrf_rpc_groups_array, const struct nrf_rpc_group)) {
1202+
group->data->dst_group_id = NRF_RPC_ID_UNKNOWN;
1203+
}
1204+
}
1205+
1206+
int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
1207+
{
1208+
int err;
1209+
1210+
if (is_initialized) {
1211+
return 0;
1212+
}
1213+
1214+
err = nrf_rpc_setup(err_handler, /* bound_handler */ NULL);
1215+
if (err < 0) {
1216+
return err;
1217+
}
1218+
1219+
return nrf_rpc_bind();
1220+
}
1221+
11981222
int nrf_rpc_cmd(const struct nrf_rpc_group *group, uint8_t cmd, uint8_t *packet,
11991223
size_t len, nrf_rpc_handler_t handler, void *handler_data)
12001224
{

0 commit comments

Comments
 (0)