1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

net/nanocoap: add function to iterate over options

This commit is contained in:
Ken Bannister 2019-07-15 00:45:05 -04:00
parent 6c8e646b83
commit 4e89741b79
2 changed files with 56 additions and 0 deletions

View File

@ -530,6 +530,38 @@ static inline ssize_t coap_get_uri_query(const coap_pkt_t *pkt, uint8_t *target)
return coap_opt_get_string(pkt, COAP_OPT_URI_QUERY, target,
NANOCOAP_URI_MAX, '&');
}
/**
* @brief Iterate over a packet's options
*
* To start iteration from the first option, set @p init_opt to true. To start
* iteration from a specific option, set @p init_opt to false, set
* @p opt->offset to the offset of the desired option from pkt->hdr, and
* @p opt->opt_num as required. See below for how @p opt->opt_num is modified.
*
* With each invocation, this function returns the length of the option value
* and sets @p value to point to the start of the value. The value for
* @p opt->opt_num is increased by the delta in the option number value over
* the preceding option in the packet. So, @p opt->opt_num is accurate if
* iteration started with the first option. Otherwise, it is useful for
* identification of repeated options. Finally, @p opt->offset is set to the
* offset for any following option, to prepare for the next iteration.
*
* The end of the options is indicated by a -ENOENT return value. In this case
* @p value and @p opt are unchanged from their input values.
*
* @param[in] pkt packet to read from
* @param[in,out] opt option attributes; read on input if @p init_opt
* is false
* @param[out] value start of the option value
* @param[in] init_opt true to retrieve first option; false to retrieve
* option at opt->offset
*
* @return length of option value
* @return -ENOENT if option not found
*/
ssize_t coap_opt_get_next(const coap_pkt_t *pkt, coap_optpos_t *opt,
uint8_t **value, bool init_opt);
/**@}*/

View File

@ -269,6 +269,30 @@ unsigned coap_get_content_type(coap_pkt_t *pkt)
return content_type;
}
ssize_t coap_opt_get_next(const coap_pkt_t *pkt, coap_optpos_t *opt,
uint8_t **value, bool init_opt)
{
if (init_opt) {
opt->opt_num = 0;
opt->offset = coap_get_total_hdr_len(pkt);
}
uint8_t *start = (uint8_t*)pkt->hdr + opt->offset;
/* Find start of option value and value length. */
uint16_t delta;
int len;
start = _parse_option(pkt, start, &delta, &len);
if (!start) {
return -ENOENT;
}
*value = start;
opt->opt_num += delta;
opt->offset = start + len - (uint8_t*)pkt->hdr;
return len;
}
ssize_t coap_opt_get_string(const coap_pkt_t *pkt, uint16_t optnum,
uint8_t *target, size_t max_len, char separator)
{