1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

Merge pull request #11057 from kb2ma/coap/block_optimization

net/coap: Block optimizations
This commit is contained in:
Francisco 2019-10-04 09:41:05 +02:00 committed by GitHub
commit 7d7596ea6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 80 additions and 98 deletions

View File

@ -717,6 +717,26 @@ size_t coap_blockwise_put_bytes(coap_block_slicer_t *slicer, uint8_t *bufpos,
*/
size_t coap_blockwise_put_char(coap_block_slicer_t *slicer, uint8_t *bufpos, char c);
/**
* @brief Block option getter
*
* This function gets a CoAP packet's block option and parses it into a helper
* structure.
*
* If no block option is present in @p pkt, the values in @p block will be
* initialized with zero. That implies both block->offset and block->more are
* also valid in that case, as packet with offset==0 and more==0 means it contains
* all the payload for the corresponding request.
*
* @param[in] pkt pkt to work on
* @param[out] block ptr to preallocated coap_block1_t structure
* @param[in] option block1 or block2
*
* @returns 0 if block option not present
* @returns 1 if structure has been filled
*/
int coap_get_block(coap_pkt_t *pkt, coap_block1_t *block, uint16_t option);
/**
* @brief Block1 option getter
*
@ -729,23 +749,29 @@ size_t coap_blockwise_put_char(coap_block_slicer_t *slicer, uint8_t *bufpos, cha
* all the payload for the corresponding request.
*
* @param[in] pkt pkt to work on
* @param[out] block1 ptr to preallocated coap_block1_t structure
* @param[out] block ptr to preallocated coap_block1_t structure
*
* @returns 0 if block1 option not present
* @returns 1 if structure has been filled
*/
int coap_get_block1(coap_pkt_t *pkt, coap_block1_t *block1);
static inline int coap_get_block1(coap_pkt_t *pkt, coap_block1_t *block)
{
return coap_get_block(pkt, block, COAP_OPT_BLOCK1);
}
/**
* @brief Block2 option getter
*
* @param[in] pkt pkt to work on
* @param[out] block2 ptr to preallocated coap_block1_t structure
* @param[out] block ptr to preallocated coap_block1_t structure
*
* @returns 0 if block2 option not present
* @returns 1 if structure has been filled
*/
int coap_get_block2(coap_pkt_t *pkt, coap_block1_t *block2);
static inline int coap_get_block2(coap_pkt_t *pkt, coap_block1_t *block)
{
return coap_get_block(pkt, block, COAP_OPT_BLOCK2);
}
/**
* @brief Generic block option getter
@ -1039,17 +1065,18 @@ static inline size_t coap_opt_put_block2(uint8_t *buf, uint16_t lastonum,
}
/**
* @brief Insert block option into buffer from block struct
* @brief Encode the given uint option into buffer
*
* @param[in] buf buffer to write to
* @param[in] lastonum last option number (must be < @p option)
* @param[in] block block option attribute struct
* @param[in] option option number (block1 or block2)
* @param[out] buf buffer to write to
* @param[in] lastonum number of previous option (for delta calculation),
* or 0 for first option
* @param[in] onum number of option
* @param[in] value value to encode
*
* @returns amount of bytes written to @p buf
*/
size_t coap_opt_put_block_object(uint8_t *buf, uint16_t lastonum,
coap_block1_t *block, uint16_t option);
size_t coap_opt_put_uint(uint8_t *buf, uint16_t lastonum, uint16_t onum,
uint32_t value);
/**
* @brief Insert block1 option into buffer in control usage
@ -1063,7 +1090,8 @@ size_t coap_opt_put_block_object(uint8_t *buf, uint16_t lastonum,
static inline size_t coap_opt_put_block1_control(uint8_t *buf, uint16_t lastonum,
coap_block1_t *block)
{
return coap_opt_put_block_object(buf, lastonum, block, COAP_OPT_BLOCK1);
return coap_opt_put_uint(buf, lastonum, COAP_OPT_BLOCK1,
(block->blknum << 4) | block->szx | (block->more ? 0x8 : 0));
}
/**
@ -1080,8 +1108,9 @@ static inline size_t coap_opt_put_block1_control(uint8_t *buf, uint16_t lastonum
static inline size_t coap_opt_put_block2_control(uint8_t *buf, uint16_t lastonum,
coap_block1_t *block)
{
block->more = 0;
return coap_opt_put_block_object(buf, lastonum, block, COAP_OPT_BLOCK2);
/* block.more must be zero, so no need to 'or' it in */
return coap_opt_put_uint(buf, lastonum, COAP_OPT_BLOCK2,
(block->blknum << 4) | block->szx);
}
/**
@ -1216,7 +1245,12 @@ size_t coap_put_option(uint8_t *buf, uint16_t lastonum, uint16_t onum, const uin
*
* @returns amount of bytes written to @p buf
*/
size_t coap_put_option_block1(uint8_t *buf, uint16_t lastonum, unsigned blknum, unsigned szx, int more);
static inline size_t coap_put_option_block1(uint8_t *buf, uint16_t lastonum,
unsigned blknum, unsigned szx, int more)
{
return coap_opt_put_uint(buf, lastonum, COAP_OPT_BLOCK1,
(blknum << 4) | szx | (more ? 0x8 : 0));
}
/**
* @brief Insert content type option into buffer
@ -1228,7 +1262,11 @@ size_t coap_put_option_block1(uint8_t *buf, uint16_t lastonum, unsigned blknum,
*
* @returns amount of bytes written to @p buf
*/
size_t coap_put_option_ct(uint8_t *buf, uint16_t lastonum, uint16_t content_type);
static inline size_t coap_put_option_ct(uint8_t *buf, uint16_t lastonum,
uint16_t content_type)
{
return coap_opt_put_uint(buf, lastonum, COAP_OPT_CONTENT_FORMAT, content_type);
}
/**@}*/

View File

@ -26,6 +26,7 @@
#include <stdio.h>
#include <string.h>
#include "bitarithm.h"
#include "net/nanocoap.h"
#define ENABLE_DEBUG (0)
@ -653,35 +654,20 @@ size_t coap_put_option(uint8_t *buf, uint16_t lastonum, uint16_t onum, const uin
return (size_t)n;
}
size_t coap_put_option_ct(uint8_t *buf, uint16_t lastonum, uint16_t content_type)
{
if (content_type == 0) {
return coap_put_option(buf, lastonum, COAP_OPT_CONTENT_FORMAT, NULL, 0);
}
else if (content_type <= 255) {
uint8_t tmp = content_type;
return coap_put_option(buf, lastonum, COAP_OPT_CONTENT_FORMAT, &tmp, sizeof(tmp));
}
else {
return coap_put_option(buf, lastonum, COAP_OPT_CONTENT_FORMAT, (uint8_t *)&content_type, sizeof(content_type));
}
}
static unsigned _size2szx(size_t size)
{
unsigned szx = 0;
assert(size <= 1024);
while (size) {
size = size >> 1;
szx++;
}
/* Size exponent + 1 */
assert(szx >= 5);
return szx - 5;
/* We must wait to subract the szx offset of 4 until after the assert below.
* Input should be a power of two, but if not it may have a stray low order
* '1' bit that would invalidate the subtraction. */
unsigned szx = bitarithm_lsb(size);
assert(szx >= 4);
return szx - 4;
}
static unsigned _slicer_blknum(coap_block_slicer_t *slicer)
static unsigned _slicer2blkopt(coap_block_slicer_t *slicer, bool more)
{
size_t blksize = slicer->end - slicer->start;
size_t start = slicer->start;
@ -691,51 +677,23 @@ static unsigned _slicer_blknum(coap_block_slicer_t *slicer)
start -= blksize;
blknum++;
}
return blknum;
return (blknum << 4) | _size2szx(blksize) | (more ? 0x8 : 0);
}
static size_t coap_put_option_block(uint8_t *buf, uint16_t lastonum, unsigned blknum, unsigned szx, int more, uint16_t option)
int coap_get_block(coap_pkt_t *pkt, coap_block1_t *block, uint16_t option)
{
uint32_t blkopt = (blknum << 4) | szx | (more ? 0x8 : 0);
size_t olen = _encode_uint(&blkopt);
return coap_put_option(buf, lastonum, option, (uint8_t *)&blkopt, olen);
}
size_t coap_put_option_block1(uint8_t *buf, uint16_t lastonum, unsigned blknum, unsigned szx, int more)
{
return coap_put_option_block(buf, lastonum, blknum, szx, more, COAP_OPT_BLOCK1);
}
int coap_get_block(coap_pkt_t *pkt, coap_block1_t *block, uint16_t blkopt)
{
uint32_t blknum;
unsigned szx;
block->more = coap_get_blockopt(pkt, blkopt, &blknum, &szx);
block->more = coap_get_blockopt(pkt, option, &block->blknum, &block->szx);
if (block->more >= 0) {
block->offset = blknum << (szx + 4);
block->offset = block->blknum << (block->szx + 4);
}
else {
block->offset = 0;
}
block->blknum = blknum;
block->szx = szx;
return (block->more >= 0);
}
int coap_get_block1(coap_pkt_t *pkt, coap_block1_t *block)
{
return coap_get_block(pkt, block, COAP_OPT_BLOCK1);
}
int coap_get_block2(coap_pkt_t *pkt, coap_block1_t *block)
{
return coap_get_block(pkt, block, COAP_OPT_BLOCK2);
}
size_t coap_put_block1_ok(uint8_t *pkt_pos, coap_block1_t *block1, uint16_t lastonum)
{
if (block1->more >= 1) {
@ -749,23 +707,9 @@ size_t coap_put_block1_ok(uint8_t *pkt_pos, coap_block1_t *block1, uint16_t last
size_t coap_opt_put_block(uint8_t *buf, uint16_t lastonum, coap_block_slicer_t *slicer,
bool more, uint16_t option)
{
coap_block1_t block;
coap_block_object_init(&block, _slicer_blknum(slicer),
slicer->end - slicer->start, more);
slicer->opt = buf;
return coap_opt_put_block_object(buf, lastonum, &block, option);
}
size_t coap_opt_put_block_object(uint8_t *buf, uint16_t lastonum,
coap_block1_t *block, uint16_t option)
{
uint32_t blkopt = (block->blknum << 4) | block->szx | (block->more ? 0x8 : 0);
size_t olen = _encode_uint(&blkopt);
return coap_put_option(buf, lastonum, option, (uint8_t *)&blkopt, olen);
return coap_opt_put_uint(buf, lastonum, option, _slicer2blkopt(slicer, more));
}
size_t coap_opt_put_string(uint8_t *buf, uint16_t lastonum, uint16_t optnum,
@ -810,6 +754,14 @@ size_t coap_opt_put_string(uint8_t *buf, uint16_t lastonum, uint16_t optnum,
return bufpos - buf;
}
size_t coap_opt_put_uint(uint8_t *buf, uint16_t lastonum, uint16_t onum,
uint32_t value)
{
unsigned uint_len = _encode_uint(&value);
return coap_put_option(buf, lastonum, onum, (uint8_t *)&value, uint_len);
}
/* Common functionality for addition of an option */
static ssize_t _add_opt_pkt(coap_pkt_t *pkt, uint16_t optnum, const uint8_t *val,
size_t val_len)
@ -900,13 +852,9 @@ ssize_t coap_opt_add_uint(coap_pkt_t *pkt, uint16_t optnum, uint32_t value)
ssize_t coap_opt_add_block(coap_pkt_t *pkt, coap_block_slicer_t *slicer,
bool more, uint16_t option)
{
uint32_t blkopt = (_slicer_blknum(slicer) << 4);
blkopt |= _size2szx(slicer->end - slicer->start);
blkopt |= (more ? 0x8 : 0);
slicer->opt = pkt->payload;
return coap_opt_add_uint(pkt, option, blkopt);
return coap_opt_add_uint(pkt, option, _slicer2blkopt(slicer, more));
}
ssize_t coap_opt_finish(coap_pkt_t *pkt, uint16_t flags)
@ -932,6 +880,7 @@ void coap_block_object_init(coap_block1_t *block, size_t blknum, size_t blksize,
block->szx = _size2szx(blksize);
block->blknum = blknum;
block->more = more;
block->offset = block->blknum << (block->szx + 4);
}
void coap_block_slicer_init(coap_block_slicer_t *slicer, size_t blknum,
@ -969,12 +918,7 @@ void coap_block_finish(coap_block_slicer_t *slicer, uint16_t option)
uint8_t *pos = slicer->opt + 1;
uint16_t delta = _decode_value(*slicer->opt >> 4, &pos, slicer->opt + 3);
/* Calculate the block uint value inline here rather than through
* coap_opt_put_block(). Conserves stack and avoids importing Buffer API
* functions when using Packet API. */
uint32_t blkopt = (_slicer_blknum(slicer) << 4);
blkopt |= _size2szx(slicer->end - slicer->start);
blkopt |= ((slicer->cur > slicer->end) ? 0x8 : 0);
uint32_t blkopt = _slicer2blkopt(slicer, slicer->cur > slicer->end);
size_t olen = _encode_uint(&blkopt);
coap_put_option(slicer->opt, option - delta, option, (uint8_t *)&blkopt, olen);