mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-24 22:13:52 +01:00
nanocoap_sock: add nanocoap_sock_block_request()
This commit is contained in:
parent
f2279e43ae
commit
b99d4b58bd
@ -134,6 +134,7 @@
|
||||
|
||||
#include "net/nanocoap.h"
|
||||
#include "net/sock/udp.h"
|
||||
#include "net/sock/util.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -145,6 +146,17 @@ extern "C" {
|
||||
*/
|
||||
typedef sock_udp_t nanocoap_sock_t;
|
||||
|
||||
/**
|
||||
* @brief Blockwise request helper struct
|
||||
*/
|
||||
typedef struct {
|
||||
nanocoap_sock_t sock; /**< socket used for the request */
|
||||
const char *path; /**< path on the server */
|
||||
uint32_t blknum; /**< current block number */
|
||||
uint8_t method; /**< request method (GET, POST, PUT) */
|
||||
uint8_t blksize; /**< CoAP blocksize exponent */
|
||||
} coap_block_request_t;
|
||||
|
||||
/**
|
||||
* @brief Start a nanocoap server instance
|
||||
*
|
||||
@ -332,6 +344,87 @@ ssize_t nanocoap_request(coap_pkt_t *pkt, sock_udp_ep_t *local,
|
||||
ssize_t nanocoap_get(sock_udp_ep_t *remote, const char *path, void *buf,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* @brief Initialize block request context
|
||||
*
|
||||
* @param[out] ctx The block request context to initialize
|
||||
* @param[in] remote Server endpoint
|
||||
* @param[in] path Server path for request
|
||||
* @param[in] method Request method (`COAP_METHOD_{GET|PUT|POST}`)
|
||||
* @param[in] blksize Request blocksize exponent
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval <0 Error (see @ref nanocoap_sock_connect for details)
|
||||
*/
|
||||
static inline int nanocoap_block_request_init(coap_block_request_t *ctx,
|
||||
sock_udp_ep_t *remote,
|
||||
const char *path,
|
||||
uint8_t method,
|
||||
coap_blksize_t blksize)
|
||||
{
|
||||
ctx->path = path;
|
||||
ctx->blknum = 0;
|
||||
ctx->method = method;
|
||||
ctx->blksize = blksize;
|
||||
return nanocoap_sock_connect(&ctx->sock, NULL, remote);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize block request context by URL
|
||||
*
|
||||
* @param[out] ctx The block request context to initialize
|
||||
* @param[in] url The request URL
|
||||
* @param[in] method Request method (`COAP_METHOD_{GET|PUT|POST}`)
|
||||
* @param[in] blksize Request blocksize exponent
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval <0 Error (see @ref nanocoap_sock_url_connect for details)
|
||||
*/
|
||||
static inline int nanocoap_block_request_init_url(coap_block_request_t *ctx,
|
||||
const char *url,
|
||||
uint8_t method,
|
||||
coap_blksize_t blksize)
|
||||
{
|
||||
ctx->path = sock_urlpath(url);
|
||||
ctx->blknum = 0;
|
||||
ctx->method = method;
|
||||
ctx->blksize = blksize;
|
||||
return nanocoap_sock_url_connect(url, &ctx->sock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free block request context
|
||||
*
|
||||
* @param[out] ctx The block request context to finalize
|
||||
*/
|
||||
static inline void nanocoap_block_request_done(coap_block_request_t *ctx)
|
||||
{
|
||||
nanocoap_sock_close(&ctx->sock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Do a block-wise request, send a single block.
|
||||
*
|
||||
* This method is expected to be called in a loop until all
|
||||
* payload blocks have been transferred.
|
||||
*
|
||||
* @pre @p ctx was initialized with @ref nanocoap_block_request_init or
|
||||
* @ref nanocoap_block_request_init_url
|
||||
*
|
||||
* @param[in] ctx blockwise request context
|
||||
* @param[in] data payload to send
|
||||
* @param[in] len payload length
|
||||
* @param[in] more more blocks after this one
|
||||
* (will be set automatically if @p len > block size)
|
||||
* @param[in] cb callback for response
|
||||
* @param[in] arg callback context
|
||||
*
|
||||
* @return Number of payload bytes written on success
|
||||
* Negative error on failure
|
||||
*/
|
||||
int nanocoap_sock_block_request(coap_block_request_t *ctx,
|
||||
const void *data, size_t len, bool more,
|
||||
coap_request_cb_t cb, void *arg);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -392,6 +392,52 @@ static int _fetch_block(nanocoap_sock_t *sock, uint8_t *buf, size_t len,
|
||||
return nanocoap_sock_request_cb(sock, &pkt, _block_cb, ctx);
|
||||
}
|
||||
|
||||
int nanocoap_sock_block_request(coap_block_request_t *req,
|
||||
const void *data, size_t len, bool more,
|
||||
coap_request_cb_t callback, void *arg)
|
||||
{
|
||||
/* clip the payload at the block size */
|
||||
if (len > coap_szx2size(req->blksize)) {
|
||||
len = coap_szx2size(req->blksize);
|
||||
more = true;
|
||||
}
|
||||
|
||||
int res;
|
||||
uint8_t buf[CONFIG_NANOCOAP_BLOCK_HEADER_MAX];
|
||||
iolist_t snip = {
|
||||
.iol_base = (void *)data,
|
||||
.iol_len = len,
|
||||
};
|
||||
|
||||
coap_pkt_t pkt = {
|
||||
.hdr = (void *)buf,
|
||||
.snips = &snip,
|
||||
};
|
||||
|
||||
uint8_t *pktpos = (void *)pkt.hdr;
|
||||
uint16_t lastonum = 0;
|
||||
|
||||
pktpos += coap_build_hdr(pkt.hdr, COAP_TYPE_CON, NULL, 0, req->method, _get_id());
|
||||
pktpos += coap_opt_put_uri_pathquery(pktpos, &lastonum, req->path);
|
||||
pktpos += coap_opt_put_uint(pktpos, lastonum, COAP_OPT_BLOCK1,
|
||||
(req->blknum << 4) | req->blksize | (more ? 0x8 : 0));
|
||||
if (len) {
|
||||
/* set payload marker */
|
||||
*pktpos++ = 0xFF;
|
||||
}
|
||||
|
||||
pkt.payload = pktpos;
|
||||
pkt.payload_len = 0;
|
||||
|
||||
res = nanocoap_sock_request_cb(&req->sock, &pkt, callback, arg);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
++req->blknum;
|
||||
return len;
|
||||
}
|
||||
|
||||
int nanocoap_sock_get_blockwise(nanocoap_sock_t *sock, const char *path,
|
||||
coap_blksize_t blksize,
|
||||
coap_blockwise_cb_t callback, void *arg)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user