@@ -125,6 +125,7 @@ static uint8_t initialized_group_count;
125125
126126/* nRF RPC initialization status. */
127127static bool is_initialized ;
128+ static bool is_stopped ;
128129
129130/* Error handler provided to the init function. */
130131static nrf_rpc_err_handler_t global_err_handler ;
@@ -135,6 +136,9 @@ static nrf_rpc_group_bound_handler_t global_bound_handler;
135136static struct internal_task internal_task ;
136137static struct nrf_rpc_os_event internal_task_consumed ;
137138
139+ static struct nrf_rpc_os_mutex cleanup_mutex ;
140+ static struct nrf_rpc_cleanup_handler * cleanup_handlers ;
141+
138142/* Array with all defiend groups */
139143NRF_RPC_AUTO_ARR (nrf_rpc_groups_array , "grp" );
140144
@@ -738,6 +742,21 @@ static int init_packet_handle(struct header *hdr, const struct nrf_rpc_group **g
738742 return 0 ;
739743}
740744
745+ static void abort_all_ops (void )
746+ {
747+ NRF_RPC_WRN ("Canceling all tasks." );
748+ for (int i = 0 ; i < CONFIG_NRF_RPC_CMD_CTX_POOL_SIZE ; i ++ ) {
749+ struct nrf_rpc_cmd_ctx * ctx = & cmd_ctx_pool [i ];
750+ nrf_rpc_os_mutex_lock (& ctx -> mutex );
751+ if (ctx -> use_count > 0 ) {
752+ NRF_RPC_WRN ("Canceling context %u." , ctx -> id );
753+ nrf_rpc_os_msg_set (& ctx -> recv_msg , NULL , 0 );
754+ }
755+ nrf_rpc_os_mutex_unlock (& ctx -> mutex );
756+ }
757+ NRF_RPC_WRN ("Canceling all tasks done." );
758+ }
759+
741760/* Callback from transport layer that handles incoming. */
742761static void receive_handler (const struct nrf_rpc_tr * transport , const uint8_t * packet , size_t len ,
743762 void * context )
@@ -754,6 +773,18 @@ static void receive_handler(const struct nrf_rpc_tr *transport, const uint8_t *p
754773 goto cleanup_and_exit ;
755774 }
756775
776+ if (is_stopped &&
777+ (hdr .type == NRF_RPC_PACKET_TYPE_CMD ||
778+ hdr .type == NRF_RPC_PACKET_TYPE_EVT ||
779+ hdr .type == NRF_RPC_PACKET_TYPE_ACK ||
780+ hdr .type == NRF_RPC_PACKET_TYPE_RSP )) {
781+ // drop only selected types of packets
782+ // do not drop INITs and ERRORS
783+
784+ NRF_RPC_WRN ("Dropping the packet." );
785+ goto cleanup_and_exit ;
786+ }
787+
757788 if (hdr .type == NRF_RPC_PACKET_TYPE_CMD ||
758789 hdr .type == NRF_RPC_PACKET_TYPE_EVT ||
759790 hdr .type == NRF_RPC_PACKET_TYPE_ACK ||
@@ -986,33 +1017,41 @@ int nrf_rpc_cmd_common(const struct nrf_rpc_group *group, uint32_t cmd,
9861017 handler_data = ptr2 ;
9871018 }
9881019
989- cmd_ctx = cmd_ctx_reserve ();
1020+ nrf_rpc_os_mutex_lock (& cleanup_mutex );
1021+ if (is_stopped ) {
1022+ err = - NRF_EPERM ;
1023+ nrf_rpc_os_mutex_unlock (& cleanup_mutex );
1024+ } else {
9901025
991- hdr .dst = cmd_ctx -> remote_id ;
992- hdr .src = cmd_ctx -> id ;
993- hdr .id = cmd & 0xFF ;
994- hdr .src_group_id = group -> data -> src_group_id ;
995- hdr .dst_group_id = group -> data -> dst_group_id ;
996- header_cmd_encode (full_packet , & hdr );
1026+ cmd_ctx = cmd_ctx_reserve ();
1027+ nrf_rpc_os_mutex_unlock (& cleanup_mutex ); /* release the mutex as the context specific one has been acquired */
9971028
998- old_handler = cmd_ctx -> handler ;
999- old_handler_data = cmd_ctx -> handler_data ;
1000- cmd_ctx -> handler = handler ;
1001- cmd_ctx -> handler_data = handler_data ;
1029+ hdr .dst = cmd_ctx -> remote_id ;
1030+ hdr .src = cmd_ctx -> id ;
1031+ hdr .id = cmd & 0xFF ;
1032+ hdr .src_group_id = group -> data -> src_group_id ;
1033+ hdr .dst_group_id = group -> data -> dst_group_id ;
1034+ header_cmd_encode (full_packet , & hdr );
10021035
1003- NRF_RPC_DBG ("Sending command 0x%02X from group 0x%02X" , cmd ,
1004- group -> data -> src_group_id );
1036+ old_handler = cmd_ctx -> handler ;
1037+ old_handler_data = cmd_ctx -> handler_data ;
1038+ cmd_ctx -> handler = handler ;
1039+ cmd_ctx -> handler_data = handler_data ;
10051040
1006- err = send (group , full_packet , len + NRF_RPC_HEADER_SIZE );
1041+ NRF_RPC_DBG ("Sending command 0x%02X from group 0x%02X" , cmd ,
1042+ group -> data -> src_group_id );
10071043
1008- if (err >= 0 ) {
1009- err = wait_for_response (group , cmd_ctx , rsp_packet , rsp_len );
1010- }
1044+ err = send (group , full_packet , len + NRF_RPC_HEADER_SIZE );
1045+
1046+ if (err >= 0 ) {
1047+ err = wait_for_response (group , cmd_ctx , rsp_packet , rsp_len );
1048+ }
10111049
1012- cmd_ctx -> handler = old_handler ;
1013- cmd_ctx -> handler_data = old_handler_data ;
1050+ cmd_ctx -> handler = old_handler ;
1051+ cmd_ctx -> handler_data = old_handler_data ;
10141052
1015- cmd_ctx_release (cmd_ctx );
1053+ cmd_ctx_release (cmd_ctx );
1054+ }
10161055
10171056 return err ;
10181057}
@@ -1133,6 +1172,8 @@ int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
11331172 return 0 ;
11341173 }
11351174
1175+ nrf_rpc_os_mutex_init (& cleanup_mutex );
1176+
11361177 global_err_handler = err_handler ;
11371178
11381179 for (NRF_RPC_AUTO_ARR_FOR (iter , group , & nrf_rpc_groups_array ,
@@ -1194,6 +1235,46 @@ int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
11941235 return err ;
11951236}
11961237
1238+ void nrf_rpc_register_cleanup_handler (struct nrf_rpc_cleanup_handler * handler )
1239+ {
1240+ nrf_rpc_os_mutex_lock (& cleanup_mutex );
1241+
1242+ struct nrf_rpc_cleanup_handler * current ;
1243+
1244+ // make sure not added twice
1245+ for (current = cleanup_handlers ; current != NULL ; current = current -> next ) {
1246+ if (current == handler ) {
1247+ break ;
1248+ }
1249+ }
1250+
1251+ if (current == NULL ) {
1252+ handler -> next = cleanup_handlers ;
1253+ cleanup_handlers = handler ;
1254+ }
1255+ nrf_rpc_os_mutex_unlock (& cleanup_mutex );
1256+ }
1257+
1258+ void nrf_rpc_stop (bool cleanup )
1259+ {
1260+ nrf_rpc_os_mutex_lock (& cleanup_mutex );
1261+
1262+ is_stopped = true;
1263+ abort_all_ops ();
1264+ if (cleanup ) {
1265+ struct nrf_rpc_cleanup_handler * current ;
1266+ for (current = cleanup_handlers ; current != NULL ; current = current -> next ) {
1267+ current -> handler (current -> context );
1268+ }
1269+ }
1270+ nrf_rpc_os_mutex_unlock (& cleanup_mutex );
1271+ }
1272+
1273+ void nrf_rpc_resume (void )
1274+ {
1275+ is_stopped = false;
1276+ }
1277+
11971278int nrf_rpc_cmd (const struct nrf_rpc_group * group , uint8_t cmd , uint8_t * packet ,
11981279 size_t len , nrf_rpc_handler_t handler , void * handler_data )
11991280{
0 commit comments