net: coap_client: allow application to add block2 option to requests
Allow an application to add a Block2 option to an initial request for a resource. For any subsequent requests as part of a blockwise transfer, drop the application-added Block2 option since the coap_client must append a Block2 option with updated NUM and SZX fields based on the server response. Signed-off-by: Matt Rodgers <mrodgers@witekio.com>
This commit is contained in:
parent
ed49d7c5e9
commit
47fbb8512f
3 changed files with 60 additions and 0 deletions
|
@ -79,6 +79,34 @@ The following is an example of a very simple response handling function:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoAP options may also be added to the request by the application. The following is an example of
|
||||||
|
the application adding a Block2 option to the initial request, to suggest a maximum block size to
|
||||||
|
the server for a resource that it expects to be large enough to require a blockwise transfer (see
|
||||||
|
RFC7959 Figure 3: Block-Wise GET with Early Negotiation).
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
static struct coap_client;
|
||||||
|
struct coap_client_request req = { 0 };
|
||||||
|
|
||||||
|
/* static, since options must remain valid throughout the whole execution of the request */
|
||||||
|
static struct coap_client_option block2_option;
|
||||||
|
|
||||||
|
coap_client_init(&client, NULL);
|
||||||
|
block2_option = coap_client_option_initial_block2();
|
||||||
|
|
||||||
|
req.method = COAP_METHOD_GET;
|
||||||
|
req.confirmable = true;
|
||||||
|
req.path = "test";
|
||||||
|
req.fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN;
|
||||||
|
req.cb = response_cb;
|
||||||
|
req.options = &block2_option;
|
||||||
|
req.num_options = 1;
|
||||||
|
req.payload = NULL;
|
||||||
|
req.len = 0;
|
||||||
|
|
||||||
|
ret = coap_client_req(&client, sock, &address, &req, -1);
|
||||||
|
|
||||||
API Reference
|
API Reference
|
||||||
*************
|
*************
|
||||||
|
|
||||||
|
|
|
@ -159,6 +159,28 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr
|
||||||
*/
|
*/
|
||||||
void coap_client_cancel_requests(struct coap_client *client);
|
void coap_client_cancel_requests(struct coap_client *client);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialise a Block2 option to be added to a request
|
||||||
|
*
|
||||||
|
* If the application expects a request to require a blockwise transfer, it may pre-emptively
|
||||||
|
* suggest a maximum block size to the server - see RFC7959 Figure 3: Block-Wise GET with Early
|
||||||
|
* Negotiation.
|
||||||
|
*
|
||||||
|
* This helper function returns a Block2 option to send with the initial request.
|
||||||
|
*
|
||||||
|
* @return CoAP client initial Block2 option structure
|
||||||
|
*/
|
||||||
|
static inline struct coap_client_option coap_client_option_initial_block2(void)
|
||||||
|
{
|
||||||
|
struct coap_client_option block2 = {
|
||||||
|
.code = COAP_OPTION_BLOCK2,
|
||||||
|
.len = 1,
|
||||||
|
.value[0] = coap_bytes_to_block_size(CONFIG_COAP_CLIENT_BLOCK_SIZE),
|
||||||
|
};
|
||||||
|
|
||||||
|
return block2;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -148,6 +148,7 @@ static int coap_client_init_request(struct coap_client *client,
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int i;
|
int i;
|
||||||
|
bool block2 = false;
|
||||||
|
|
||||||
memset(client->send_buf, 0, sizeof(client->send_buf));
|
memset(client->send_buf, 0, sizeof(client->send_buf));
|
||||||
|
|
||||||
|
@ -189,6 +190,7 @@ static int coap_client_init_request(struct coap_client *client,
|
||||||
|
|
||||||
/* Blockwise receive ongoing, request next block. */
|
/* Blockwise receive ongoing, request next block. */
|
||||||
if (internal_req->recv_blk_ctx.current > 0) {
|
if (internal_req->recv_blk_ctx.current > 0) {
|
||||||
|
block2 = true;
|
||||||
ret = coap_append_block2_option(&internal_req->request,
|
ret = coap_append_block2_option(&internal_req->request,
|
||||||
&internal_req->recv_blk_ctx);
|
&internal_req->recv_blk_ctx);
|
||||||
|
|
||||||
|
@ -200,6 +202,14 @@ static int coap_client_init_request(struct coap_client *client,
|
||||||
|
|
||||||
/* Add extra options if any */
|
/* Add extra options if any */
|
||||||
for (i = 0; i < req->num_options; i++) {
|
for (i = 0; i < req->num_options; i++) {
|
||||||
|
if (COAP_OPTION_BLOCK2 == req->options[i].code && block2) {
|
||||||
|
/* After the first request, ignore any block2 option added by the
|
||||||
|
* application, since NUM (and possibly SZX) must be updated based on the
|
||||||
|
* server response.
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ret = coap_packet_append_option(&internal_req->request, req->options[i].code,
|
ret = coap_packet_append_option(&internal_req->request, req->options[i].code,
|
||||||
req->options[i].value, req->options[i].len);
|
req->options[i].value, req->options[i].len);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue