net/nanocoap: create pkt-based request
Includes string and uint options.
This commit is contained in:
parent
fd1a987bf1
commit
43db2715cd
@ -17,6 +17,7 @@
|
|||||||
* @brief nanocoap API
|
* @brief nanocoap API
|
||||||
*
|
*
|
||||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||||
|
* @author Ken Bannister <kb2ma@runbox.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef NET_NANOCOAP_H
|
#ifndef NET_NANOCOAP_H
|
||||||
@ -224,6 +225,18 @@ extern "C" {
|
|||||||
#define COAP_BLOCKWISE_SZX_MAX (7)
|
#define COAP_BLOCKWISE_SZX_MAX (7)
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name coap_opt_finish() flag parameter values
|
||||||
|
*
|
||||||
|
* Directs packet/buffer updates when user finishes adding options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/** @brief no special handling required */
|
||||||
|
#define COAP_OPT_FINISH_NONE (0x0000)
|
||||||
|
/** @brief expect a payload to follow */
|
||||||
|
#define COAP_OPT_FINISH_PAYLOAD (0x0001)
|
||||||
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raw CoAP PDU header structure
|
* @brief Raw CoAP PDU header structure
|
||||||
*/
|
*/
|
||||||
@ -390,6 +403,22 @@ 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,
|
ssize_t coap_build_hdr(coap_hdr_t *hdr, unsigned type, uint8_t *token,
|
||||||
size_t token_len, unsigned code, uint16_t id);
|
size_t token_len, unsigned code, uint16_t id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize a packet struct, to build a message buffer
|
||||||
|
*
|
||||||
|
* @pre buf CoAP header already initialized
|
||||||
|
* @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
|
* @brief Insert a CoAP option into buffer
|
||||||
*
|
*
|
||||||
@ -499,6 +528,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);
|
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[in,out] 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
|
||||||
|
* @return -ENOSPC if no available options
|
||||||
|
*/
|
||||||
|
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[in,out] 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
|
||||||
|
* @return <0 reserved for error but not implemented yet
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
*
|
||||||
|
* @post pkt.payload advanced to first available byte after options
|
||||||
|
* @post pkt.payload_len is maximum bytes available for payload
|
||||||
|
*
|
||||||
|
* @param[in,out] pkt pkt to update
|
||||||
|
* @param[in] flags see COAP_OPT_FINISH... macros
|
||||||
|
*
|
||||||
|
* @return total number of bytes written to buffer
|
||||||
|
*/
|
||||||
|
ssize_t coap_opt_finish(coap_pkt_t *pkt, uint16_t flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get content type from packet
|
* @brief Get content type from packet
|
||||||
*
|
*
|
||||||
|
|||||||
@ -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;
|
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)
|
static int _decode_value(unsigned val, uint8_t **pkt_pos_ptr, uint8_t *pkt_end)
|
||||||
{
|
{
|
||||||
uint8_t *pkt_pos = *pkt_pos_ptr;
|
uint8_t *pkt_pos = *pkt_pos_ptr;
|
||||||
@ -595,6 +604,85 @@ size_t coap_put_option_uri(uint8_t *buf, uint16_t lastonum, const char *uri, uin
|
|||||||
return bufpos - buf;
|
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)
|
||||||
|
{
|
||||||
|
assert(pkt->options_len < NANOCOAP_NOPTS_MAX);
|
||||||
|
|
||||||
|
uint16_t lastonum = (pkt->options_len)
|
||||||
|
? pkt->options[pkt->options_len - 1].opt_num : 0;
|
||||||
|
assert(optnum >= lastonum);
|
||||||
|
|
||||||
|
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) {
|
||||||
|
if (pkt->options_len == NANOCOAP_NOPTS_MAX) {
|
||||||
|
return -ENOSPC;
|
||||||
|
}
|
||||||
|
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, uint16_t flags)
|
||||||
|
{
|
||||||
|
if (flags & COAP_OPT_FINISH_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, \
|
ssize_t coap_well_known_core_default_handler(coap_pkt_t *pkt, uint8_t *buf, \
|
||||||
size_t len, void *context)
|
size_t len, void *context)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user