mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge #19713
19713: nanocoap: clean up coap_iterate_option(), make it public r=benpicco a=benpicco Co-authored-by: Benjamin Valentin <benjamin.valentin@ml-pa.com>
This commit is contained in:
commit
ed3b894389
@ -28,6 +28,7 @@ BOARD_INSUFFICIENT_MEMORY := \
|
||||
stk3200 \
|
||||
stm32f030f4-demo \
|
||||
stm32f0discovery \
|
||||
stm32f7508-dk \
|
||||
stm32g0316-disco \
|
||||
stm32l0538-disco \
|
||||
telosb \
|
||||
|
@ -656,6 +656,21 @@ static inline void coap_hdr_set_type(coap_hdr_t *hdr, unsigned type)
|
||||
*/
|
||||
uint8_t *coap_find_option(coap_pkt_t *pkt, unsigned opt_num);
|
||||
|
||||
/**
|
||||
* @brief Get pointer to an option field, can be called in a loop
|
||||
* if there are multiple options with the same number
|
||||
*
|
||||
* @param[in] pkt packet to work on
|
||||
* @param[in] opt_num the option number to search for
|
||||
* @param[out] opt_pos opaque, must be set to `NULL` on first call
|
||||
* @param[out] opt_len size of the current option data
|
||||
*
|
||||
* @returns pointer to the option data
|
||||
* NULL if option number was not found
|
||||
*/
|
||||
uint8_t *coap_iterate_option(coap_pkt_t *pkt, unsigned opt_num,
|
||||
uint8_t **opt_pos, int *opt_len);
|
||||
|
||||
/**
|
||||
* @brief Get content type from packet
|
||||
*
|
||||
|
@ -281,19 +281,27 @@ int coap_opt_get_uint(coap_pkt_t *pkt, uint16_t opt_num, uint32_t *target)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
uint8_t *coap_iterate_option(coap_pkt_t *pkt, uint8_t **optpos,
|
||||
int *opt_len, int first)
|
||||
uint8_t *coap_iterate_option(coap_pkt_t *pkt, unsigned optnum,
|
||||
uint8_t **opt_pos, int *opt_len)
|
||||
{
|
||||
uint8_t *data_start;
|
||||
|
||||
bool first = false;
|
||||
if (*opt_pos == NULL) {
|
||||
*opt_pos = coap_find_option(pkt, optnum);
|
||||
first = true;
|
||||
if (*opt_pos == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t delta = 0;
|
||||
data_start = _parse_option(pkt, *optpos, &delta, opt_len);
|
||||
data_start = _parse_option(pkt, *opt_pos, &delta, opt_len);
|
||||
if (data_start && (first || !delta)) {
|
||||
*optpos = data_start + *opt_len;
|
||||
*opt_pos = data_start + *opt_len;
|
||||
return data_start;
|
||||
}
|
||||
else {
|
||||
*optpos = NULL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -359,31 +367,35 @@ ssize_t coap_opt_get_string(coap_pkt_t *pkt, uint16_t optnum,
|
||||
{
|
||||
assert(pkt && target && (max_len > 1));
|
||||
|
||||
uint8_t *opt_pos = coap_find_option(pkt, optnum);
|
||||
if (!opt_pos) {
|
||||
uint8_t *opt_pos = NULL;
|
||||
int opt_len;
|
||||
unsigned left = max_len;
|
||||
|
||||
while (1) {
|
||||
uint8_t *part_start = coap_iterate_option(pkt, optnum, &opt_pos, &opt_len);
|
||||
|
||||
if (part_start == NULL) {
|
||||
/* if option was not found still return separator */
|
||||
if (opt_pos == NULL) {
|
||||
*target++ = (uint8_t)separator;
|
||||
--left;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* separator and terminating \0 have to fit */
|
||||
if (left < (unsigned)(opt_len + 2)) {
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
*target++ = (uint8_t)separator;
|
||||
*target = '\0';
|
||||
return 2;
|
||||
memcpy(target, part_start, opt_len);
|
||||
target += opt_len;
|
||||
left -= opt_len + 1;
|
||||
}
|
||||
|
||||
unsigned left = max_len - 1;
|
||||
uint8_t *part_start = NULL;
|
||||
do {
|
||||
int opt_len;
|
||||
part_start = coap_iterate_option(pkt, &opt_pos, &opt_len,
|
||||
(part_start == NULL));
|
||||
if (part_start) {
|
||||
if (left < (unsigned)(opt_len + 1)) {
|
||||
return -ENOSPC;
|
||||
}
|
||||
*target++ = (uint8_t)separator;
|
||||
memcpy(target, part_start, opt_len);
|
||||
target += opt_len;
|
||||
left -= (opt_len + 1);
|
||||
}
|
||||
} while (opt_pos);
|
||||
|
||||
*target = '\0';
|
||||
left--;
|
||||
|
||||
return (int)(max_len - left);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user