1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

suit/transport/coap: move suit_coap_get_blockwise() to nanocoap

This commit is contained in:
Benjamin Valentin 2022-01-06 13:08:59 +01:00
parent 8c9f413b33
commit 2682848a29
8 changed files with 179 additions and 156 deletions

View File

@ -590,6 +590,7 @@ endif
ifneq (,$(filter nanocoap_sock,$(USEMODULE)))
USEMODULE += sock_udp
USEMODULE += sock_util
endif
ifneq (,$(filter nanocoap_%,$(USEMODULE)))

View File

@ -233,6 +233,19 @@ extern "C" {
#define COAP_BLOCKWISE_SZX_MAX (7)
/** @} */
/**
* @brief Coap block-wise-transfer size SZX
*/
typedef enum {
COAP_BLOCKSIZE_16 = 0,
COAP_BLOCKSIZE_32,
COAP_BLOCKSIZE_64,
COAP_BLOCKSIZE_128,
COAP_BLOCKSIZE_256,
COAP_BLOCKSIZE_512,
COAP_BLOCKSIZE_1024,
} coap_blksize_t;
#ifdef __cplusplus
}
#endif

View File

@ -225,6 +225,20 @@ typedef struct {
*/
typedef ssize_t (*coap_handler_t)(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context);
/**
* @brief Coap blockwise request callback descriptor
*
* @param[in] arg Pointer to be passed as arguments to the callback
* @param[in] offset Offset of received data
* @param[in] buf Pointer to the received data
* @param[in] len Length of the received data
* @param[in] more -1 for no option, 0 for last block, 1 for more blocks
*
* @returns 0 on success
* @returns -1 on error
*/
typedef int (*coap_blockwise_cb_t)(void *arg, size_t offset, uint8_t *buf, size_t len, int more);
/**
* @brief Method flag type
*

View File

@ -190,6 +190,49 @@ static inline void nanocoap_close(sock_udp_t *sock)
ssize_t nanocoap_get(sock_udp_t *sock, const char *path, void *buf,
size_t len);
/**
* @brief Performs a blockwise coap get request on a socket.
*
* This function will fetch the content of the specified resource path via
* block-wise-transfer. A coap_blockwise_cb_t will be called on each received
* block.
*
* @param[in] sock socket to use for the request
* @param[in] path pointer to source path
* @param[in] blksize sender suggested SZX for the COAP block request
* @param[in] work_buf Work buffer, must be `NANOCOAP_BLOCKWISE_BUF(blksize)` bytes
* @param[in] callback callback to be executed on each received block
* @param[in] arg optional function arguments
*
* @returns -EINVAL if an invalid url is provided
* @returns -1 if failed to fetch the url content
* @returns 0 on success
*/
int nanocoap_get_blockwise(sock_udp_t *sock, const char *path,
coap_blksize_t blksize, void *work_buf,
coap_blockwise_cb_t callback, void *arg);
/**
* @brief Performs a blockwise coap get request to the specified url.
*
* This function will fetch the content of the specified resource path via
* block-wise-transfer. A coap_blockwise_cb_t will be called on each received
* block.
*
* @param[in] url Absolute URL pointer to source path (i.e. not containing a fragment identifier)
* @param[in] blksize sender suggested SZX for the COAP block request
* @param[in] work_buf Work buffer, must be `NANOCOAP_BLOCKWISE_BUF(blksize)` bytes
* @param[in] callback callback to be executed on each received block
* @param[in] arg optional function arguments
*
* @returns -EINVAL if an invalid url is provided
* @returns -1 if failed to fetch the url content
* @returns 0 on success
*/
int nanocoap_get_blockwise_url(const char *url,
coap_blksize_t blksize, void *work_buf,
coap_blockwise_cb_t callback, void *arg);
/**
* @brief Simple synchronous CoAP request
*

View File

@ -90,37 +90,11 @@ typedef const struct {
const size_t resources_numof; /**< nr of entries in array */
} coap_resource_subtree_t;
/**
* @brief Coap blockwise request callback descriptor
*
* @param[in] arg Pointer to be passed as arguments to the callback
* @param[in] offset Offset of received data
* @param[in] buf Pointer to the received data
* @param[in] len Length of the received data
* @param[in] more -1 for no option, 0 for last block, 1 for more blocks
*
* @returns 0 on success
* @returns -1 on error
*/
typedef int (*coap_blockwise_cb_t)(void *arg, size_t offset, uint8_t *buf, size_t len, int more);
/**
* @brief Reference to the coap resource subtree
*/
extern const coap_resource_subtree_t coap_resource_subtree_suit;
/**
* @brief Coap block-wise-transfer size SZX
*/
typedef enum {
COAP_BLOCKSIZE_32 = 1,
COAP_BLOCKSIZE_64,
COAP_BLOCKSIZE_128,
COAP_BLOCKSIZE_256,
COAP_BLOCKSIZE_512,
COAP_BLOCKSIZE_1024,
} coap_blksize_t;
/**
* @brief Coap block-wise-transfer size used for SUIT
*/
@ -128,27 +102,6 @@ typedef enum {
#define CONFIG_SUIT_COAP_BLOCKSIZE COAP_BLOCKSIZE_64
#endif
/**
* @brief Performs a blockwise coap get request to the specified url.
*
* This function will fetch the content of the specified resource path via
* block-wise-transfer. A coap_blockwise_cb_t will be called on each received
* block.
*
* @param[in] url url pointer to source path
* @param[in] blksize sender suggested SZX for the COAP block request
* @param[in] work_buf Work buffer, must be NANOCOAP_BLOCKWISE_BUF(blksize) bytes
* @param[in] callback callback to be executed on each received block
* @param[in] arg optional function arguments
*
* @returns -EINVAL if an invalid url is provided
* @returns -1 if failed to fetch the url content
* @returns 0 on success
*/
int suit_coap_get_blockwise_url(const char *url,
coap_blksize_t blksize, void *work_buf,
coap_blockwise_cb_t callback, void *arg);
/**
* @brief Trigger a SUIT udate
*

View File

@ -25,6 +25,7 @@
#include <stdio.h>
#include "net/nanocoap_sock.h"
#include "net/sock/util.h"
#include "net/sock/udp.h"
#include "timex.h"
@ -140,6 +141,108 @@ ssize_t nanocoap_get(sock_udp_t *sock, const char *path, void *buf, size_t len)
return res;
}
static int _fetch_block(coap_pkt_t *pkt, uint8_t *buf, sock_udp_t *sock,
const char *path, coap_blksize_t blksize, size_t num)
{
uint8_t *pktpos = buf;
uint16_t lastonum = 0;
pkt->hdr = (coap_hdr_t *)buf;
pktpos += coap_build_hdr(pkt->hdr, COAP_TYPE_CON, NULL, 0, COAP_METHOD_GET,
num);
pktpos += coap_opt_put_uri_pathquery(pktpos, &lastonum, path);
pktpos += coap_opt_put_uint(pktpos, lastonum, COAP_OPT_BLOCK2,
(num << 4) | blksize);
pkt->payload = pktpos;
pkt->payload_len = 0;
int res = nanocoap_request(sock, pkt, NANOCOAP_BLOCKWISE_BUF(blksize));
if (res < 0) {
return res;
}
res = coap_get_code(pkt);
DEBUG("code=%i\n", res);
if (res != 205) {
return -res;
}
return 0;
}
int nanocoap_get_blockwise(sock_udp_t *sock, const char *path,
coap_blksize_t blksize, void *buf,
coap_blockwise_cb_t callback, void *arg)
{
coap_pkt_t pkt;
coap_block1_t block2;
size_t num = 0;
do {
DEBUG("fetching block %u\n", (unsigned)num);
int res = _fetch_block(&pkt, buf, sock, path, blksize, num);
if (res) {
DEBUG("error fetching block: %d\n", res);
return -1;
}
/* no block option in response - direcly use paylaod */
if (!coap_get_block2(&pkt, &block2)) {
block2.more = 0;
block2.offset = 0;
}
res = callback(arg, block2.offset, pkt.payload, pkt.payload_len,
block2.more);
if (res) {
DEBUG("callback %d != 0, aborting.\n", res);
return res;
}
num += 1;
} while (block2.more == 1);
return 0;
}
int nanocoap_get_blockwise_url(const char *url,
coap_blksize_t blksize, void *buf,
coap_blockwise_cb_t callback, void *arg)
{
char hostport[CONFIG_SOCK_HOSTPORT_MAXLEN];
char urlpath[CONFIG_SOCK_URLPATH_MAXLEN];
sock_udp_ep_t remote;
sock_udp_t sock;
int res;
if (strncmp(url, "coap://", 7)) {
DEBUG("nanocoap: URL doesn't start with \"coap://\"\n");
return -EINVAL;
}
if (sock_urlsplit(url, hostport, urlpath) < 0) {
DEBUG("nanocoap: invalid URL\n");
return -EINVAL;
}
if (sock_udp_str2ep(&remote, hostport) < 0) {
DEBUG("nanocoap: invalid URL\n");
return -EINVAL;
}
res = nanocoap_connect(&sock, NULL, &remote);
if (res) {
return res;
}
res = nanocoap_get_blockwise(&sock, urlpath, blksize, buf, callback, arg);
nanocoap_close(&sock);
return res;
}
int nanocoap_server(sock_udp_ep_t *local, uint8_t *buf, size_t bufsize)
{
sock_udp_t sock;

View File

@ -37,6 +37,7 @@
#ifdef MODULE_SUIT_TRANSPORT_COAP
#include "suit/transport/coap.h"
#include "net/nanocoap_sock.h"
#endif
#include "suit/transport/mock.h"
@ -359,9 +360,9 @@ static int _dtv_fetch(suit_manifest_t *manifest, int key,
#ifdef MODULE_SUIT_TRANSPORT_COAP
else if (strncmp(manifest->urlbuf, "coap://", 7) == 0) {
uint8_t buffer[NANOCOAP_BLOCKWISE_BUF(CONFIG_SUIT_COAP_BLOCKSIZE)];
res = suit_coap_get_blockwise_url(manifest->urlbuf, CONFIG_SUIT_COAP_BLOCKSIZE,
buffer, suit_storage_helper,
manifest);
res = nanocoap_get_blockwise_url(manifest->urlbuf, CONFIG_SUIT_COAP_BLOCKSIZE,
buffer, suit_storage_helper,
manifest);
}
#endif
#ifdef MODULE_SUIT_TRANSPORT_MOCK

View File

@ -133,111 +133,6 @@ static inline uint32_t deadline_left(uint32_t deadline)
return left;
}
static int _fetch_block(coap_pkt_t *pkt, uint8_t *buf, sock_udp_t *sock,
const char *path, coap_blksize_t blksize, size_t num)
{
uint8_t *pktpos = buf;
uint16_t lastonum = 0;
pkt->hdr = (coap_hdr_t *)buf;
pktpos += coap_build_hdr(pkt->hdr, COAP_TYPE_CON, NULL, 0, COAP_METHOD_GET,
num);
pktpos += coap_opt_put_uri_pathquery(pktpos, &lastonum, path);
pktpos += coap_opt_put_uint(pktpos, lastonum, COAP_OPT_BLOCK2,
(num << 4) | blksize);
pkt->payload = pktpos;
pkt->payload_len = 0;
int res = nanocoap_request(sock, pkt, NANOCOAP_BLOCKWISE_BUF(blksize));
if (res < 0) {
return res;
}
res = coap_get_code(pkt);
DEBUG("code=%i\n", res);
if (res != 205) {
return -res;
}
return 0;
}
int suit_coap_get_blockwise(sock_udp_t *sock, const char *path,
coap_blksize_t blksize, void *buf,
coap_blockwise_cb_t callback, void *arg)
{
coap_pkt_t pkt;
int res, more = 1;
size_t num = 0;
res = -1;
while (more == 1) {
DEBUG("fetching block %u\n", (unsigned)num);
res = _fetch_block(&pkt, buf, sock, path, blksize, num);
DEBUG("res=%i\n", res);
if (!res) {
coap_block1_t block2;
coap_get_block2(&pkt, &block2);
more = block2.more;
if (callback(arg, block2.offset, pkt.payload, pkt.payload_len,
more)) {
DEBUG("callback res != 0, aborting.\n");
res = -1;
goto out;
}
}
else {
DEBUG("error fetching block\n");
res = -1;
goto out;
}
num += 1;
}
out:
return res;
}
int suit_coap_get_blockwise_url(const char *url,
coap_blksize_t blksize, void *buf,
coap_blockwise_cb_t callback, void *arg)
{
char hostport[CONFIG_SOCK_HOSTPORT_MAXLEN];
char urlpath[CONFIG_SOCK_URLPATH_MAXLEN];
sock_udp_ep_t remote;
sock_udp_t sock;
int res;
if (strncmp(url, "coap://", 7)) {
LOG_INFO("suit: URL doesn't start with \"coap://\"\n");
return -EINVAL;
}
if (sock_urlsplit(url, hostport, urlpath) < 0) {
LOG_INFO("suit: invalid URL\n");
return -EINVAL;
}
if (sock_udp_str2ep(&remote, hostport) < 0) {
LOG_INFO("suit: invalid URL\n");
return -EINVAL;
}
res = nanocoap_connect(&sock, NULL, &remote);
if (res) {
return res;
}
res = suit_coap_get_blockwise(&sock, urlpath, blksize, buf, callback, arg);
nanocoap_close(&sock);
return res;
}
typedef struct {
size_t offset;
uint8_t *ptr;
@ -269,7 +164,7 @@ static ssize_t suit_coap_get_blockwise_url_buf(const char *url,
uint8_t *buf, size_t len)
{
_buf_t _buf = { .ptr = buf, .len = len };
int res = suit_coap_get_blockwise_url(url, blksize, work_buf, _2buf, &_buf);
int res = nanocoap_get_blockwise_url(url, blksize, work_buf, _2buf, &_buf);
return (res < 0) ? (ssize_t)res : (ssize_t)_buf.offset;
}