1010#include <stdbool.h>
1111#include <string.h>
1212
13+ #include <zephyr/kernel.h>
14+
1315#include "nrf_rpc.h"
1416#include "nrf_rpc_tr.h"
1517#include "nrf_rpc_os.h"
@@ -125,6 +127,7 @@ static uint8_t initialized_group_count;
125127
126128/* nRF RPC initialization status. */
127129static bool is_initialized ;
130+ static bool is_stopped ;
128131
129132/* Error handler provided to the init function. */
130133static nrf_rpc_err_handler_t global_err_handler ;
@@ -135,6 +138,9 @@ static nrf_rpc_group_bound_handler_t global_bound_handler;
135138static struct internal_task internal_task ;
136139static struct nrf_rpc_os_event internal_task_consumed ;
137140
141+ static struct nrf_rpc_os_mutex cleanup_mutex ;
142+ static struct nrf_rpc_cleanup_handler * cleanup_handlers ;
143+
138144/* Array with all defiend groups */
139145NRF_RPC_AUTO_ARR (nrf_rpc_groups_array , "grp" );
140146
@@ -738,6 +744,21 @@ static int init_packet_handle(struct header *hdr, const struct nrf_rpc_group **g
738744 return 0 ;
739745}
740746
747+ static void abort_all_ops (void )
748+ {
749+ NRF_RPC_WRN ("Canceling all tasks." );
750+ for (int i = 0 ; i < CONFIG_NRF_RPC_CMD_CTX_POOL_SIZE ; i ++ ) {
751+ struct nrf_rpc_cmd_ctx * ctx = & cmd_ctx_pool [i ];
752+ nrf_rpc_os_mutex_lock (& ctx -> mutex );
753+ if (ctx -> recv_msg .waiting > 0 ) {
754+ NRF_RPC_WRN ("Canceling context %u." , ctx -> id );
755+ nrf_rpc_os_msg_set (& ctx -> recv_msg , NULL , 0 );
756+ }
757+ nrf_rpc_os_mutex_unlock (& ctx -> mutex );
758+ }
759+ NRF_RPC_WRN ("Canceling all tasks done." );
760+ }
761+
741762/* Callback from transport layer that handles incoming. */
742763static void receive_handler (const struct nrf_rpc_tr * transport , const uint8_t * packet , size_t len ,
743764 void * context )
@@ -754,6 +775,17 @@ static void receive_handler(const struct nrf_rpc_tr *transport, const uint8_t *p
754775 goto cleanup_and_exit ;
755776 }
756777
778+ if (is_stopped &&
779+ (hdr .type == NRF_RPC_PACKET_TYPE_CMD ||
780+ hdr .type == NRF_RPC_PACKET_TYPE_EVT ||
781+ hdr .type == NRF_RPC_PACKET_TYPE_RSP )) {
782+ // drop only selected types of packets
783+ // do not drop ACKs INITs and ERRORS
784+
785+ NRF_RPC_WRN ("Dropping the packet." );
786+ goto cleanup_and_exit ;
787+ }
788+
757789 if (hdr .type == NRF_RPC_PACKET_TYPE_CMD ||
758790 hdr .type == NRF_RPC_PACKET_TYPE_EVT ||
759791 hdr .type == NRF_RPC_PACKET_TYPE_ACK ||
@@ -986,33 +1018,41 @@ int nrf_rpc_cmd_common(const struct nrf_rpc_group *group, uint32_t cmd,
9861018 handler_data = ptr2 ;
9871019 }
9881020
989- cmd_ctx = cmd_ctx_reserve ();
1021+ nrf_rpc_os_mutex_lock (& cleanup_mutex );
1022+ if (is_stopped ) {
1023+ err = - NRF_EPERM ;
1024+ nrf_rpc_os_mutex_unlock (& cleanup_mutex );
1025+ } else {
9901026
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 );
1027+ cmd_ctx = cmd_ctx_reserve ();
1028+ nrf_rpc_os_mutex_unlock (& cleanup_mutex ); /* release the mutex as the context specific one has been aqqured */
9971029
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 ;
1030+ hdr .dst = cmd_ctx -> remote_id ;
1031+ hdr .src = cmd_ctx -> id ;
1032+ hdr .id = cmd & 0xFF ;
1033+ hdr .src_group_id = group -> data -> src_group_id ;
1034+ hdr .dst_group_id = group -> data -> dst_group_id ;
1035+ header_cmd_encode (full_packet , & hdr );
10021036
1003- NRF_RPC_DBG ("Sending command 0x%02X from group 0x%02X" , cmd ,
1004- group -> data -> src_group_id );
1037+ old_handler = cmd_ctx -> handler ;
1038+ old_handler_data = cmd_ctx -> handler_data ;
1039+ cmd_ctx -> handler = handler ;
1040+ cmd_ctx -> handler_data = handler_data ;
10051041
1006- err = send (group , full_packet , len + NRF_RPC_HEADER_SIZE );
1042+ NRF_RPC_DBG ("Sending command 0x%02X from group 0x%02X" , cmd ,
1043+ group -> data -> src_group_id );
10071044
1008- if (err >= 0 ) {
1009- err = wait_for_response (group , cmd_ctx , rsp_packet , rsp_len );
1010- }
1045+ err = send (group , full_packet , len + NRF_RPC_HEADER_SIZE );
10111046
1012- cmd_ctx -> handler = old_handler ;
1013- cmd_ctx -> handler_data = old_handler_data ;
1047+ if (err >= 0 ) {
1048+ err = wait_for_response (group , cmd_ctx , rsp_packet , rsp_len );
1049+ }
10141050
1015- cmd_ctx_release (cmd_ctx );
1051+ cmd_ctx -> handler = old_handler ;
1052+ cmd_ctx -> handler_data = old_handler_data ;
1053+
1054+ cmd_ctx_release (cmd_ctx );
1055+ }
10161056
10171057 return err ;
10181058}
@@ -1133,6 +1173,8 @@ int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
11331173 return 0 ;
11341174 }
11351175
1176+ nrf_rpc_os_mutex_init (& cleanup_mutex );
1177+
11361178 global_err_handler = err_handler ;
11371179
11381180 for (NRF_RPC_AUTO_ARR_FOR (iter , group , & nrf_rpc_groups_array ,
@@ -1194,6 +1236,46 @@ int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
11941236 return err ;
11951237}
11961238
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+
11971279int nrf_rpc_cmd (const struct nrf_rpc_group * group , uint8_t cmd , uint8_t * packet ,
11981280 size_t len , nrf_rpc_handler_t handler , void * handler_data )
11991281{
0 commit comments