Skip to content

Commit

Permalink
NACK handling: simplify libcoap code
Browse files Browse the repository at this point in the history
Remove a lot of code duplication by providing new coap_handle_nack()
function.
  • Loading branch information
mrdeep1 committed Oct 19, 2024
1 parent 7f14e0a commit 92b3db2
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 89 deletions.
5 changes: 5 additions & 0 deletions include/coap3/coap_session_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,11 @@ void coap_read_session(coap_context_t *ctx, coap_session_t *session, coap_tick_t

void coap_connect_session(coap_session_t *session, coap_tick_t now);

void coap_handle_nack(coap_session_t *session,
coap_pdu_t *sent,
const coap_nack_reason_t reason,
const coap_mid_t mid);

#define COAP_SESSION_REF(s) ((s)->ref

/* RFC7252 */
Expand Down
7 changes: 2 additions & 5 deletions src/coap_block.c
Original file line number Diff line number Diff line change
Expand Up @@ -1470,11 +1470,8 @@ coap_block_check_lg_crcv_timeouts(coap_session_t *session, coap_tick_t now,

if (lg_crcv->rec_blocks.retry >= COAP_NON_MAX_RETRANSMIT(session)) {
/* Done NON_MAX_RETRANSMIT retries */
coap_update_token(&lg_crcv->pdu, lg_crcv->app_token->length, lg_crcv->app_token->s);
coap_lock_callback(session->context,
session->context->nack_handler(session, &lg_crcv->pdu,
COAP_NACK_TOO_MANY_RETRIES,
lg_crcv->pdu.mid));
coap_handle_nack(session, &lg_crcv->pdu,
COAP_NACK_TOO_MANY_RETRIES, lg_crcv->pdu.mid);
goto expire;
}
if (lg_crcv->rec_blocks.last_seen + scaled_timeout <= now) {
Expand Down
44 changes: 11 additions & 33 deletions src/coap_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -1997,11 +1997,8 @@ coap_retransmit(coap_context_t *context, coap_queue_t *node) {
}

/* And finally delete the node */
if (node->pdu->type == COAP_MESSAGE_CON && context->nack_handler) {
coap_check_update_token(node->session, node->pdu);
coap_lock_callback(context,
context->nack_handler(node->session, node->pdu,
COAP_NACK_TOO_MANY_RETRIES, node->id));
if (node->pdu->type == COAP_MESSAGE_CON) {
coap_handle_nack(node->session, node->pdu, COAP_NACK_TOO_MANY_RETRIES, node->id);
}
coap_delete_node_lkd(node);
return COAP_INVALID_MID;
Expand Down Expand Up @@ -2579,10 +2576,8 @@ coap_cancel_session_messages(coap_context_t *context, coap_session_t *session,
context->sendqueue = q->next;
coap_log_debug("** %s: mid=0x%04x: removed (3)\n",
coap_session_str(session), q->id);
if (q->pdu->type == COAP_MESSAGE_CON && context->nack_handler) {
coap_check_update_token(session, q->pdu);
coap_lock_callback(context,
context->nack_handler(session, q->pdu, reason, q->id));
if (q->pdu->type == COAP_MESSAGE_CON) {
coap_handle_nack(session, q->pdu, reason, q->id);
}
coap_delete_node_lkd(q);
}
Expand All @@ -2598,10 +2593,8 @@ coap_cancel_session_messages(coap_context_t *context, coap_session_t *session,
p->next = q->next;
coap_log_debug("** %s: mid=0x%04x: removed (4)\n",
coap_session_str(session), q->id);
if (q->pdu->type == COAP_MESSAGE_CON && context->nack_handler) {
coap_check_update_token(session, q->pdu);
coap_lock_callback(context,
context->nack_handler(session, q->pdu, reason, q->id));
if (q->pdu->type == COAP_MESSAGE_CON) {
coap_handle_nack(session, q->pdu, reason, q->id);
}
coap_delete_node_lkd(q);
q = p->next;
Expand Down Expand Up @@ -4132,11 +4125,8 @@ coap_dispatch(coap_context_t *context, coap_session_t *session,
coap_cancel(context, sent);

if (!is_ping_rst && !is_ext_token_rst) {
if (sent->pdu->type==COAP_MESSAGE_CON && context->nack_handler) {
coap_check_update_token(sent->session, sent->pdu);
coap_lock_callback(context,
context->nack_handler(sent->session, sent->pdu,
COAP_NACK_RST, sent->id));
if (sent->pdu->type==COAP_MESSAGE_CON) {
coap_handle_nack(sent->session, sent->pdu, COAP_NACK_RST, sent->id);
}
} else if (is_ping_rst) {
if (context->pong_handler) {
Expand All @@ -4156,21 +4146,14 @@ coap_dispatch(coap_context_t *context, coap_session_t *session,
/* Need to do this now as session may get de-referenced */
coap_session_reference_lkd(session);
coap_delete_observer(r, session, &obs->pdu->actual_token);
if (context->nack_handler) {
coap_lock_callback(context,
context->nack_handler(session, NULL,
COAP_NACK_RST, pdu->mid));
}
coap_handle_nack(session, NULL, COAP_NACK_RST, pdu->mid);
coap_session_release_lkd(session);
goto cleanup;
}
}
}
#endif /* COAP_SERVER_SUPPORT */
if (context->nack_handler) {
coap_lock_callback(context,
context->nack_handler(session, NULL, COAP_NACK_RST, pdu->mid));
}
coap_handle_nack(session, NULL, COAP_NACK_RST, pdu->mid);
}
goto cleanup;

Expand Down Expand Up @@ -4265,12 +4248,7 @@ coap_dispatch(coap_context_t *context, coap_session_t *session,
cleanup:
if (packet_is_bad) {
if (sent) {
if (context->nack_handler) {
coap_check_update_token(session, sent->pdu);
coap_lock_callback(context,
context->nack_handler(session, sent->pdu,
COAP_NACK_BAD_RESPONSE, sent->id));
}
coap_handle_nack(session, sent->pdu, COAP_NACK_BAD_RESPONSE, sent->id);
} else {
coap_handle_event_lkd(context, COAP_EVENT_BAD_PACKET, session);
}
Expand Down
110 changes: 59 additions & 51 deletions src/coap_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,13 +535,11 @@ coap_session_mfree(coap_session_t *session) {
}
#endif /* COAP_SERVER_SUPPORT */
LL_FOREACH_SAFE(session->delayqueue, q, tmp) {
if (q->pdu->type==COAP_MESSAGE_CON && session->context->nack_handler) {
coap_check_update_token(session, q->pdu);
coap_lock_callback(session->context,
session->context->nack_handler(session, q->pdu,
session->proto == COAP_PROTO_DTLS ?
COAP_NACK_TLS_FAILED : COAP_NACK_NOT_DELIVERABLE,
q->id));
if (q->pdu->type==COAP_MESSAGE_CON) {
coap_handle_nack(session, q->pdu,
session->proto == COAP_PROTO_DTLS ?
COAP_NACK_TLS_FAILED : COAP_NACK_NOT_DELIVERABLE,
q->id);
}
coap_delete_node_lkd(q);
}
Expand Down Expand Up @@ -904,6 +902,26 @@ coap_nack_name(coap_nack_reason_t reason) {
}
#endif /* COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_DEBUG */

void
coap_handle_nack(coap_session_t *session,
coap_pdu_t *sent,
const coap_nack_reason_t reason,
const coap_mid_t mid) {
if (session->context->nack_handler) {
coap_bin_const_t token;

if (sent) {
coap_check_update_token(session, sent);
token = sent->actual_token;
}
coap_lock_callback(session->context,
session->context->nack_handler(session, sent, reason, mid));
if (sent) {
coap_update_token(sent, token.length, token.s);
}
}
}

COAP_API void
coap_session_disconnected(coap_session_t *session, coap_nack_reason_t reason) {
coap_lock_lock(session->context, return);
Expand All @@ -923,57 +941,47 @@ coap_session_disconnected_lkd(coap_session_t *session, coap_nack_reason_t reason
#if COAP_CLIENT_SUPPORT
coap_lg_crcv_t *cq, *etmp;
#endif /* COAP_CLIENT_SUPPORT */
int sent_nack = 0;
coap_queue_t *q;

coap_lock_check_locked(session->context);
if (session->context->nack_handler) {
int sent_nack = 0;
coap_queue_t *q = session->context->sendqueue;

while (q) {
if (q->session == session) {
/* Take the first one */
coap_bin_const_t token = q->pdu->actual_token;

coap_check_update_token(session, q->pdu);
coap_lock_callback(session->context,
session->context->nack_handler(session, q->pdu, reason, q->id));
coap_update_token(q->pdu, token.length, token.s);
q = session->context->sendqueue;

while (q) {
if (q->session == session) {
/* Take the first one */
coap_handle_nack(session, q->pdu, reason, q->id);
sent_nack = 1;
break;
}
q = q->next;
}

if (reason != COAP_NACK_ICMP_ISSUE) {
while (session->delayqueue) {
q = session->delayqueue;
session->delayqueue = q->next;
q->next = NULL;
coap_log_debug("** %s: mid=0x%04x: not transmitted after disconnect\n",
coap_session_str(session), q->id);
if (q->pdu->type == COAP_MESSAGE_CON) {
coap_handle_nack(session, q->pdu, reason, q->id);
sent_nack = 1;
break;
}
q = q->next;
}

if (reason != COAP_NACK_ICMP_ISSUE) {
while (session->delayqueue) {
q = session->delayqueue;
session->delayqueue = q->next;
q->next = NULL;
coap_log_debug("** %s: mid=0x%04x: not transmitted after disconnect\n",
coap_session_str(session), q->id);
if (q->pdu->type == COAP_MESSAGE_CON) {
coap_check_update_token(session, q->pdu);
coap_lock_callback(session->context,
session->context->nack_handler(session, q->pdu, reason, q->id));
sent_nack = 1;
}
coap_delete_node_lkd(q);
}
coap_delete_node_lkd(q);
}
}
#if COAP_CLIENT_SUPPORT
if (!sent_nack && session->lg_crcv) {
/* Take the first one */
coap_lock_callback(session->context,
session->context->nack_handler(session, &session->lg_crcv->pdu, reason,
session->lg_crcv->pdu.mid));
sent_nack = 1;
}
if (!sent_nack && session->lg_crcv) {
/* Take the first one */
coap_handle_nack(session, &session->lg_crcv->pdu, reason, session->lg_crcv->pdu.mid);
sent_nack = 1;
}
#endif /* COAP_CLIENT_SUPPORT */
if (!sent_nack) {
/* Unable to determine which request disconnection was for */
coap_lock_callback(session->context,
session->context->nack_handler(session, NULL, reason, 0));
}
if (!sent_nack) {
/* Unable to determine which request disconnection was for */
coap_handle_nack(session, NULL, reason, 0);
}
if (reason == COAP_NACK_ICMP_ISSUE) {
coap_log_debug("***%s: session ICMP issue (%s)\n",
Expand Down Expand Up @@ -1001,7 +1009,7 @@ coap_session_disconnected_lkd(coap_session_t *session, coap_nack_reason_t reason

/* Not done if nack handler called above */
while (session->delayqueue) {
coap_queue_t *q = session->delayqueue;
q = session->delayqueue;
session->delayqueue = q->next;
q->next = NULL;
coap_log_debug("** %s: mid=0x%04x: not transmitted after disconnect\n",
Expand Down

0 comments on commit 92b3db2

Please sign in to comment.