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:
parent
8c9f413b33
commit
2682848a29
@ -590,6 +590,7 @@ endif
|
||||
|
||||
ifneq (,$(filter nanocoap_sock,$(USEMODULE)))
|
||||
USEMODULE += sock_udp
|
||||
USEMODULE += sock_util
|
||||
endif
|
||||
|
||||
ifneq (,$(filter nanocoap_%,$(USEMODULE)))
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user