Skip to content

Commit 7452f01

Browse files
committed
WIP:fix: send element stuck after TRANSMIT_COMPLETE_FAIL
TS fails to deliver a fragmented frame it called send_data_callback_func(TRANSMIT_COMPLETE_FAIL), in this cause the TS does not pop the falied session. Subsequent sends appended a fresh frame to the tail while the stale 48-byte session stayed at the head, causing all following commands to be re-driven through Transport Service regardless of their actual size. Fix a potential double-callback in fc_timer_expired: after invoking completedFunc in the flag_replied_frag_req path, null the pointer so the transmission_aborted guard cannot call it a second time if the timer fires again.
1 parent 8ec2d1c commit 7452f01

4 files changed

Lines changed: 26 additions & 7 deletions

File tree

libs2/protocol/S2.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "misc.h"
1313
#include "../inclusion/s2_inclusion_internal.h"
1414
#include<string.h>
15+
#include <stdio.h>
1516
#include "ccm.h"
1617
#include "aes_cmac.h"
1718
#include "nextnonce.h"
@@ -447,6 +448,9 @@ S2_encrypt_and_send(struct S2* p_context)
447448

448449
hdr_len = 4;
449450
n_ext = 0;
451+
printf("[ZGW-3457] S2_encrypt_and_send: src=%u dst=%u plaintext=%u span_state=%u\n",
452+
ctxt->peer.l_node, ctxt->peer.r_node, ctxt->length, span->state);
453+
fflush(stdout);
450454
DPRINT("S2_encrypt_and_send\r\n");
451455
/*If span is not negotiated, include senders nonce (SN) */
452456
ext_data = &msg[4];
@@ -567,6 +571,9 @@ S2_encrypt_and_send(struct S2* p_context)
567571
debug_print_hex(ciphertext, msg_len);
568572

569573
ASSERT(msg_len > 0);
574+
printf("[ZGW-3457] S2_encrypt_and_send: total_frame=%u (hdr=%u shdr=%u payload=%u mic=%u)\n",
575+
msg_len + hdr_len, hdr_len, shdr_len, ctxt->length, msg_len - ctxt->length - shdr_len);
576+
fflush(stdout);
570577
S2_send_raw(ctxt, msg, msg_len + hdr_len);
571578
}
572579

libs2/transport_service/transport_service2.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ void fc_timer_expired(void *nthing)
512512
#else
513513
scb.cmn.completedFunc(S2_TRANSMIT_COMPLETE_FAIL, 0);
514514
#endif
515+
scb.cmn.completedFunc = NULL;
515516
}
516517
return;
517518
}

src/transport/S2_wrap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ uint8_t S2_send_frame(struct S2* ctxt,const s2_connection_t* conn, uint8_t* buf,
603603
p.snode = conn->l_node;
604604
p.dnode = conn->r_node;
605605
p.tx_flags = conn->zw_tx_options;
606-
LOG_PRINTF(" Sending S2_send_frame %i %d -> %d\n", len, p.snode, p.dnode);
606+
LOG_PRINTF("[ZGW-3457] S2_send_frame: len=%i src=%d dst=%d\n", len, p.snode, p.dnode);
607607
transmit_start_time = clock_time();
608608
return send_data(&p, buf, len,S2_send_frame_callback,ctxt);
609609
}

src/transport/ZW_SendDataAppl.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -280,33 +280,39 @@ do_discard_timeout_memb(void * data)
280280
static void
281281
send_data_callback_func(u8_t status, TX_STATUS_TYPE* ts)
282282
{
283-
LOG_PRINTF("send_data_callback_func() | status %d\n", status);
283+
LOG_PRINTF("[ZGW-3457] send_data_callback_func: status=%d\n", status);
284284
enum en_queue_state queue_state = get_queue_state();
285285

286286
if(!lock_ll) {
287287
ERR_PRINTF("Double callback?\n");
288288
return;
289289
}
290290

291-
292-
// if (status == TRANSMIT_COMPLETE_NO_ACK)
291+
// TS and other senders report TRANSMIT_COMPLETE_FAIL. Pop and
292+
// free the session so the queue advances; the original hold-for-retry
293+
// behaviour (previously on NO_ACK) is preserved only when the resend watchdog
294+
// is active.
293295
if (status == TRANSMIT_COMPLETE_FAIL)
294296
{
295297
etimer_stop(&emergency_timer);
296298

297299
if(resend_counter == 0) {
298-
send_data_appl_session_t *s = list_head(send_data_list);
300+
send_data_appl_session_t *s = list_pop(send_data_list);
299301
if (s)
300302
{
303+
zw_frame_buffer_free(s->fb);
304+
memb_free(&session_memb, s);
301305
if (s->callback)
302306
{
303307
s->callback(status, s->user, ts);
304308
}
305309
}
306310
else
307311
{
312+
DBG_PRINTF("event in the send data list is NULL\n");
308313
ASSERT(0);
309314
}
315+
process_post(&ZW_SendDataAppl_process, SEND_EVENT_SEND_NEXT_LL, NULL);
310316
}
311317

312318
lock_ll = FALSE;
@@ -795,6 +801,11 @@ PROCESS_THREAD(ZW_SendDataAppl_process, ev, data)
795801
DBG_PRINTF("SEND_EVENT_SEND_NEXT_LL | current_session_ll: %p | lock_ll %u\n", current_session_ll, lock_ll);
796802
if (current_session_ll && lock_ll == FALSE)
797803
{
804+
LOG_PRINTF("[ZGW-3457] SEND_NEXT_LL: routing session %p snode=%u dnode=%u frame_len=%u\n",
805+
(void*)current_session_ll,
806+
(unsigned)current_session_ll->fb->param.snode,
807+
(unsigned)current_session_ll->fb->param.dnode,
808+
(unsigned)current_session_ll->fb->frame_len);
798809
if(current_session_ll->fb->param.discard_timeout)
799810
{
800811
//Prevent a timer to discard the frame if the session has a discard_timeout defined.
@@ -810,7 +821,7 @@ PROCESS_THREAD(ZW_SendDataAppl_process, ev, data)
810821
if (SupportsCmdClass(current_session_ll->fb->param.dnode,
811822
COMMAND_CLASS_TRANSPORT_SERVICE))
812823
{
813-
DBG_PRINTF("SEND_EVENT_SEND_NEXT_LL | SupportsCmdClass | ZW_TransportService_SendData \n");
824+
LOG_PRINTF("[ZGW-3457] SEND_NEXT_LL: -> ZW_TransportService_SendData\n");
814825
LOG_PRINTF("[ZGW-3457][TS] SendDataAppl->TransportService snode=%u dnode=%u frame_len=%u dnode_low8=%u\n",
815826
(unsigned)current_session_ll->fb->param.snode,
816827
(unsigned)current_session_ll->fb->param.dnode,
@@ -843,7 +854,7 @@ PROCESS_THREAD(ZW_SendDataAppl_process, ev, data)
843854
{
844855
if (current_session_ll->fb->param.snode != MyNodeID)
845856
{
846-
DBG_PRINTF("SEND_EVENT_SEND_NEXT_LL | ZW_SendData_Bridge \n");
857+
LOG_PRINTF("[ZGW-3457] SEND_NEXT_LL: -> ZW_SendData_Bridge\n");
847858
if (etimer_expired(&resend_lockup_timer) && (cfg.time_resend_serial != 0)) {
848859
DBG_PRINTF("etimer_set resend_lockup_timer with time: %d \n", cfg.time_resend_serial);
849860
etimer_set(&resend_lockup_timer, 1000UL * cfg.time_resend_serial);

0 commit comments

Comments
 (0)