mirror of
https://github.com/obgm/libcoap.git
synced 2026-11-01 15:35:46 +03:00
93 lines
2.1 KiB
C
93 lines
2.1 KiB
C
/*
|
|
* option.c -- helpers for handling options in CoAP PDUs
|
|
*
|
|
* Copyright (C) 2010,2011 Olaf Bergmann <bergmann@tzi.org>
|
|
*
|
|
* This file is part of the CoAP library libcoap. Please see
|
|
* README for terms of use.
|
|
*/
|
|
|
|
|
|
#include "config.h"
|
|
|
|
#if defined(HAVE_ASSERT_H) && !defined(assert)
|
|
# include <assert.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "option.h"
|
|
|
|
|
|
const coap_opt_filter_t COAP_OPT_ALL =
|
|
{ 0xff, 0xff, 0xff }; /* must be sizeof(coap_opt_filter_t) */
|
|
|
|
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;
|
|
}
|
|
|
|
#define IS_EMPTY_NOOP(Type,Option) \
|
|
((Type) % COAP_OPTION_NOOP == 0 && COAP_OPT_LENGTH(Option) == 0)
|
|
|
|
#define opt_finished(oi) ((oi)->optcnt == COAP_OPT_LONG \
|
|
? ((oi)->option && *((oi)->option) == COAP_OPT_END) \
|
|
: (oi->n > (oi)->optcnt))
|
|
|
|
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_t *
|
|
coap_check_option(coap_pdu_t *pdu, unsigned char type,
|
|
coap_opt_iterator_t *oi) {
|
|
coap_opt_filter_t f;
|
|
|
|
memset(f, 0, sizeof(coap_opt_filter_t));
|
|
coap_option_setb(f, type);
|
|
|
|
coap_option_iterator_init(pdu, oi, f);
|
|
|
|
coap_option_next(oi);
|
|
|
|
return oi->option && oi->type == type ? oi->option : NULL;
|
|
}
|