Skip to content

Commit

Permalink
Merge pull request #11024 from kb2ma/coap/add_block_helpers
Browse files Browse the repository at this point in the history
net/nanocoap: Buffer API Block helper functions
  • Loading branch information
kb2ma authored Jul 31, 2019
2 parents dd6a5cd + 64b4e0a commit b5200e9
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 15 deletions.
66 changes: 62 additions & 4 deletions sys/include/net/nanocoap.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,18 +540,64 @@ static inline ssize_t coap_get_uri_query(const coap_pkt_t *pkt, uint8_t *target)
* generally useful functions to write block options.
*/
/**@{*/
/**
* @brief Initialize a block struct from content information
*
* @param[out] block block struct to initialize
* @param[in] blknum offset from the beginning of content, in terms of
@p blksize byte blocks
* @param[in] blksize size of each block; must be a power of 2 between 16
* and 2 raised to #NANOCOAP_BLOCK_SIZE_EXP_MAX
* @param[in] more more blocks? use 1 if yes; 0 if no or unknown
*/
void coap_block_object_init(coap_block1_t *block, size_t blknum, size_t blksize,
int more);

/**
* @brief Finish a block request (block1 or block2)
*
* This function finalizes the block response header
*
* Checks whether the `more` bit should be set in the block option and
* sets/clears it if required. Doesn't return the number of bytes, as this
* function overwrites bytes in the packet rather than adding new.
*
* @param[in] slicer Preallocated slicer struct to use
* @param[in] option option number (block1 or block2)
*/
void coap_block_finish(coap_block_slicer_t *slicer, uint16_t option);

/**
* @brief Finish a block1 request
*
* This function finalizes the block1 response header
*
* Checks whether the `more` bit should be set in the block1 option and
* sets/clears it if required. Doesn't return the number of bytes, as this
* function overwrites bytes in the packet rather than adding new.
*
* @param[in] slicer Preallocated slicer struct to use
*/
static inline void coap_block1_finish(coap_block_slicer_t *slicer)
{
coap_block_finish(slicer, COAP_OPT_BLOCK1);
}

/**
* @brief Finish a block2 response
*
* This function finalizes the block2 response header
*
* Checks whether the `more` bit should be set in the block2 option and
* sets/clears it if required. Doesn't return the number of bytes as this
* overwrites bytes in the packet, it doesn't add new bytes to the packet.
* sets/clears it if required. Doesn't return the number of bytes, as this
* function overwrites bytes in the packet rather than adding new.
*
* @param[inout] slicer Preallocated slicer struct to use
* @param[in] slicer Preallocated slicer struct to use
*/
void coap_block2_finish(coap_block_slicer_t *slicer);
static inline void coap_block2_finish(coap_block_slicer_t *slicer)
{
coap_block_finish(slicer, COAP_OPT_BLOCK2);
}

/**
* @brief Initialize a block2 slicer struct for writing the payload
Expand All @@ -564,6 +610,18 @@ void coap_block2_finish(coap_block_slicer_t *slicer);
*/
void coap_block2_init(coap_pkt_t *pkt, coap_block_slicer_t *slicer);

/**
* @brief Initialize a block slicer struct from content information
*
* @param[out] slicer slicer struct to initialize
* @param[in] blknum offset from the beginning of content, in terms of
@p blksize byte blocks
* @param[in] blksize size of each block; must be a power of 2 between 16
* and 2 raised to #NANOCOAP_BLOCK_SIZE_EXP_MAX
*/
void coap_block_slicer_init(coap_block_slicer_t *slicer, size_t blknum,
size_t blksize);

/**
* @brief Add a byte array to a block2 reply.
*
Expand Down
44 changes: 33 additions & 11 deletions sys/net/application_layer/nanocoap/nanocoap.c
Original file line number Diff line number Diff line change
Expand Up @@ -710,14 +710,14 @@ 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)
{
unsigned szx = _size2szx(slicer->end - slicer->start);
unsigned blknum = _slicer_blknum(slicer);
coap_block1_t block;

uint32_t blkopt = (blknum << 4) | szx | (more ? 0x8 : 0);
size_t olen = _encode_uint(&blkopt);
coap_block_object_init(&block, _slicer_blknum(slicer),
slicer->end - slicer->start, more);

slicer->opt = buf;
return coap_put_option(buf, lastonum, option, (uint8_t *)&blkopt, olen);

return coap_opt_put_block_object(buf, lastonum, &block, option);
}

size_t coap_opt_put_block_object(uint8_t *buf, uint16_t lastonum,
Expand Down Expand Up @@ -875,6 +875,22 @@ ssize_t coap_opt_finish(coap_pkt_t *pkt, uint16_t flags)
return pkt->payload - (uint8_t *)pkt->hdr;
}

void coap_block_object_init(coap_block1_t *block, size_t blknum, size_t blksize,
int more)
{
block->szx = _size2szx(blksize);
block->blknum = blknum;
block->more = more;
}

void coap_block_slicer_init(coap_block_slicer_t *slicer, size_t blknum,
size_t blksize)
{
slicer->start = blknum * blksize;
slicer->end = slicer->start + blksize;
slicer->cur = 0;
}

void coap_block2_init(coap_pkt_t *pkt, coap_block_slicer_t *slicer)
{
uint32_t blknum;
Expand All @@ -888,12 +904,11 @@ void coap_block2_init(coap_pkt_t *pkt, coap_block_slicer_t *slicer)
szx = NANOCOAP_BLOCK_SIZE_EXP_MAX - 4;
}
}
slicer->start = blknum * coap_szx2size(szx);
slicer->end = slicer->start + coap_szx2size(szx);
slicer->cur = 0;

coap_block_slicer_init(slicer, blknum, coap_szx2size(szx));
}

void coap_block2_finish(coap_block_slicer_t *slicer)
void coap_block_finish(coap_block_slicer_t *slicer, uint16_t option)
{
assert(slicer->opt);

Expand All @@ -902,9 +917,16 @@ void coap_block2_finish(coap_block_slicer_t *slicer)
* it's already in the buffer. So just point past the option. */
uint8_t *pos = slicer->opt + 1;
uint16_t delta = _decode_value(*slicer->opt >> 4, &pos, slicer->opt + 3);
int more = (slicer->cur > slicer->end) ? 1 : 0;

coap_opt_put_block2(slicer->opt, COAP_OPT_BLOCK2 - delta, slicer, more);
/* 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);
size_t olen = _encode_uint(&blkopt);

coap_put_option(slicer->opt, option - delta, option, (uint8_t *)&blkopt, olen);
}

ssize_t coap_block2_build_reply(coap_pkt_t *pkt, unsigned code,
Expand Down

0 comments on commit b5200e9

Please sign in to comment.