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:
Olaf Bergmann committed 2014-02-04 17:50:35 +01:00
1 parent a391c9e9cb
commit b5fe35646b
2 files changed
+36 -20

No files matched your search

+20 -2
View File
@@ -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;
}
+16 -18
View File
@@ -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