Skip to content

Commit

Permalink
net/nanocoap: create pkt-based request
Browse files Browse the repository at this point in the history
Includes string and uint options, entered in final form.
  • Loading branch information
kb2ma committed May 10, 2018
1 parent d0f22b7 commit 06eda0b
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 0 deletions.
71 changes: 71 additions & 0 deletions sys/include/net/nanocoap.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,14 @@ extern "C" {
#define COAP_DEFAULT_LEISURE (5)
/** @} */

/**
* @name coap_pkt_t bitwise flags identifiers
* @{
*/
#define COAP_PKT_FLAGS_OPT_PROVISIONAL (0x1)
#define COAP_PKT_FLAGS_OPT_MOVE_PAYLOAD (0x2)
/** @} */

/**
* @name Blockwise transfer (RFC7959)
* @{
Expand Down Expand Up @@ -252,6 +260,8 @@ typedef struct {
uint16_t payload_len; /**< length of payload */
uint16_t options_len; /**< length of options array */
coap_optpos_t options[NANOCOAP_NOPTS_MAX]; /**< option offset array */
uint16_t flags; /**< bitwise flags used while
building packet */
#ifdef MODULE_GCOAP
uint8_t url[NANOCOAP_URI_MAX]; /**< parsed request URL */
uint8_t qs[NANOCOAP_QS_MAX]; /**< parsed query string */
Expand Down Expand Up @@ -390,6 +400,21 @@ ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_le
ssize_t coap_build_hdr(coap_hdr_t *hdr, unsigned type, uint8_t *token,
size_t token_len, unsigned code, uint16_t id);

/**
* @brief Initialize a packet struct, to build a message buffer
*
* @post pkt.flags all zeroed
* @post pkt.payload points to first byte after header
* @post pkt.payload_len set to maximum space available for options + payload
*
* @param[out] pkt pkt to initialize
* @param[in] buf buffer to write for pkt, with CoAP header already
* initialized
* @param[in] len length of buf
* @param[in] header_len length of header in buf, including token
*/
void coap_pkt_init(coap_pkt_t *pkt, uint8_t *buf, size_t len, size_t header_len);

/**
* @brief Insert a CoAP option into buffer
*
Expand Down Expand Up @@ -499,6 +524,52 @@ size_t coap_put_option_block1(uint8_t *buf, uint16_t lastonum, unsigned blknum,
*/
size_t coap_put_block1_ok(uint8_t *pkt_pos, coap_block1_t *block1, uint16_t lastonum);

/**
* @brief Encode the given string as option(s) into pkt
*
* Use separator to split string into multiple options.
*
* @post pkt.payload advanced to first byte after option(s)
* @post pkt.payload_len reduced by option(s) length
*
* @param[inout] pkt pkt referencing target buffer
* @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 buffer
*/
ssize_t coap_opt_add_string(coap_pkt_t *pkt, uint16_t optnum, const char *string, char separator);

/**
* @brief Encode the given uint option into pkt
*
* @post pkt.payload advanced to first byte after option
* @post pkt.payload_len reduced by option length
*
* @param[inout] pkt pkt referencing target buffer
* @param[in] optnum option number to use
* @param[in] value uint to encode
*
* @return number of bytes written to buffer
*/
ssize_t coap_opt_add_uint(coap_pkt_t *pkt, uint16_t optnum, uint32_t value);

/**
* @brief Finalizes options as required and prepares for payload
*
* If building in provisional mode, rewrites options in order.
*
* @post pkt.payload advanced to first available byte after options
* @post pkt.payload_len is maximum bytes available for payload
*
* @param[inout] pkt pkt to update
* @param[in] expect_payload user plans to append a payload
*
* @return total number of bytes written to buffer
*/
ssize_t coap_opt_finish(coap_pkt_t *pkt, bool expect_payload);

/**
* @brief Get content type from packet
*
Expand Down
87 changes: 87 additions & 0 deletions sys/net/application_layer/nanocoap/nanocoap.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,15 @@ ssize_t coap_build_hdr(coap_hdr_t *hdr, unsigned type, uint8_t *token, size_t to
return sizeof(coap_hdr_t) + token_len;
}

void coap_pkt_init(coap_pkt_t *pkt, uint8_t *buf, size_t len, size_t header_len)
{
memset(pkt, 0, sizeof(coap_pkt_t));
pkt->hdr = (coap_hdr_t *)buf;
pkt->token = buf + sizeof(coap_hdr_t);
pkt->payload = buf + header_len;
pkt->payload_len = len - header_len;
}

static int _decode_value(unsigned val, uint8_t **pkt_pos_ptr, uint8_t *pkt_end)
{
uint8_t *pkt_pos = *pkt_pos_ptr;
Expand Down Expand Up @@ -595,6 +604,84 @@ size_t coap_put_option_uri(uint8_t *buf, uint16_t lastonum, const char *uri, uin
return bufpos - buf;
}

/* Common functionality for addition of an option */
static ssize_t _add_opt_pkt(coap_pkt_t *pkt, uint16_t optnum, uint8_t *val,
size_t val_len)
{
uint16_t lastonum;
if (!pkt->options_len || (pkt->flags & COAP_PKT_FLAGS_OPT_PROVISIONAL)) {
lastonum = 0;
}
else {
lastonum = pkt->options[pkt->options_len - 1].opt_num;
}

size_t optlen = coap_put_option(pkt->payload, lastonum, optnum, val, val_len);
assert(pkt->payload_len > optlen);

pkt->options[pkt->options_len].opt_num = optnum;
pkt->options[pkt->options_len].offset = pkt->payload - (uint8_t *)pkt->hdr;
pkt->options_len++;
pkt->payload += optlen;
pkt->payload_len -= optlen;

return optlen;
}

ssize_t coap_opt_add_string(coap_pkt_t *pkt, uint16_t optnum, const char *string,
char separator)
{
size_t unread_len = strlen(string);
if (!unread_len) {
return 0;
}
char *uripos = (char *)string;
size_t write_len = 0;

while (unread_len) {
size_t part_len;
uripos++;
uint8_t *part_start = (uint8_t *)uripos;

while (unread_len--) {
if ((*uripos == separator) || (*uripos == '\0')) {
break;
}
uripos++;
}

part_len = (uint8_t *)uripos - part_start;

if (part_len) {
write_len += _add_opt_pkt(pkt, optnum, part_start, part_len);;
}
}

return write_len;
}

ssize_t coap_opt_add_uint(coap_pkt_t *pkt, uint16_t optnum, uint32_t value)
{
uint32_t tmp = value;
unsigned tmp_len = _encode_uint(&tmp);
return _add_opt_pkt(pkt, optnum, (uint8_t *)&tmp, tmp_len);
}

ssize_t coap_opt_finish(coap_pkt_t *pkt, bool expect_payload)
{
if (expect_payload) {
assert(pkt->payload_len > 1);

*pkt->payload++ = 0xFF;
pkt->payload_len--;
}
else {
pkt->payload_len = 0;
}

return pkt->payload - (uint8_t *)pkt->hdr;
}

ssize_t coap_well_known_core_default_handler(coap_pkt_t *pkt, uint8_t *buf, \
size_t len, void *context)
{
Expand Down

0 comments on commit 06eda0b

Please sign in to comment.