Skip to content

Commit 33b10f5

Browse files
committed
nRF RPC: cancel ongoing commands on peer reboot
If out-of-order initialization packet is received from the peer, cancel ongoing commands waiting for a response as the response is never going to arrive. Signed-off-by: Damian Krolik <[email protected]>
1 parent 9f5da70 commit 33b10f5

File tree

1 file changed

+37
-4
lines changed

1 file changed

+37
-4
lines changed

nrf_rpc/nrf_rpc.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@
2121
#pragma GCC diagnostic ignored "-Warray-bounds"
2222
#endif
2323

24-
/* A pointer value to pass information that response */
24+
/* A pointer value to pass information that the response has been handled in the receive thread. */
2525
#define RESPONSE_HANDLED_PTR ((uint8_t *)1)
2626

27+
/* A pointer value to pass information that the connection has been reset. */
28+
#define CONNECTION_RESET_PTR ((uint8_t *)2)
29+
2730
/* Internal definition used in the macros. */
2831
#define NRF_RPC_HEADER_SIZE 5
2932

@@ -50,6 +53,7 @@ struct nrf_rpc_cmd_ctx {
5053
uint8_t use_count; /* Context usage counter. It increases
5154
* each time context is reused.
5255
*/
56+
const struct nrf_rpc_group* group;
5357
nrf_rpc_handler_t handler; /* Response handler provided be the user. */
5458
void *handler_data; /* Pointer for the response handler. */
5559
struct nrf_rpc_os_msg recv_msg;
@@ -650,6 +654,18 @@ static int init_packet_parse(struct init_packet_data *init_data, const uint8_t *
650654
return 0;
651655
}
652656

657+
static void cancel_wait_for_response(const struct nrf_rpc_group* group)
658+
{
659+
for (size_t i = 0; i < CONFIG_NRF_RPC_CMD_CTX_POOL_SIZE; ++i) {
660+
struct nrf_rpc_cmd_ctx* cmd_ctx = &cmd_ctx_pool[i];
661+
662+
if (cmd_ctx->group == group) {
663+
nrf_rpc_os_msg_set(&cmd_ctx->recv_msg,
664+
CONNECTION_RESET_PTR, 0);
665+
}
666+
}
667+
}
668+
653669
static int init_packet_handle(struct header *hdr, const struct nrf_rpc_group **group,
654670
const uint8_t *packet, size_t len)
655671
{
@@ -709,6 +725,13 @@ static int init_packet_handle(struct header *hdr, const struct nrf_rpc_group **g
709725
*/
710726
needs_reply = (hdr->dst_group_id == NRF_RPC_ID_UNKNOWN);
711727

728+
/*
729+
* If the connection has been reset, cancel any ongoing commands waiting for response.
730+
*/
731+
if (!first_init && needs_reply) {
732+
cancel_wait_for_response(*group);
733+
}
734+
712735
/*
713736
* Spawn the async task only if necessary. The async task is used to avoid sending the init
714737
* reply in the transport receive thread. The application is also notified about the group
@@ -888,7 +911,7 @@ void nrf_rpc_decoding_done(const struct nrf_rpc_group *group, const uint8_t *pac
888911
* @param[out] rsp_len If not NULL contains response packet length.
889912
* @return 0 on success or negative error code.
890913
*/
891-
static void wait_for_response(const struct nrf_rpc_group *group, struct nrf_rpc_cmd_ctx *cmd_ctx,
914+
static int wait_for_response(const struct nrf_rpc_group *group, struct nrf_rpc_cmd_ctx *cmd_ctx,
892915
const uint8_t **rsp_packet, size_t *rsp_len)
893916
{
894917
size_t len;
@@ -905,7 +928,11 @@ static void wait_for_response(const struct nrf_rpc_group *group, struct nrf_rpc_
905928
NRF_RPC_ASSERT(packet != NULL);
906929

907930
if (packet == RESPONSE_HANDLED_PTR) {
908-
return;
931+
return 0;
932+
}
933+
934+
if (packet == CONNECTION_RESET_PTR) {
935+
return -NRF_ECONNRESET;
909936
}
910937

911938
type = parse_incoming_packet(cmd_ctx, packet, len);
@@ -927,13 +954,16 @@ static void wait_for_response(const struct nrf_rpc_group *group, struct nrf_rpc_
927954

928955
nrf_rpc_decoding_done(group, &packet[NRF_RPC_HEADER_SIZE]);
929956
}
957+
958+
return 0;
930959
}
931960

932961
int nrf_rpc_cmd_common(const struct nrf_rpc_group *group, uint32_t cmd,
933962
uint8_t *packet, size_t len, void *ptr1, void *ptr2)
934963
{
935964
int err;
936965
struct header hdr;
966+
const struct nrf_rpc_group* old_group;
937967
nrf_rpc_handler_t old_handler;
938968
void *old_handler_data;
939969
uint8_t *full_packet = &packet[-NRF_RPC_HEADER_SIZE];
@@ -968,8 +998,11 @@ int nrf_rpc_cmd_common(const struct nrf_rpc_group *group, uint32_t cmd,
968998
hdr.dst_group_id = group->data->dst_group_id;
969999
header_cmd_encode(full_packet, &hdr);
9701000

1001+
old_group = cmd_ctx->group;
9711002
old_handler = cmd_ctx->handler;
9721003
old_handler_data = cmd_ctx->handler_data;
1004+
1005+
cmd_ctx->group = group;
9731006
cmd_ctx->handler = handler;
9741007
cmd_ctx->handler_data = handler_data;
9751008

@@ -979,7 +1012,7 @@ int nrf_rpc_cmd_common(const struct nrf_rpc_group *group, uint32_t cmd,
9791012
err = send(group, full_packet, len + NRF_RPC_HEADER_SIZE);
9801013

9811014
if (err >= 0) {
982-
wait_for_response(group, cmd_ctx, rsp_packet, rsp_len);
1015+
err = wait_for_response(group, cmd_ctx, rsp_packet, rsp_len);
9831016
}
9841017

9851018
cmd_ctx->handler = old_handler;

0 commit comments

Comments
 (0)