net: coap_client: Move send buffer into request context
Keep a separate buffer for each request context instead of having a single common buffer for the entire client context. This allows to simplify the retransmission logic, as parallel requests will no longer overwrite the buffer for each other. That way, we can simply retransmit the packet w/o a need to recreate it, and thus reach to the payload pointer or callback. This removes the requirement to keep the payload pointer, provided to asynchronous coap_client_req() call, valid throughout the exchange lifetime for simple cases (i.e. no block transfer used). In case of block transfer, this is unavoidable and needs to be documented. Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
committed by
Johan Hedberg
parent
c5c51f23d8
commit
75ef63921d
@@ -74,7 +74,7 @@ typedef void (*coap_client_response_cb_t)(const struct coap_client_response_data
|
||||
*
|
||||
* An optional callback for providing a payload for CoAP client requests. If set in
|
||||
* @ref coap_client_request, the CoAP client library will call this callback when
|
||||
* preparing a PUT/POST request (note that this is also true for retransmissions).
|
||||
* preparing a PUT/POST request.
|
||||
*
|
||||
* When called, the library provides the application with the current payload offset
|
||||
* for the transfer and the payload block size. In return, the application sets the
|
||||
@@ -155,6 +155,7 @@ struct coap_client_internal_request {
|
||||
struct coap_client_request coap_request;
|
||||
struct coap_packet request;
|
||||
uint8_t request_tag[COAP_TOKEN_MAX_LEN];
|
||||
uint8_t send_buf[MAX_COAP_MSG_LEN];
|
||||
|
||||
/* For GETs with observe option set */
|
||||
bool is_observe;
|
||||
@@ -166,7 +167,6 @@ struct coap_client {
|
||||
struct sockaddr address;
|
||||
socklen_t socklen;
|
||||
struct k_mutex lock;
|
||||
uint8_t send_buf[MAX_COAP_MSG_LEN];
|
||||
uint8_t recv_buf[MAX_COAP_MSG_LEN];
|
||||
struct coap_client_internal_request requests[CONFIG_COAP_CLIENT_MAX_REQUESTS];
|
||||
struct coap_option echo_option;
|
||||
@@ -194,6 +194,10 @@ int coap_client_init(struct coap_client *client, const char *info);
|
||||
* Once the callback is called with last block set as true, socket can be closed or
|
||||
* used for another query.
|
||||
*
|
||||
* @note If block transfer is used, the @p payload pointer provided in @p req parameter has to
|
||||
* remain valid throughout the transaction (i.e. until the last block or an error is reported).
|
||||
* The library will need to access the payload pointer when sending consecutive payload blocks.
|
||||
*
|
||||
* @param client Client instance.
|
||||
* @param sock Open socket file descriptor.
|
||||
* @param addr the destination address of the request, NULL if socket is already connected.
|
||||
|
||||
@@ -206,7 +206,7 @@ static int coap_client_init_request(struct coap_client *client,
|
||||
int i;
|
||||
bool block2 = false;
|
||||
|
||||
memset(client->send_buf, 0, sizeof(client->send_buf));
|
||||
memset(internal_req->send_buf, 0, sizeof(internal_req->send_buf));
|
||||
|
||||
if (!reconstruct) {
|
||||
uint8_t *token = coap_next_token();
|
||||
@@ -216,7 +216,7 @@ static int coap_client_init_request(struct coap_client *client,
|
||||
memcpy(internal_req->request_token, token, internal_req->request_tkl);
|
||||
}
|
||||
|
||||
ret = coap_packet_init(&internal_req->request, client->send_buf, MAX_COAP_MSG_LEN,
|
||||
ret = coap_packet_init(&internal_req->request, internal_req->send_buf, MAX_COAP_MSG_LEN,
|
||||
1, req->confirmable ? COAP_TYPE_CON : COAP_TYPE_NON_CON,
|
||||
COAP_TOKEN_MAX_LEN, internal_req->request_token, req->method,
|
||||
internal_req->last_id);
|
||||
@@ -569,17 +569,6 @@ static int resend_request(struct coap_client *client,
|
||||
coap_pending_cycle(&internal_req->pending)) {
|
||||
LOG_ERR("Timeout, retrying send");
|
||||
|
||||
/* Reset send block context as it was updated in previous init from packet */
|
||||
if (internal_req->send_blk_ctx.total_size > 0) {
|
||||
internal_req->send_blk_ctx.current = internal_req->offset;
|
||||
}
|
||||
ret = coap_client_init_request(client, &internal_req->coap_request,
|
||||
internal_req, true);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Error re-creating CoAP request %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = send_request(client->fd, internal_req->request.data,
|
||||
internal_req->request.offset, 0, &client->address,
|
||||
client->socklen);
|
||||
@@ -759,8 +748,9 @@ static int send_ack(struct coap_client *client, const struct coap_packet *req,
|
||||
{
|
||||
int ret;
|
||||
struct coap_packet ack;
|
||||
uint8_t ack_buf[COAP_FIXED_HEADER_SIZE + COAP_TOKEN_MAX_LEN];
|
||||
|
||||
ret = coap_ack_init(&ack, req, client->send_buf, MAX_COAP_MSG_LEN, response_code);
|
||||
ret = coap_ack_init(&ack, req, ack_buf, sizeof(ack_buf), response_code);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to initialize CoAP ACK-message");
|
||||
return ret;
|
||||
@@ -779,8 +769,9 @@ static int send_rst(struct coap_client *client, const struct coap_packet *req)
|
||||
{
|
||||
int ret;
|
||||
struct coap_packet rst;
|
||||
uint8_t rst_buf[COAP_FIXED_HEADER_SIZE + COAP_TOKEN_MAX_LEN];
|
||||
|
||||
ret = coap_rst_init(&rst, req, client->send_buf, MAX_COAP_MSG_LEN);
|
||||
ret = coap_rst_init(&rst, req, rst_buf, sizeof(rst_buf));
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to initialize CoAP RST-message");
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user