diff --git a/include/coap/coap_session.h b/include/coap/coap_session.h index b3841d5c..060d9d3a 100644 --- a/include/coap/coap_session.h +++ b/include/coap/coap_session.h @@ -68,6 +68,7 @@ typedef struct coap_session_t { struct coap_context_t *context; /**< session's context */ void *tls; /**< security parameters */ uint16_t tx_mid; /**< the last message id that was used in this session */ + uint8_t con_active; /**< Active CON request sent */ struct coap_queue_t *sendqueue; /**< list of messages waiting to be sent */ size_t partial_write; /**< if > 0 indicates number of bytes already written from the pdu at the head of sendqueue */ uint8_t read_header[8]; /**< storage space for header of incoming message header */ diff --git a/src/net.c b/src/net.c index c7cbfa61..bd5ee83b 100644 --- a/src/net.c +++ b/src/net.c @@ -617,6 +617,9 @@ coap_session_send_pdu(coap_session_t *session, coap_pdu_t *pdu) { default: break; } + if (LOG_DEBUG <= coap_get_log_level()) { + coap_show_pdu(pdu); + } return bytes_written; } @@ -631,7 +634,12 @@ coap_send_pdu(coap_session_t *session, coap_pdu_t *pdu, coap_queue_t *node) { assert(session->endpoint != NULL); sock = &session->endpoint->sock; } + if (pdu->type == COAP_MESSAGE_CON) + session->con_active++; bytes_written = coap_socket_send_pdu(sock, session, pdu); + if (LOG_DEBUG <= coap_get_log_level()) { + coap_show_pdu(pdu); + } coap_ticks(&session->last_rx_tx); #else @@ -682,13 +690,17 @@ coap_send_pdu(coap_session_t *session, coap_pdu_t *pdu, coap_queue_t *node) { } } - if (session->state != COAP_SESSION_STATE_ESTABLISHED) + if (session->state != COAP_SESSION_STATE_ESTABLISHED || + (pdu->type == COAP_MESSAGE_CON && session->con_active >= COAP_DEFAULT_NSTART)) { return coap_session_delay_pdu(session, pdu, node); + } if ((session->sock.flags & COAP_SOCKET_NOT_EMPTY) && (session->sock.flags & COAP_SOCKET_WANT_WRITE)) return coap_session_delay_pdu(session, pdu, node); + if (pdu->type == COAP_MESSAGE_CON) + session->con_active++; bytes_written = coap_session_send_pdu(session, pdu); #endif /* WITH_LWIP */ @@ -901,6 +913,8 @@ coap_retransmit(coap_context_t *context, coap_queue_t *node) { debug("** %s tid=%d: retransmission #%d\n", coap_session_str(node->session), node->id, node->retransmit_cnt); + if (node->session->con_active) + node->session->con_active--; bytes_written = coap_send_pdu(node->session, node->pdu, node); if (bytes_written == COAP_PDU_DELAYED) { @@ -934,6 +948,8 @@ coap_retransmit(coap_context_t *context, coap_queue_t *node) { coap_handle_failed_notify(context, node->session, &token); } #endif /* WITHOUT_OBSERVE */ + if (node->session->con_active) + node->session->con_active--; /* And finally delete the node */ if (node->pdu->type == COAP_MESSAGE_CON && context->nack_handler) @@ -2070,8 +2086,10 @@ coap_dispatch(coap_context_t *context, coap_session_t *session, /* find transaction in sendqueue to stop retransmission */ coap_remove_from_queue(&context->sendqueue, session, pdu->tid, &sent); + if (session->con_active) + session->con_active--; if (pdu->code == 0) - goto cleanup; + goto cleanup; /* if sent code was >= 64 the message might have been a * notification. Then, we must flag the observer to be alive diff --git a/src/resource.c b/src/resource.c index 440feccc..f54311d7 100644 --- a/src/resource.c +++ b/src/resource.c @@ -712,6 +712,8 @@ coap_notify_observers(coap_context_t *context, coap_resource_t *r) { if (r->dirty == 0 && obs->dirty == 0) /* running this resource due to partiallydirty, but this observation's notification was already enqueued */ continue; + if (obs->session->con_active >= COAP_DEFAULT_NSTART) + continue; coap_tid_t tid = COAP_INVALID_TID; obs->dirty = 0;