@@ -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
@@ -726,6 +730,19 @@ static int init_packet_handle(struct header *hdr, const struct nrf_rpc_group **g
726730 return 0 ;
727731}
728732
733+ static void abort_all_ops (void )
734+ {
735+ NRF_RPC_INF ("Canceling all tasks." );
736+ for (int i = 0 ; i < CONFIG_NRF_RPC_CMD_CTX_POOL_SIZE ; i ++ ) {
737+ struct nrf_rpc_cmd_ctx * ctx = & cmd_ctx_pool [i ];
738+ nrf_rpc_os_mutex_lock (& ctx -> mutex );
739+ if (ctx -> use_count > 0 ) {
740+ nrf_rpc_os_msg_set (& ctx -> recv_msg , NULL , 0 );
741+ }
742+ nrf_rpc_os_mutex_unlock (& ctx -> mutex );
743+ }
744+ }
745+
729746/* Callback from transport layer that handles incoming. */
730747static void receive_handler (const struct nrf_rpc_tr * transport , const uint8_t * packet , size_t len ,
731748 void * context )
@@ -742,6 +759,18 @@ static void receive_handler(const struct nrf_rpc_tr *transport, const uint8_t *p
742759 goto cleanup_and_exit ;
743760 }
744761
762+ if (is_stopped &&
763+ (hdr .type == NRF_RPC_PACKET_TYPE_CMD ||
764+ hdr .type == NRF_RPC_PACKET_TYPE_EVT ||
765+ hdr .type == NRF_RPC_PACKET_TYPE_ACK ||
766+ hdr .type == NRF_RPC_PACKET_TYPE_RSP )) {
767+ // drop only selected types of packets
768+ // do not drop INITs and ERRORS
769+
770+ NRF_RPC_WRN ("Dropping the packet." );
771+ goto cleanup_and_exit ;
772+ }
773+
745774 if (hdr .type == NRF_RPC_PACKET_TYPE_CMD ||
746775 hdr .type == NRF_RPC_PACKET_TYPE_EVT ||
747776 hdr .type == NRF_RPC_PACKET_TYPE_ACK ||
@@ -974,33 +1003,41 @@ int nrf_rpc_cmd_common(const struct nrf_rpc_group *group, uint32_t cmd,
9741003 handler_data = ptr2 ;
9751004 }
9761005
977- cmd_ctx = cmd_ctx_reserve ();
1006+ nrf_rpc_os_mutex_lock (& cleanup_mutex );
1007+ if (is_stopped ) {
1008+ err = - NRF_EPERM ;
1009+ nrf_rpc_os_mutex_unlock (& cleanup_mutex );
1010+ } else {
9781011
979- hdr .dst = cmd_ctx -> remote_id ;
980- hdr .src = cmd_ctx -> id ;
981- hdr .id = cmd & 0xFF ;
982- hdr .src_group_id = group -> data -> src_group_id ;
983- hdr .dst_group_id = group -> data -> dst_group_id ;
984- header_cmd_encode (full_packet , & hdr );
1012+ cmd_ctx = cmd_ctx_reserve ();
1013+ nrf_rpc_os_mutex_unlock (& cleanup_mutex ); /* release the mutex as the context specific one has been acquired */
9851014
986- old_handler = cmd_ctx -> handler ;
987- old_handler_data = cmd_ctx -> handler_data ;
988- cmd_ctx -> handler = handler ;
989- cmd_ctx -> handler_data = handler_data ;
1015+ hdr .dst = cmd_ctx -> remote_id ;
1016+ hdr .src = cmd_ctx -> id ;
1017+ hdr .id = cmd & 0xFF ;
1018+ hdr .src_group_id = group -> data -> src_group_id ;
1019+ hdr .dst_group_id = group -> data -> dst_group_id ;
1020+ header_cmd_encode (full_packet , & hdr );
9901021
991- NRF_RPC_DBG ("Sending command 0x%02X from group 0x%02X" , cmd ,
992- group -> data -> src_group_id );
1022+ old_handler = cmd_ctx -> handler ;
1023+ old_handler_data = cmd_ctx -> handler_data ;
1024+ cmd_ctx -> handler = handler ;
1025+ cmd_ctx -> handler_data = handler_data ;
9931026
994- err = send (group , full_packet , len + NRF_RPC_HEADER_SIZE );
1027+ NRF_RPC_DBG ("Sending command 0x%02X from group 0x%02X" , cmd ,
1028+ group -> data -> src_group_id );
9951029
996- if (err >= 0 ) {
997- err = wait_for_response (group , cmd_ctx , rsp_packet , rsp_len );
998- }
1030+ err = send (group , full_packet , len + NRF_RPC_HEADER_SIZE );
9991031
1000- cmd_ctx -> handler = old_handler ;
1001- cmd_ctx -> handler_data = old_handler_data ;
1032+ if (err >= 0 ) {
1033+ err = wait_for_response (group , cmd_ctx , rsp_packet , rsp_len );
1034+ }
10021035
1003- cmd_ctx_release (cmd_ctx );
1036+ cmd_ctx -> handler = old_handler ;
1037+ cmd_ctx -> handler_data = old_handler_data ;
1038+
1039+ cmd_ctx_release (cmd_ctx );
1040+ }
10041041
10051042 return err ;
10061043}
@@ -1121,6 +1158,8 @@ int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
11211158 return 0 ;
11221159 }
11231160
1161+ nrf_rpc_os_mutex_init (& cleanup_mutex );
1162+
11241163 global_err_handler = err_handler ;
11251164
11261165 for (NRF_RPC_AUTO_ARR_FOR (iter , group , & nrf_rpc_groups_array ,
@@ -1195,6 +1234,50 @@ int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
11951234 return err ;
11961235}
11971236
1237+ void nrf_rpc_register_cleanup_handler (struct nrf_rpc_cleanup_handler * handler )
1238+ {
1239+ nrf_rpc_os_mutex_lock (& cleanup_mutex );
1240+
1241+ struct nrf_rpc_cleanup_handler * current ;
1242+
1243+ // make sure not added twice
1244+ for (current = cleanup_handlers ; current != NULL ; current = current -> next ) {
1245+ if (current == handler ) {
1246+ break ;
1247+ }
1248+ }
1249+
1250+ if (current == NULL ) {
1251+ handler -> next = cleanup_handlers ;
1252+ cleanup_handlers = handler ;
1253+ }
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+ if (current -> handler != NULL ) {
1268+ current -> handler (current -> context );
1269+ }
1270+ }
1271+ }
1272+
1273+ nrf_rpc_os_mutex_unlock (& cleanup_mutex );
1274+ }
1275+
1276+ void nrf_rpc_resume (void )
1277+ {
1278+ is_stopped = false;
1279+ }
1280+
11981281int nrf_rpc_cmd (const struct nrf_rpc_group * group , uint8_t cmd , uint8_t * packet ,
11991282 size_t len , nrf_rpc_handler_t handler , void * handler_data )
12001283{
0 commit comments