mirror of
https://github.com/obgm/libcoap.git
synced 2026-11-05 17:32:54 +03:00
Fixed handling of zero-length options in COAP_OPT_BLOCK_LAST macro.
The macro did not respect zero-length option values hence a pointer to the option byte itself was returned. This macro now returns NULL for zero-length option values. Macros and functions that use this macro have been updated accordingly. COAP_OPT_BLOCK_NUM has been replaced by the function coap_opt_block_num().
This commit is contained in:
1 parent
a391c9e9cb
commit
b5fe35646b
2 files changed
+36
-20
No files matched your search
@@ -18,6 +18,25 @@
|
||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
#ifndef WITHOUT_BLOCK
|
||||
unsigned int
|
||||
coap_opt_block_num(const coap_opt_t *block_opt) {
|
||||
unsigned int num = 0;
|
||||
unsigned short len;
|
||||
|
||||
len = coap_opt_length(block_opt);
|
||||
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len > 1) {
|
||||
num = coap_decode_var_bytes(COAP_OPT_VALUE(block_opt),
|
||||
COAP_OPT_LENGTH(block_opt) - 1);
|
||||
}
|
||||
|
||||
return (num << 4) | ((*COAP_OPT_BLOCK_LAST(block_opt) & 0xF0) >> 4);
|
||||
}
|
||||
|
||||
int
|
||||
coap_get_block(coap_pdu_t *pdu, unsigned short type, coap_block_t *block) {
|
||||
coap_opt_iterator_t opt_iter;
|
||||
@@ -30,8 +49,7 @@ coap_get_block(coap_pdu_t *pdu, unsigned short type, coap_block_t *block) {
|
||||
block->szx = COAP_OPT_BLOCK_SZX(option);
|
||||
if (COAP_OPT_BLOCK_MORE(option))
|
||||
block->m = 1;
|
||||
block->num = COAP_OPT_BLOCK_NUM(option);
|
||||
|
||||
block->num = coap_opt_block_num(option);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,29 +40,27 @@ typedef struct {
|
||||
unsigned int szx:3; /**< block size */
|
||||
} coap_block_t;
|
||||
|
||||
/** Returns the value of the least significant byte of a Block option @p opt. */
|
||||
#define COAP_OPT_BLOCK_LAST(opt) ( COAP_OPT_VALUE(opt) + (COAP_OPT_LENGTH(opt) - 1) )
|
||||
/**
|
||||
* Returns the value of the least significant byte of a Block option @p opt.
|
||||
* For zero-length options (i.e. num == m == szx == 0), COAP_OPT_BLOCK_LAST
|
||||
* returns @c NULL.
|
||||
*/
|
||||
#define COAP_OPT_BLOCK_LAST(opt) \
|
||||
(COAP_OPT_LENGTH(opt) ? (COAP_OPT_VALUE(opt) + (COAP_OPT_LENGTH(opt)-1)) : 0)
|
||||
|
||||
/** Returns the value of the More-bit of a Block option @p opt. */
|
||||
#define COAP_OPT_BLOCK_MORE(opt) ( *COAP_OPT_BLOCK_LAST(opt) & 0x08 )
|
||||
#define COAP_OPT_BLOCK_MORE(opt) \
|
||||
(COAP_OPT_LENGTH(opt) ? (*COAP_OPT_BLOCK_LAST(opt) & 0x08) : 0)
|
||||
|
||||
/** Returns the value of the SZX-field of a Block option @p opt. */
|
||||
#define COAP_OPT_BLOCK_SZX(opt) ( *COAP_OPT_BLOCK_LAST(opt) & 0x07 )
|
||||
#define COAP_OPT_BLOCK_SZX(opt) \
|
||||
(COAP_OPT_LENGTH(opt) ? (*COAP_OPT_BLOCK_LAST(opt) & 0x07) : 0)
|
||||
|
||||
/** Implementation of COAP_OPT_BLOCK_NUM */
|
||||
static inline unsigned int
|
||||
_coap_block_num_impl(const coap_opt_t *block_opt) {
|
||||
unsigned int num = 0;
|
||||
|
||||
if (COAP_OPT_LENGTH(block_opt) > 1)
|
||||
num = coap_decode_var_bytes(COAP_OPT_VALUE(block_opt),
|
||||
COAP_OPT_LENGTH(block_opt) - 1);
|
||||
|
||||
return (num << 4) | ((*COAP_OPT_BLOCK_LAST(block_opt) & 0xF0) >> 4);
|
||||
}
|
||||
|
||||
/** Returns the value of field @c num in the given block option @p Block. */
|
||||
#define COAP_OPT_BLOCK_NUM(Block) _coap_block_num_impl(Block)
|
||||
/**
|
||||
* Returns the value of field @c num in the given block option @p
|
||||
* block_opt.
|
||||
*/
|
||||
unsigned int coap_opt_block_num(const coap_opt_t *block_opt);
|
||||
|
||||
/**
|
||||
* Checks if more than @p num blocks are required to deliver @p data_len
|
||||
|
||||
Reference in new issue
Block a user