Skip to content

Commit 6d18cf2

Browse files
committed
[nrf fromtree] net: lib: coap_client: Release non-confirmable requests
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)
1 parent 401a47a commit 6d18cf2

File tree

1 file changed

+35
-18
lines changed

1 file changed

+35
-18
lines changed

subsys/net/lib/coap/coap_client.c

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ static bool exchange_lifetime_exceeded(struct coap_client_internal_request *inte
105105
return true;
106106
}
107107

108+
if (internal_req->pending.t0 == 0) {
109+
return true;
110+
}
111+
108112
time_since_t0 = k_uptime_get() - internal_req->pending.t0;
109113
exchange_lifetime =
110114
(internal_req->pending.params.ack_timeout * COAP_EXCHANGE_LIFETIME_FACTOR);
@@ -364,7 +368,7 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr
364368
/* Don't allow changing to a different socket if there is already request ongoing. */
365369
if (client->fd != sock && has_ongoing_request(client)) {
366370
ret = -EALREADY;
367-
goto out;
371+
goto release;
368372
}
369373

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

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

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

403407
if (client->send_echo) {
404408
ret = coap_packet_append_option(&internal_req->request, COAP_OPTION_ECHO,
405409
client->echo_option.value, client->echo_option.len);
406410
if (ret < 0) {
407411
LOG_ERR("Failed to append echo option");
408-
goto out;
412+
goto release;
409413
}
410414
client->send_echo = false;
411415
}
412416

413417
ret = coap_client_schedule_poll(client, sock, req, internal_req);
414418
if (ret < 0) {
415419
LOG_ERR("Failed to schedule polling");
416-
goto out;
420+
goto release;
417421
}
418422

419-
/* only TYPE_CON messages need pending tracking */
420-
if (coap_header_get_type(&internal_req->request) == COAP_TYPE_CON) {
421-
ret = coap_pending_init(&internal_req->pending, &internal_req->request,
422-
&client->address, params);
423+
ret = coap_pending_init(&internal_req->pending, &internal_req->request,
424+
&client->address, params);
423425

424-
if (ret < 0) {
425-
LOG_ERR("Failed to initialize pending struct");
426-
goto out;
427-
}
426+
if (ret < 0) {
427+
LOG_ERR("Failed to initialize pending struct");
428+
goto release;
429+
}
428430

429-
coap_pending_cycle(&internal_req->pending);
430-
internal_req->is_observe = coap_request_is_observe(&internal_req->request);
431-
LOG_DBG("Request is_observe %d", internal_req->is_observe);
431+
/* Non-Confirmable messages are not retried, but we still track the lifetime as
432+
* replies are acceptable.
433+
*/
434+
if (coap_header_get_type(&internal_req->request) == COAP_TYPE_NON_CON) {
435+
internal_req->pending.retries = 0;
432436
}
437+
coap_pending_cycle(&internal_req->pending);
438+
internal_req->is_observe = coap_request_is_observe(&internal_req->request);
439+
LOG_DBG("Request is_observe %d", internal_req->is_observe);
433440

434441
ret = send_request(sock, internal_req->request.data, internal_req->request.offset, 0,
435442
&client->address, client->socklen);
436443
if (ret < 0) {
437-
LOG_ERR("Transmission failed: %d", errno);
444+
ret = -errno;
445+
}
446+
447+
release:
448+
if (ret < 0) {
449+
LOG_ERR("Failed to send request: %d", ret);
438450
reset_internal_request(internal_req);
439451
} else {
440452
/* Do not return the number of bytes sent */
@@ -521,6 +533,11 @@ static void coap_client_resend_handler(struct coap_client *client)
521533

522534
for (int i = 0; i < CONFIG_COAP_CLIENT_MAX_REQUESTS; i++) {
523535
if (timeout_expired(&client->requests[i])) {
536+
if (!client->requests[i].coap_request.confirmable) {
537+
release_internal_request(&client->requests[i]);
538+
continue;
539+
}
540+
524541
ret = resend_request(client, &client->requests[i]);
525542
if (ret < 0) {
526543
report_callback_error(&client->requests[i], ret);

0 commit comments

Comments
 (0)