Repository navigation
Conversation
| @@ -1314,8 +1335,10 @@ static inline ssize_t unicoap_pdu_build_rfc7252(uint8_t* pdu, size_t capacity, | |||
| const unicoap_message_properties_t* properties) | |||
| { | |||
| ssize_t res = 0; | |||
|
|
|||
| if ((res = unicoap_pdu_build_header_rfc7252(pdu, capacity, message, properties)) < 0) { | |||
| if ((res = unicoap_pdu_build_header_rfc7252(pdu, capacity, message, properties)) < 0 || | |||
| unlikely(!message) | |||
| ) { | |||
| /* If failed, return. Also, if no message, there're no options and no payload, so return. */ | |||
There was a problem hiding this comment.
Purpose: be able to build PDU without needing to allocate a message structure, which can be larger than the actual on-the-wire PDU we're trying to create. Would be kinda laughable if a helper struct was bigger than the actual on-the-wire PDU...
| /* Require allocated message struct unless it's an empty message. This saves memory at the call | ||
| * site when sending an (empty) ACK or RST. */ | ||
| assert(packet->message || | ||
| _get_type(packet) == UNICOAP_TYPE_ACK || | ||
| _get_type(packet) == UNICOAP_TYPE_RST); |
| static int _acknowledge_or_reset(unicoap_packet_t* packet, unicoap_rfc7252_message_type_t type) | ||
| { | ||
| packet->message->code = UNICOAP_CODE_EMPTY; | ||
| packet->message->options = NULL; | ||
| packet->message->payload = NULL; | ||
| packet->message->payload_size = 0; | ||
|
|
||
| packet->properties.token = NULL; | ||
| packet->properties.token_length = 0; | ||
|
|
||
| return (int)_build_and_send_pdu(packet, NULL); | ||
| /* This is all faster than going through the PDU builder for an empty message. And it saves us | ||
| * stack allocations that we'd need to prepare for an arbitrary message (more iolist structs and | ||
| * bigger header buffer for additional token. */ | ||
| unicoap_rfc7252_header_t empty_message = { | ||
| .version = UNICOAP_COAP_VERSION_1, | ||
| .code = UNICOAP_CODE_EMPTY, | ||
| }; | ||
|
|
||
| iolist_t vector = { | ||
| .iol_base = &empty_message, | ||
| .iol_len = sizeof(empty_message) | ||
| }; | ||
|
|
||
| unicoap_rfc7252_header_set_message_id(&empty_message, _get_id(packet)); | ||
| unicoap_rfc7252_header_set_type(&empty_message, type); | ||
|
|
||
| /* We do not reconnect here for messaging-layer-only PDUs (empty ACKs and RSTs). | ||
| * Reason: If we send an ACK or RST that means we got a message before. This implies | ||
| * there was a DTLS session. RFC 7252 mandates ACKs and RSTs must be sent within the | ||
| * same epoch. A new DTLS session always leads to a new epoch. So sending an ACK or RST | ||
| * after reconnecting is pointless. Hence, we do not need to call _connect here and can | ||
| * just send, possibly getting an error from the DTLS transport layer if there's no session. */ | ||
| return _sendv(&vector, packet->remote, packet->local, _packet_get_dtls_session(packet)); |
There was a problem hiding this comment.
Faster than going through the PDU builder, allocating iolists, a scratch buffer, etc. The message we're trying to send is 4 bytes, so let's not be silly.
| if (_get_type(packet) == UNICOAP_TYPE_CON) { | ||
| MESSAGING_7252_DEBUG(UNICOAP_MESSAGE_ID_FORMAT "have not ACKed yet\n", _get_id(packet)); | ||
| assert(_state._unacknowledged_packet == NULL); | ||
| _state._unacknowledged_packet = packet; | ||
| /* TODO: Deferred responses (proxy) require space for more than one outstanding ACK. */ | ||
| } |
There was a problem hiding this comment.
This is safe because state access is synchronised by an event_queue_t.
| unicoap_message_t* message = packet->message; | ||
| unicoap_message_t m = *packet->message; | ||
| packet->message = &m; | ||
| _acknowledge(packet); | ||
| packet->message = message; |
| @@ -0,0 +1,207 @@ | |||
| /* | |||
There was a problem hiding this comment.
Basically, I can see people wanting to do some CoAP PDU trickery in the future, and providing a header here that exists but is hidden prevent's me from having that headache in the future.
924cd88 to
021d3eb
Compare
Murdock results❌ FAILED a5bb29f fixup! token bit width
Build failures (1)
Artifacts |
This PR introduces support for extended tokens (https://www.rfc-editor.org/info/rfc8974/#name-extended-tokens), fixes missing ACKs from reliable resources, reduces overhead when ACKing and RSTing, and moves PDU message header definitions into a private C header.
Testing procedure
make -C tests/unittests -j tests-unicoap flash termIssues/PRs references
Preparation for #23074 and #22277
Declaration of AI-Tools / LLMs usage:
AI-Tools / LLMs that were used are:
[upper .. lower]in designated initialisers