Skip to content

Commit

Permalink
[nrf fromtree] net: lib: coap_client: Release non-confirmable requests
Browse files Browse the repository at this point in the history
Non-confirmable CoAP requests need lifetime tracking as well
so we can free the structure after a timeout.

Signed-off-by: Seppo Takalo <[email protected]>
(cherry picked from commit 2066cf6)
  • Loading branch information
SeppoTakalo committed Nov 28, 2024
1 parent 83b90e7 commit f6004fc
Showing 1 changed file with 35 additions and 18 deletions.
53 changes: 35 additions & 18 deletions subsys/net/lib/coap/coap_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ static bool exchange_lifetime_exceeded(struct coap_client_internal_request *inte
return true;
}

if (internal_req->pending.t0 == 0) {
return true;
}

time_since_t0 = k_uptime_get() - internal_req->pending.t0;
exchange_lifetime =
(internal_req->pending.params.ack_timeout * COAP_EXCHANGE_LIFETIME_FACTOR);
Expand Down Expand Up @@ -364,7 +368,7 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr
/* Don't allow changing to a different socket if there is already request ongoing. */
if (client->fd != sock && has_ongoing_request(client)) {
ret = -EALREADY;
goto out;
goto release;
}

/* Don't allow changing to a different address if there is already request ongoing. */
Expand All @@ -373,7 +377,7 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr
if (has_ongoing_request(client)) {
LOG_WRN("Can't change to a different socket, request ongoing.");
ret = -EALREADY;
goto out;
goto release;
}

memcpy(&client->address, addr, sizeof(*addr));
Expand All @@ -384,7 +388,7 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr
if (has_ongoing_request(client)) {
LOG_WRN("Can't change to a different socket, request ongoing.");
ret = -EALREADY;
goto out;
goto release;
}

memset(&client->address, 0, sizeof(client->address));
Expand All @@ -397,44 +401,52 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr
ret = coap_client_init_request(client, req, internal_req, false);
if (ret < 0) {
LOG_ERR("Failed to initialize coap request");
goto out;
goto release;
}

if (client->send_echo) {
ret = coap_packet_append_option(&internal_req->request, COAP_OPTION_ECHO,
client->echo_option.value, client->echo_option.len);
if (ret < 0) {
LOG_ERR("Failed to append echo option");
goto out;
goto release;
}
client->send_echo = false;
}

ret = coap_client_schedule_poll(client, sock, req, internal_req);
if (ret < 0) {
LOG_ERR("Failed to schedule polling");
goto out;
goto release;
}

/* only TYPE_CON messages need pending tracking */
if (coap_header_get_type(&internal_req->request) == COAP_TYPE_CON) {
ret = coap_pending_init(&internal_req->pending, &internal_req->request,
&client->address, params);
ret = coap_pending_init(&internal_req->pending, &internal_req->request,
&client->address, params);

if (ret < 0) {
LOG_ERR("Failed to initialize pending struct");
goto out;
}
if (ret < 0) {
LOG_ERR("Failed to initialize pending struct");
goto release;
}

coap_pending_cycle(&internal_req->pending);
internal_req->is_observe = coap_request_is_observe(&internal_req->request);
LOG_DBG("Request is_observe %d", internal_req->is_observe);
/* Non-Confirmable messages are not retried, but we still track the lifetime as
* replies are acceptable.
*/
if (coap_header_get_type(&internal_req->request) == COAP_TYPE_NON_CON) {
internal_req->pending.retries = 0;
}
coap_pending_cycle(&internal_req->pending);
internal_req->is_observe = coap_request_is_observe(&internal_req->request);
LOG_DBG("Request is_observe %d", internal_req->is_observe);

ret = send_request(sock, internal_req->request.data, internal_req->request.offset, 0,
&client->address, client->socklen);
if (ret < 0) {
LOG_ERR("Transmission failed: %d", errno);
ret = -errno;
}

release:
if (ret < 0) {
LOG_ERR("Failed to send request: %d", ret);
reset_internal_request(internal_req);
} else {
/* Do not return the number of bytes sent */
Expand Down Expand Up @@ -521,6 +533,11 @@ static void coap_client_resend_handler(struct coap_client *client)

for (int i = 0; i < CONFIG_COAP_CLIENT_MAX_REQUESTS; i++) {
if (timeout_expired(&client->requests[i])) {
if (!client->requests[i].coap_request.confirmable) {
release_internal_request(&client->requests[i]);
continue;
}

ret = resend_request(client, &client->requests[i]);
if (ret < 0) {
report_callback_error(&client->requests[i], ret);
Expand Down

0 comments on commit f6004fc

Please sign in to comment.