Skip to content

Confirmable Messaging

Ken Bannister edited this page Mar 15, 2020 · 25 revisions

This page describes the various messaging scenarios that gcoap must handle, particularly to integrate confirmable messaging. The new structs and functions mentioned below are included in a commit for illustration purposes.

  1. CON request, piggyback response

This is the most common confirmable scenario.

a. CON -->
b. <-- ACK/(RST?)

Server implementation is simple. The server at (b) reads the request, and responds with message type ACK. Support CON empty message request "ping" with an RST response?

Client implementation begins with marking a request as confirmable. The sender must call coap_hdr_set_type() after gcoap_req_init(). Alternatively, the sender can use the new gcoap_req_init_opts(), which includes message type. Eventually, gcoap_req_init() likely will use gcoap_req_init_opts() internally to avoid code duplication.

gcoap recognizes the confirmable request in gcoap_req_send2(). gcoap_request_memo_t has been extended to support the ability to resend a PDU. gcoap reuses nanocoap's macros for timeout, maximum number of retransmissions, etc., as used in nanocoap_get(). gcoap reuses its existing timeout mechanism for non-confirmable messages. A message is resent, if necessary, by the gcoap thread within the event loop mechanism. If resends are exhausted, the response handler callback is executed, as it is for non-confirmable messages.

In order to resend a PDU, gcoap must have access to the contents of the sent buffer. Initially, we plan to copy this buffer to the new resend_bufs array in gcoap_state. However, it looks feasible to use an alternative, synchronous approach that does not require this buffer. In other words, the initial request can block the sending thread after sending the message. gcoap then can maintain a pointer to the original PDU buffer for resends on the gcoap thread. When gcoap receives the response from the server or retries are exhausted, the sending thread can be resumed. This approach is similar to nanocoap's approach in nanocoap_get(), which is implemented with a single thread and blocks waiting for the response.

  1. CON request, separate response

The server responds with an empty ACK at (b). The semantic response in (d) actually is a request back to the client. So, the client must retain the request memo until (e).

a. CON -->
b. <-- ACK
c. ...
d. <-- CON (NON)
e. ACK/RST, if CON at (d) -->

The server handling at (b) is similar to scenario (1). However, the response is an empty message, so gcoap's internal handling must ensure any token is removed.

The client must set a timeout at (b) to clear the request memo in case it does not receive the semantic response at (d).

The server's semantic response at (d) is contained in a new confirmable message. However, the response reuses the token from the original request at (a). This requirement means the server must specify the token for the PDU rather than use the randomly generated value. Also, the response at (d) may be sent non-confirmably, but there are no extra issues with this choice.

  1. NON request and response

This is the common non-confirmable sequence that gcoap already handles.

a. NON -->
b. <-- NON/(RST)

A RST response at (b) is optional according to RFC 7252 if the server can't process the request. However, gcoap does not generate this response.

  1. NON Observe notification

A notification response to an Observe request may be non-confirmable. gcoap already handles this scenario.

a. NON -->
b. ... (time passes)
c. <-- NON
( d. RST --> )

(d) is possible per RFC 7641, but not supported currently.

  1. CON Observe notification

A notification response to an Observe request also may be confirmable. In fact, the server must send a confirmable notification at least once a day. Conceptually, a confirmable notification is like the separate response in scenario 2.

a. NON/CON -->
b. ... (time passes)
c. <-- CON
d. ACK/RST -->

A reset at (d) cancels further Observe notifications to the client.

  1. NON request, CON response (NOT supported)

Theoretically, the response to a non-confirmable request could be confirmable. I can't imagine this scenario though, because the request from the client at (a) is non-confirmable. If the client wanted to ensure it received a response, it would have sent the request confirmably.

a. NON -->
b. <-- CON
c. ACK/RST -->