Merge pull request #8920 from haukepetersen/add_nanocaop_urilocationoption

net/nanocoap: add generic handling for string-based options
This commit is contained in:
Koen Zandberg 2018-08-31 12:04:32 +02:00 committed by GitHub
commit e8dfabd4c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 219 additions and 42 deletions

View File

@ -1,5 +1,6 @@
/* /*
* Copyright (C) 2016-17 Kaspar Schleiser <kaspar@schleiser.de> * Copyright (C) 2016-17 Kaspar Schleiser <kaspar@schleiser.de>
* 2018 Freie Universität Berlin
* *
* This file is subject to the terms and conditions of the GNU Lesser * This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level * General Public License v2.1. See the file LICENSE in the top level
@ -18,6 +19,7 @@
* *
* @author Kaspar Schleiser <kaspar@schleiser.de> * @author Kaspar Schleiser <kaspar@schleiser.de>
* @author Ken Bannister <kb2ma@runbox.com> * @author Ken Bannister <kb2ma@runbox.com>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/ */
#ifndef NET_NANOCOAP_H #ifndef NET_NANOCOAP_H
@ -63,9 +65,11 @@ extern "C" {
*/ */
#define COAP_OPT_URI_HOST (3) #define COAP_OPT_URI_HOST (3)
#define COAP_OPT_OBSERVE (6) #define COAP_OPT_OBSERVE (6)
#define COAP_OPT_LOCATION_PATH (8)
#define COAP_OPT_URI_PATH (11) #define COAP_OPT_URI_PATH (11)
#define COAP_OPT_CONTENT_FORMAT (12) #define COAP_OPT_CONTENT_FORMAT (12)
#define COAP_OPT_URI_QUERY (15) #define COAP_OPT_URI_QUERY (15)
#define COAP_OPT_LOCATION_QUERY (20)
#define COAP_OPT_BLOCK2 (23) #define COAP_OPT_BLOCK2 (23)
#define COAP_OPT_BLOCK1 (27) #define COAP_OPT_BLOCK1 (27)
/** @} */ /** @} */
@ -450,17 +454,87 @@ size_t coap_put_option(uint8_t *buf, uint16_t lastonum, uint16_t onum, uint8_t *
size_t coap_put_option_ct(uint8_t *buf, uint16_t lastonum, uint16_t content_type); size_t coap_put_option_ct(uint8_t *buf, uint16_t lastonum, uint16_t content_type);
/** /**
* @brief Insert URI encoded option into buffer * @brief Encode the given string as multi-part option into buffer
*
* @param[out] buf buffer to write to
* @param[in] lastonum number of previous option (for delta calculation),
* or 0 if first option
* @param[in] optnum option number to use
* @param[in] string string to encode as option
* @param[in] separator character used in @p string to separate parts
*
* @return number of bytes written to @p buf
*/
size_t coap_opt_put_string(uint8_t *buf, uint16_t lastonum, uint16_t optnum,
const char *string, char separator);
/**
* @brief Convenience function for inserting URI_PATH option into buffer
* *
* @param[out] buf buffer to write to * @param[out] buf buffer to write to
* @param[in] lastonum number of previous option (for delta calculation), * @param[in] lastonum number of previous option (for delta calculation),
* or 0 if first option * or 0 if first option
* @param[in] uri ptr to source URI * @param[in] uri ptr to source URI
* @param[in] optnum option number to use (e.g., COAP_OPT_URI_PATH)
* *
* @returns amount of bytes written to @p buf * @returns amount of bytes written to @p buf
*/ */
size_t coap_put_option_uri(uint8_t *buf, uint16_t lastonum, const char *uri, uint16_t optnum); static inline size_t coap_opt_put_uri_path(uint8_t *buf, uint16_t lastonum,
const char *uri)
{
return coap_opt_put_string(buf, lastonum, COAP_OPT_URI_PATH, uri, '/');
}
/**
* @brief Convenience function for inserting URI_QUERY option into buffer
*
* @param[out] buf buffer to write to
* @param[in] lastonum number of previous option (for delta calculation),
* or 0 if first option
* @param[in] uri ptr to source URI
*
* @returns amount of bytes written to @p buf
*/
static inline size_t coap_opt_put_uri_query(uint8_t *buf, uint16_t lastonum,
const char *uri)
{
return coap_opt_put_string(buf, lastonum, COAP_OPT_URI_QUERY, uri, '&');
}
/**
* @brief Convenience function for inserting LOCATION_PATH option into buffer
*
* @param[out] buf buffer to write to
* @param[in] lastonum number of previous option (for delta calculation),
* or 0 if first option
* @param[in] location ptr to string holding the location
*
* @returns amount of bytes written to @p buf
*/
static inline size_t coap_opt_put_location_path(uint8_t *buf,
uint16_t lastonum,
const char *location)
{
return coap_opt_put_string(buf, lastonum, COAP_OPT_LOCATION_PATH,
location, '/');
}
/**
* @brief Convenience function for inserting LOCATION_QUERY option into buffer
*
* @param[out] buf buffer to write to
* @param[in] lastonum number of previous option (for delta calculation),
* or 0 if first option
* @param[in] location ptr to string holding the location
*
* @returns amount of bytes written to @p buf
*/
static inline size_t coap_opt_put_location_query(uint8_t *buf,
uint16_t lastonum,
const char *location)
{
return coap_opt_put_string(buf, lastonum, COAP_OPT_LOCATION_QUERY,
location, '&');
}
/** /**
* @brief Generic block option getter * @brief Generic block option getter
@ -585,10 +659,30 @@ ssize_t coap_opt_finish(coap_pkt_t *pkt, uint16_t flags);
unsigned coap_get_content_type(coap_pkt_t *pkt); unsigned coap_get_content_type(coap_pkt_t *pkt);
/** /**
* @brief Get the packet's request URI * @brief Read a full option as null terminated string into the target buffer
* *
* This function decodes the pkt's URI option into a "/"-seperated and * This function is for reading and concatenating string based, multi-part CoAP
* NULL-terminated string. * options like COAP_OPT_URI_PATH or COAP_OPT_LOCATION_PATH. It will write all
* parts of the given option into the target buffer, separating the parts using
* the given @p separator. The resulting string is `\0` terminated.
*
* @param[in] pkt packet to read from
* @param[in] optnum absolute option number
* @param[out] target target buffer
* @param[in] max_len size of @p target
* @param[in] separator character used for separating the option parts
*
* @return -ENOSPC if the complete option does not fit into @p target
* @return nr of bytes written to @p target (including '\0')
*/
ssize_t coap_opt_get_string(const coap_pkt_t *pkt, uint16_t optnum,
uint8_t *target, size_t max_len, char separator);
/**
* @brief Convenience function for getting the packet's URI_PATH
*
* This function decodes the pkt's URI option into a "/"-separated and
* '\0'-terminated string.
* *
* Caller must ensure @p target can hold at least NANOCOAP_URI_MAX bytes! * Caller must ensure @p target can hold at least NANOCOAP_URI_MAX bytes!
* *
@ -598,10 +692,78 @@ unsigned coap_get_content_type(coap_pkt_t *pkt);
* @returns -ENOSPC if URI option is larger than NANOCOAP_URI_MAX * @returns -ENOSPC if URI option is larger than NANOCOAP_URI_MAX
* @returns nr of bytes written to @p target (including '\0') * @returns nr of bytes written to @p target (including '\0')
*/ */
int coap_get_uri(coap_pkt_t *pkt, uint8_t *target); static inline ssize_t coap_get_uri_path(const coap_pkt_t *pkt, uint8_t *target)
{
return coap_opt_get_string(pkt, COAP_OPT_URI_PATH, target,
NANOCOAP_URI_MAX, '/');
}
/** /**
* @brief Helper to decode SZX value to size in bytes * @brief Convenience function for getting the packet's URI_QUERY option
*
* This function decodes the pkt's URI_QUERY option into a "&"-separated and
* '\0'-terminated string.
*
* Caller must ensure @p target can hold at least NANOCOAP_URI_MAX bytes!
*
* @param[in] pkt pkt to work on
* @param[out] target buffer for target URI
*
* @returns -ENOSPC if URI option is larger than NANOCOAP_URI_MAX
* @returns nr of bytes written to @p target (including '\0')
*/
static inline ssize_t coap_get_uri_query(const coap_pkt_t *pkt, uint8_t *target)
{
return coap_opt_get_string(pkt, COAP_OPT_URI_QUERY, target,
NANOCOAP_URI_MAX, '&');
}
/**
* @brief Convenience function for getting the packet's LOCATION_PATH option
*
* This function decodes the pkt's LOCATION_PATH option into a '/'-separated and
* '\0'-terminated string.
*
* Caller must ensure @p target can hold at least 2 bytes!
*
* @param[in] pkt pkt to work on
* @param[out] target buffer for location path
* @param[in] max_len size of @p target in bytes
*
* @returns -ENOSPC if URI option is larger than @p max_len
* @returns nr of bytes written to @p target (including '\0')
*/
static inline ssize_t coap_get_location_path(const coap_pkt_t *pkt,
uint8_t *target, size_t max_len)
{
return coap_opt_get_string(pkt, COAP_OPT_LOCATION_PATH,
target, max_len, '/');
}
/**
* @brief Convenience function for getting the packet's LOCATION_QUERY option
*
* This function decodes the pkt's LOCATION_PATH option into a '&'-separated and
* '\0'-terminated string.
*
* Caller must ensure @p target can hold at least 2 bytes!
*
* @param[in] pkt pkt to work on
* @param[out] target buffer for location path
* @param[in] max_len size of @p target in bytes
*
* @returns -ENOSPC if URI option is larger than @p max_len
* @returns nr of bytes written to @p target (including '\0')
*/
static inline ssize_t coap_get_location_query(const coap_pkt_t *pkt,
uint8_t *target, size_t max_len)
{
return coap_opt_get_string(pkt, COAP_OPT_LOCATION_QUERY,
target, max_len, '&');
}
/**
* @brief Helper to decode SZX value to size in bytes
* *
* @param[in] szx SZX value to decode * @param[in] szx SZX value to decode
* *

View File

@ -564,8 +564,8 @@ static ssize_t _write_options(coap_pkt_t *pdu, uint8_t *buf, size_t len)
DEBUG("gcoap: _write_options: path does not start with '/'\n"); DEBUG("gcoap: _write_options: path does not start with '/'\n");
return -EINVAL; return -EINVAL;
} }
bufpos += coap_put_option_uri(bufpos, last_optnum, (char *)pdu->url, bufpos += coap_opt_put_uri_path(bufpos, last_optnum,
COAP_OPT_URI_PATH); (char *)pdu->url);
last_optnum = COAP_OPT_URI_PATH; last_optnum = COAP_OPT_URI_PATH;
} }
} }
@ -578,8 +578,8 @@ static ssize_t _write_options(coap_pkt_t *pdu, uint8_t *buf, size_t len)
/* Uri-query for requests */ /* Uri-query for requests */
if (coap_get_code_class(pdu) == COAP_CLASS_REQ) { if (coap_get_code_class(pdu) == COAP_CLASS_REQ) {
bufpos += coap_put_option_uri(bufpos, last_optnum, (char *)pdu->qs, bufpos += coap_opt_put_uri_query(bufpos, last_optnum,
COAP_OPT_URI_QUERY); (char *)pdu->qs);
/* uncomment when further options are added below ... */ /* uncomment when further options are added below ... */
/* last_optnum = COAP_OPT_URI_QUERY; */ /* last_optnum = COAP_OPT_URI_QUERY; */
} }

View File

@ -1,5 +1,6 @@
/* /*
* Copyright (C) 2016-18 Kaspar Schleiser <kaspar@schleiser.de> * Copyright (C) 2016-18 Kaspar Schleiser <kaspar@schleiser.de>
* 2018 Freie Universität Berlin
* *
* This file is subject to the terms and conditions of the GNU Lesser * This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level * General Public License v2.1. See the file LICENSE in the top level
@ -14,6 +15,7 @@
* @brief Nanocoap implementation * @brief Nanocoap implementation
* *
* @author Kaspar Schleiser <kaspar@schleiser.de> * @author Kaspar Schleiser <kaspar@schleiser.de>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* *
* @} * @}
*/ */
@ -117,7 +119,7 @@ int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len)
} }
#ifdef MODULE_GCOAP #ifdef MODULE_GCOAP
coap_get_uri(pkt, pkt->url); coap_get_uri_path(pkt, pkt->url);
pkt->content_type = coap_get_content_type(pkt); pkt->content_type = coap_get_content_type(pkt);
if (coap_get_option_uint(pkt, COAP_OPT_OBSERVE, &pkt->observe_value) != 0) { if (coap_get_option_uint(pkt, COAP_OPT_OBSERVE, &pkt->observe_value) != 0) {
@ -133,9 +135,9 @@ int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len)
return 0; return 0;
} }
uint8_t *coap_find_option(coap_pkt_t *pkt, unsigned opt_num) uint8_t *coap_find_option(const coap_pkt_t *pkt, unsigned opt_num)
{ {
coap_optpos_t *optpos = pkt->options; const coap_optpos_t *optpos = pkt->options;
unsigned opt_count = pkt->options_len; unsigned opt_count = pkt->options_len;
while (opt_count--) { while (opt_count--) {
@ -147,7 +149,8 @@ uint8_t *coap_find_option(coap_pkt_t *pkt, unsigned opt_num)
return NULL; return NULL;
} }
static uint8_t *_parse_option(coap_pkt_t *pkt, uint8_t *pkt_pos, uint16_t *delta, int *opt_len) static uint8_t *_parse_option(const coap_pkt_t *pkt,
uint8_t *pkt_pos, uint16_t *delta, int *opt_len)
{ {
uint8_t *hdr_end = pkt->payload; uint8_t *hdr_end = pkt->payload;
@ -188,7 +191,8 @@ int coap_get_option_uint(coap_pkt_t *pkt, unsigned opt_num, uint32_t *target)
return -1; return -1;
} }
uint8_t *coap_iterate_option(coap_pkt_t *pkt, uint8_t **optpos, int *opt_len, int first) uint8_t *coap_iterate_option(const coap_pkt_t *pkt, uint8_t **optpos,
int *opt_len, int first)
{ {
uint8_t *data_start; uint8_t *data_start;
@ -226,25 +230,29 @@ unsigned coap_get_content_type(coap_pkt_t *pkt)
return content_type; return content_type;
} }
int coap_get_uri(coap_pkt_t *pkt, uint8_t *target) ssize_t coap_opt_get_string(const coap_pkt_t *pkt, uint16_t optnum,
uint8_t *target, size_t max_len, char separator)
{ {
uint8_t *opt_pos = coap_find_option(pkt, COAP_OPT_URI_PATH); assert(pkt && target && (max_len > 1));
uint8_t *opt_pos = coap_find_option(pkt, optnum);
if (!opt_pos) { if (!opt_pos) {
*target++ = '/'; *target++ = (uint8_t)separator;
*target = '\0'; *target = '\0';
return 2; return 2;
} }
unsigned left = NANOCOAP_URI_MAX - 1; unsigned left = max_len - 1;
uint8_t *part_start = NULL; uint8_t *part_start = NULL;
do { do {
int opt_len; int opt_len;
part_start = coap_iterate_option(pkt, &opt_pos, &opt_len, part_start==NULL); part_start = coap_iterate_option(pkt, &opt_pos, &opt_len,
(part_start == NULL));
if (part_start) { if (part_start) {
if (left < (unsigned)(opt_len + 1)) { if (left < (unsigned)(opt_len + 1)) {
return -ENOSPC; return -ENOSPC;
} }
*target++ = '/'; *target++ = (uint8_t)separator;
memcpy(target, part_start, opt_len); memcpy(target, part_start, opt_len);
target += opt_len; target += opt_len;
left -= (opt_len + 1); left -= (opt_len + 1);
@ -253,7 +261,7 @@ int coap_get_uri(coap_pkt_t *pkt, uint8_t *target)
*target = '\0'; *target = '\0';
return NANOCOAP_URI_MAX - left; return (int)(max_len - left);
} }
int coap_get_blockopt(coap_pkt_t *pkt, uint16_t option, uint32_t *blknum, unsigned *szx) int coap_get_blockopt(coap_pkt_t *pkt, uint16_t option, uint32_t *blknum, unsigned *szx)
@ -296,7 +304,7 @@ ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_le
uint8_t *uri = pkt->url; uint8_t *uri = pkt->url;
#else #else
uint8_t uri[NANOCOAP_URI_MAX]; uint8_t uri[NANOCOAP_URI_MAX];
if (coap_get_uri(pkt, uri) <= 0) { if (coap_get_uri_path(pkt, uri) <= 0) {
return -EBADMSG; return -EBADMSG;
} }
#endif #endif
@ -569,24 +577,24 @@ size_t coap_put_block1_ok(uint8_t *pkt_pos, coap_block1_t *block1, uint16_t last
} }
} }
size_t coap_put_option_uri(uint8_t *buf, uint16_t lastonum, const char *uri, uint16_t optnum) size_t coap_opt_put_string(uint8_t *buf, uint16_t lastonum, uint16_t optnum,
const char *string, char separator)
{ {
char separator = (optnum == COAP_OPT_URI_PATH) ? '/' : '&'; size_t len = strlen(string);
size_t uri_len = strlen(uri);
if (uri_len == 0) { if (len == 0) {
return 0; return 0;
} }
uint8_t *bufpos = buf; uint8_t *bufpos = buf;
char *uripos = (char *)uri; char *uripos = (char *)string;
while (uri_len) { while (len) {
size_t part_len; size_t part_len;
uripos++; uripos++;
uint8_t *part_start = (uint8_t *)uripos; uint8_t *part_start = (uint8_t *)uripos;
while (uri_len--) { while (len--) {
if ((*uripos == separator) || (*uripos == '\0')) { if ((*uripos == separator) || (*uripos == '\0')) {
break; break;
} }

View File

@ -95,7 +95,7 @@ ssize_t nanocoap_get(sock_udp_ep_t *remote, const char *path, uint8_t *buf, size
pkt.hdr = (coap_hdr_t*)buf; pkt.hdr = (coap_hdr_t*)buf;
pktpos += coap_build_hdr(pkt.hdr, COAP_REQ, NULL, 0, COAP_METHOD_GET, 1); pktpos += coap_build_hdr(pkt.hdr, COAP_REQ, NULL, 0, COAP_METHOD_GET, 1);
pktpos += coap_put_option_uri(pktpos, 0, path, COAP_OPT_URI_PATH); pktpos += coap_opt_put_uri_path(pktpos, 0, path);
pkt.payload = pktpos; pkt.payload = pktpos;
pkt.payload_len = 0; pkt.payload_len = 0;

View File

@ -30,20 +30,27 @@ static void test_nanocoap__hdr(void)
uint8_t buf[128]; uint8_t buf[128];
uint16_t msgid = 0xABCD; uint16_t msgid = 0xABCD;
char path[] = "/test/abcd/efgh"; char path[] = "/test/abcd/efgh";
char loc_path[] = "/foo/bar";
unsigned char path_tmp[64] = {0}; unsigned char path_tmp[64] = {0};
uint8_t *pktpos = &buf[0]; uint8_t *pktpos = &buf[0];
pktpos += coap_build_hdr((coap_hdr_t *)pktpos, COAP_REQ, NULL, 0, COAP_METHOD_GET, msgid); pktpos += coap_build_hdr((coap_hdr_t *)pktpos, COAP_REQ, NULL, 0,
pktpos += coap_put_option_uri(pktpos, 0, path, COAP_OPT_URI_PATH); COAP_METHOD_GET, msgid);
pktpos += coap_opt_put_location_path(pktpos, 0, loc_path);
pktpos += coap_opt_put_uri_path(pktpos, COAP_OPT_LOCATION_PATH, path);
coap_pkt_t pkt; coap_pkt_t pkt;
coap_parse(&pkt, &buf[0], pktpos - &buf[0]); coap_parse(&pkt, &buf[0], pktpos - &buf[0]);
TEST_ASSERT_EQUAL_INT(msgid, coap_get_id(&pkt)); TEST_ASSERT_EQUAL_INT(msgid, coap_get_id(&pkt));
int res = coap_get_uri(&pkt, path_tmp); int res = coap_get_uri_path(&pkt, path_tmp);
TEST_ASSERT_EQUAL_INT(sizeof(path), res); TEST_ASSERT_EQUAL_INT(sizeof(path), res);
TEST_ASSERT_EQUAL_STRING((char *)path, (char *)path_tmp); TEST_ASSERT_EQUAL_STRING((char *)path, (char *)path_tmp);
res = coap_get_location_path(&pkt, path_tmp, 64);
TEST_ASSERT_EQUAL_INT(sizeof(loc_path), res);
TEST_ASSERT_EQUAL_STRING((char *)loc_path, (char *)path_tmp);
} }
/* /*
@ -76,7 +83,7 @@ static void test_nanocoap__get_req(void)
TEST_ASSERT_EQUAL_INT(total_opt_len, len); TEST_ASSERT_EQUAL_INT(total_opt_len, len);
char uri[10] = {0}; char uri[10] = {0};
coap_get_uri(&pkt, (uint8_t *)&uri[0]); coap_get_uri_path(&pkt, (uint8_t *)&uri[0]);
TEST_ASSERT_EQUAL_STRING((char *)path, (char *)uri); TEST_ASSERT_EQUAL_STRING((char *)path, (char *)uri);
len = coap_opt_finish(&pkt, COAP_OPT_FINISH_NONE); len = coap_opt_finish(&pkt, COAP_OPT_FINISH_NONE);
@ -140,7 +147,7 @@ static void test_nanocoap__get_multi_path(void)
TEST_ASSERT_EQUAL_INT(uri_opt_len, len); TEST_ASSERT_EQUAL_INT(uri_opt_len, len);
char uri[10] = {0}; char uri[10] = {0};
coap_get_uri(&pkt, (uint8_t *)&uri[0]); coap_get_uri_path(&pkt, (uint8_t *)&uri[0]);
TEST_ASSERT_EQUAL_STRING((char *)path, (char *)uri); TEST_ASSERT_EQUAL_STRING((char *)path, (char *)uri);
} }
@ -162,7 +169,7 @@ static void test_nanocoap__get_root_path(void)
coap_pkt_init(&pkt, &buf[0], sizeof(buf), len); coap_pkt_init(&pkt, &buf[0], sizeof(buf), len);
char uri[10] = {0}; char uri[10] = {0};
coap_get_uri(&pkt, (uint8_t *)&uri[0]); coap_get_uri_path(&pkt, (uint8_t *)&uri[0]);
TEST_ASSERT_EQUAL_STRING((char *)path, (char *)uri); TEST_ASSERT_EQUAL_STRING((char *)path, (char *)uri);
} }
@ -188,13 +195,13 @@ static void test_nanocoap__get_max_path(void)
TEST_ASSERT_EQUAL_INT(uri_opt_len, len); TEST_ASSERT_EQUAL_INT(uri_opt_len, len);
char uri[NANOCOAP_URI_MAX] = {0}; char uri[NANOCOAP_URI_MAX] = {0};
coap_get_uri(&pkt, (uint8_t *)&uri[0]); coap_get_uri_path(&pkt, (uint8_t *)&uri[0]);
TEST_ASSERT_EQUAL_STRING((char *)path, (char *)uri); TEST_ASSERT_EQUAL_STRING((char *)path, (char *)uri);
} }
/* /*
* Builds on get_req test, to test path longer than NANOCOAP_URI_MAX. We * Builds on get_req test, to test path longer than NANOCOAP_URI_MAX. We
* expect coap_get_uri() to return -ENOSPC. * expect coap_get_uri_path() to return -ENOSPC.
*/ */
static void test_nanocoap__get_path_too_long(void) static void test_nanocoap__get_path_too_long(void)
{ {
@ -215,7 +222,7 @@ static void test_nanocoap__get_path_too_long(void)
TEST_ASSERT_EQUAL_INT(uri_opt_len, len); TEST_ASSERT_EQUAL_INT(uri_opt_len, len);
char uri[NANOCOAP_URI_MAX] = {0}; char uri[NANOCOAP_URI_MAX] = {0};
int get_len = coap_get_uri(&pkt, (uint8_t *)&uri[0]); int get_len = coap_get_uri_path(&pkt, (uint8_t *)&uri[0]);
TEST_ASSERT_EQUAL_INT(-ENOSPC, get_len); TEST_ASSERT_EQUAL_INT(-ENOSPC, get_len);
} }