@@ -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,21 @@ 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_WRN ("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_WRN ("Canceling context %u." , ctx -> id );
741+ nrf_rpc_os_msg_set (& ctx -> recv_msg , NULL , 0 );
742+ }
743+ nrf_rpc_os_mutex_unlock (& ctx -> mutex );
744+ }
745+ NRF_RPC_WRN ("Canceling all tasks done." );
746+ }
747+
729748/* Callback from transport layer that handles incoming. */
730749static void receive_handler (const struct nrf_rpc_tr * transport , const uint8_t * packet , size_t len ,
731750 void * context )
@@ -742,6 +761,18 @@ static void receive_handler(const struct nrf_rpc_tr *transport, const uint8_t *p
742761 goto cleanup_and_exit ;
743762 }
744763
764+ if (is_stopped &&
765+ (hdr .type == NRF_RPC_PACKET_TYPE_CMD ||
766+ hdr .type == NRF_RPC_PACKET_TYPE_EVT ||
767+ hdr .type == NRF_RPC_PACKET_TYPE_ACK ||
768+ hdr .type == NRF_RPC_PACKET_TYPE_RSP )) {
769+ // drop only selected types of packets
770+ // do not drop INITs and ERRORS
771+
772+ NRF_RPC_WRN ("Dropping the packet." );
773+ goto cleanup_and_exit ;
774+ }
775+
745776 if (hdr .type == NRF_RPC_PACKET_TYPE_CMD ||
746777 hdr .type == NRF_RPC_PACKET_TYPE_EVT ||
747778 hdr .type == NRF_RPC_PACKET_TYPE_ACK ||
@@ -974,33 +1005,41 @@ int nrf_rpc_cmd_common(const struct nrf_rpc_group *group, uint32_t cmd,
9741005 handler_data = ptr2 ;
9751006 }
9761007
977- cmd_ctx = cmd_ctx_reserve ();
1008+ nrf_rpc_os_mutex_lock (& cleanup_mutex );
1009+ if (is_stopped ) {
1010+ err = - NRF_EPERM ;
1011+ nrf_rpc_os_mutex_unlock (& cleanup_mutex );
1012+ } else {
9781013
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 );
1014+ cmd_ctx = cmd_ctx_reserve ();
1015+ nrf_rpc_os_mutex_unlock (& cleanup_mutex ); /* release the mutex as the context specific one has been acquired */
9851016
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 ;
1017+ hdr .dst = cmd_ctx -> remote_id ;
1018+ hdr .src = cmd_ctx -> id ;
1019+ hdr .id = cmd & 0xFF ;
1020+ hdr .src_group_id = group -> data -> src_group_id ;
1021+ hdr .dst_group_id = group -> data -> dst_group_id ;
1022+ header_cmd_encode (full_packet , & hdr );
9901023
991- NRF_RPC_DBG ("Sending command 0x%02X from group 0x%02X" , cmd ,
992- group -> data -> src_group_id );
1024+ old_handler = cmd_ctx -> handler ;
1025+ old_handler_data = cmd_ctx -> handler_data ;
1026+ cmd_ctx -> handler = handler ;
1027+ cmd_ctx -> handler_data = handler_data ;
9931028
994- err = send (group , full_packet , len + NRF_RPC_HEADER_SIZE );
1029+ NRF_RPC_DBG ("Sending command 0x%02X from group 0x%02X" , cmd ,
1030+ group -> data -> src_group_id );
9951031
996- if (err >= 0 ) {
997- err = wait_for_response (group , cmd_ctx , rsp_packet , rsp_len );
998- }
1032+ err = send (group , full_packet , len + NRF_RPC_HEADER_SIZE );
1033+
1034+ if (err >= 0 ) {
1035+ err = wait_for_response (group , cmd_ctx , rsp_packet , rsp_len );
1036+ }
9991037
1000- cmd_ctx -> handler = old_handler ;
1001- cmd_ctx -> handler_data = old_handler_data ;
1038+ cmd_ctx -> handler = old_handler ;
1039+ cmd_ctx -> handler_data = old_handler_data ;
10021040
1003- cmd_ctx_release (cmd_ctx );
1041+ cmd_ctx_release (cmd_ctx );
1042+ }
10041043
10051044 return err ;
10061045}
@@ -1121,6 +1160,8 @@ int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
11211160 return 0 ;
11221161 }
11231162
1163+ nrf_rpc_os_mutex_init (& cleanup_mutex );
1164+
11241165 global_err_handler = err_handler ;
11251166
11261167 for (NRF_RPC_AUTO_ARR_FOR (iter , group , & nrf_rpc_groups_array ,
@@ -1195,6 +1236,46 @@ int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
11951236 return err ;
11961237}
11971238
1239+ void nrf_rpc_register_cleanup_handler (struct nrf_rpc_cleanup_handler * handler )
1240+ {
1241+ nrf_rpc_os_mutex_lock (& cleanup_mutex );
1242+
1243+ struct nrf_rpc_cleanup_handler * current ;
1244+
1245+ // make sure not added twice
1246+ for (current = cleanup_handlers ; current != NULL ; current = current -> next ) {
1247+ if (current == handler ) {
1248+ break ;
1249+ }
1250+ }
1251+
1252+ if (current == NULL ) {
1253+ handler -> next = cleanup_handlers ;
1254+ cleanup_handlers = handler ;
1255+ }
1256+ nrf_rpc_os_mutex_unlock (& cleanup_mutex );
1257+ }
1258+
1259+ void nrf_rpc_stop (bool cleanup )
1260+ {
1261+ nrf_rpc_os_mutex_lock (& cleanup_mutex );
1262+
1263+ is_stopped = true;
1264+ abort_all_ops ();
1265+ if (cleanup ) {
1266+ struct nrf_rpc_cleanup_handler * current ;
1267+ for (current = cleanup_handlers ; current != NULL ; current = current -> next ) {
1268+ current -> handler (current -> context );
1269+ }
1270+ }
1271+ nrf_rpc_os_mutex_unlock (& cleanup_mutex );
1272+ }
1273+
1274+ void nrf_rpc_resume (void )
1275+ {
1276+ is_stopped = false;
1277+ }
1278+
11981279int nrf_rpc_cmd (const struct nrf_rpc_group * group , uint8_t cmd , uint8_t * packet ,
11991280 size_t len , nrf_rpc_handler_t handler , void * handler_data )
12001281{
0 commit comments