coap_opt_t * coap_option_next(coap_opt_iterator_t *oi) { assert(oi); if (opt_finished(oi)) return NULL; /* proceed to next option */ if (oi->n++) { oi->option = options_next(oi->option); oi->type += COAP_OPT_DELTA(oi->option); } /* Skip subsequent options if it is an empty no-op (used for * fence-posting) or the filter bit is not set. */ while (!opt_finished(oi) && (IS_EMPTY_NOOP(oi->type, oi->option) || coap_option_getb(oi->filter, oi->type) == 0)) { oi->n++; oi->option = options_next(oi->option); if (opt_finished(oi)) break; oi->type += COAP_OPT_DELTA(oi->option); } return opt_finished(oi) ? NULL : oi->option; }
coap_opt_iterator_t * coap_option_iterator_init(coap_pdu_t *pdu, coap_opt_iterator_t *oi, const coap_opt_filter_t filter) { assert(pdu); assert(oi); memset(oi, 0, sizeof(coap_opt_iterator_t)); if (pdu->hdr->optcnt) { oi->optcnt = pdu->hdr->optcnt; oi->option = options_start(pdu); oi->type = COAP_OPT_DELTA(oi->option); memcpy(oi->filter, filter, sizeof(coap_opt_filter_t)); return oi; } return NULL; }
void for_each_option(coap_pdu_t *pdu, void (*f)(coap_opt_t *, unsigned char, unsigned int, const unsigned char *) ) { unsigned char cnt; coap_opt_t *opt; unsigned char opt_code = 0; if (! pdu ) return; opt = options_start( pdu ); for ( cnt = pdu->hdr->optcnt; cnt; --cnt ) { opt_code += COAP_OPT_DELTA(*opt); f ( opt, opt_code, COAP_OPT_LENGTH(*opt), COAP_OPT_VALUE(*opt) ); opt = (coap_opt_t *)( (unsigned char *)opt + COAP_OPT_SIZE(*opt) ); } }