1 /*
2 * option.h -- helpers for handling options in CoAP PDUs
3 *
4 * Copyright (C) 2010-2013 Olaf Bergmann <bergmann@tzi.org>
5 *
6 * This file is part of the CoAP library libcoap. Please see README for terms
7 * of use.
8 */
9
10 /**
11 * @file option.h
12 * @brief Helpers for handling options in CoAP PDUs
13 */
14
15 #ifndef _COAP_OPTION_H_
16 #define _COAP_OPTION_H_
17
18 #include "bits.h"
19 #include "pdu.h"
20
21 /**
22 * Use byte-oriented access methods here because sliding a complex struct
23 * coap_opt_t over the data buffer may cause bus error on certain platforms.
24 */
25 typedef unsigned char coap_opt_t;
26 #define PCHAR(p) ((coap_opt_t *)(p))
27
28 /** Representation of CoAP options. */
29 typedef struct {
30 unsigned short delta;
31 size_t length;
32 unsigned char *value;
33 } coap_option_t;
34
35 /**
36 * Parses the option pointed to by @p opt into @p result. This function returns
37 * the number of bytes that have been parsed, or @c 0 on error. An error is
38 * signaled when illegal delta or length values are encountered or when option
39 * parsing would result in reading past the option (i.e. beyond opt + length).
40 *
41 * @param opt The beginning of the option to parse.
42 * @param length The maximum length of @p opt.
43 * @param result A pointer to the coap_option_t structure that is filled with
44 * actual values iff coap_opt_parse() > 0.
45 * @return The number of bytes parsed or @c 0 on error.
46 */
47 size_t coap_opt_parse(const coap_opt_t *opt,
48 size_t length,
49 coap_option_t *result);
50
51 /**
52 * Returns the size of the given option, taking into account a possible option
53 * jump.
54 *
55 * @param opt An option jump or the beginning of the option.
56 * @return The number of bytes between @p opt and the end of the option
57 * starting at @p opt. In case of an error, this function returns
58 * @c 0 as options need at least one byte storage space.
59 */
60 size_t coap_opt_size(const coap_opt_t *opt);
61
62 /** @deprecated { Use coap_opt_size() instead. } */
63 #define COAP_OPT_SIZE(opt) coap_opt_size(opt)
64
65 /**
66 * Calculates the beginning of the PDU's option section.
67 *
68 * @param pdu The PDU containing the options.
69 * @return A pointer to the first option if available, or @c NULL otherwise.
70 */
71 coap_opt_t *options_start(coap_pdu_t *pdu);
72
73 /**
74 * Interprets @p opt as pointer to a CoAP option and advances to
75 * the next byte past this option.
76 * @hideinitializer
77 */
78 #define options_next(opt) \
79 ((coap_opt_t *)((unsigned char *)(opt) + COAP_OPT_SIZE(opt)))
80
81 /**
82 * @defgroup opt_filter Option Filters
83 * @{
84 */
85
86 /**
87 * The number of option types below 256 that can be stored in an
88 * option filter. COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be
89 * at most 16. Each coap_option_filter_t object reserves
90 * ((COAP_OPT_FILTER_SHORT + 1) / 2) * 2 bytes for short options.
91 */
92 #define COAP_OPT_FILTER_SHORT 6
93
94 /**
95 * The number of option types above 255 that can be stored in an
96 * option filter. COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be
97 * at most 16. Each coap_option_filter_t object reserves
98 * COAP_OPT_FILTER_LONG * 2 bytes for short options.
99 */
100 #define COAP_OPT_FILTER_LONG 2
101
102 /* Ensure that COAP_OPT_FILTER_SHORT and COAP_OPT_FILTER_LONG are set
103 * correctly. */
104 #if (COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG > 16)
105 #error COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG must be less or equal 16
106 #endif /* (COAP_OPT_FILTER_SHORT + COAP_OPT_FILTER_LONG > 16) */
107
108 /** The number of elements in coap_opt_filter_t. */
109 #define COAP_OPT_FILTER_SIZE \
110 (((COAP_OPT_FILTER_SHORT + 1) >> 1) + COAP_OPT_FILTER_LONG) +1
111
112 /**
113 * Fixed-size vector we use for option filtering. It is large enough
114 * to hold COAP_OPT_FILTER_SHORT entries with an option number between
115 * 0 and 255, and COAP_OPT_FILTER_LONG entries with an option number
116 * between 256 and 65535. Its internal structure is
117 *
118 * @code
119 struct {
120 uint16_t mask;
121 uint16_t long_opts[COAP_OPT_FILTER_LONG];
122 uint8_t short_opts[COAP_OPT_FILTER_SHORT];
123 }
124 * @endcode
125 *
126 * The first element contains a bit vector that indicates which fields
127 * in the remaining array are used. The first COAP_OPT_FILTER_LONG
128 * bits correspond to the long option types that are stored in the
129 * elements from index 1 to COAP_OPT_FILTER_LONG. The next
130 * COAP_OPT_FILTER_SHORT bits correspond to the short option types
131 * that are stored in the elements from index COAP_OPT_FILTER_LONG + 1
132 * to COAP_OPT_FILTER_LONG + COAP_OPT_FILTER_SHORT. The latter
133 * elements are treated as bytes.
134 */
135 typedef uint16_t coap_opt_filter_t[COAP_OPT_FILTER_SIZE];
136
137 /** Pre-defined filter that includes all options. */
138 #define COAP_OPT_ALL NULL
139
140 /**
141 * Clears filter @p f.
142 *
143 * @param f The filter to clear.
144 */
145 static inline void
coap_option_filter_clear(coap_opt_filter_t f)146 coap_option_filter_clear(coap_opt_filter_t f) {
147 memset(f, 0, sizeof(coap_opt_filter_t));
148 }
149
150 /**
151 * Sets the corresponding entry for @p type in @p filter. This
152 * function returns @c 1 if bit was set or @c 0 on error (i.e. when
153 * the given type does not fit in the filter).
154 *
155 * @param filter The filter object to change.
156 * @param type The type for which the bit should be set.
157 *
158 * @return @c 1 if bit was set, @c 0 otherwise.
159 */
160 int coap_option_filter_set(coap_opt_filter_t filter, unsigned short type);
161
162 /**
163 * Clears the corresponding entry for @p type in @p filter. This
164 * function returns @c 1 if bit was set or @c 0 on error (i.e. when
165 * the given type does not fit in the filter).
166 *
167 * @param filter The filter object to change.
168 * @param type The type that should be cleared from the filter.
169 *
170 * @return @c 1 if bit was set, @c 0 otherwise.
171 */
172 int coap_option_filter_unset(coap_opt_filter_t filter, unsigned short type);
173
174 /**
175 * Checks if @p type is contained in @p filter. This function returns
176 * @c 1 if found, @c 0 if not, or @c -1 on error (i.e. when the given
177 * type does not fit in the filter).
178 *
179 * @param filter The filter object to search.
180 * @param type The type to search for.
181 *
182 * @return @c 1 if @p type was found, @c 0 otherwise, or @c -1 on error.
183 */
184 int coap_option_filter_get(const coap_opt_filter_t filter, unsigned short type);
185
186 /**
187 * Sets the corresponding bit for @p type in @p filter. This function returns @c
188 * 1 if bit was set or @c -1 on error (i.e. when the given type does not fit in
189 * the filter).
190 *
191 * @deprecated Use coap_option_filter_set() instead.
192 *
193 * @param filter The filter object to change.
194 * @param type The type for which the bit should be set.
195 *
196 * @return @c 1 if bit was set, @c -1 otherwise.
197 */
198 inline static int
coap_option_setb(coap_opt_filter_t filter,unsigned short type)199 coap_option_setb(coap_opt_filter_t filter, unsigned short type) {
200 return coap_option_filter_set(filter, type) ? 1 : -1;
201 }
202
203 /**
204 * Clears the corresponding bit for @p type in @p filter. This function returns
205 * @c 1 if bit was cleared or @c -1 on error (i.e. when the given type does not
206 * fit in the filter).
207 *
208 * @deprecated Use coap_option_filter_unset() instead.
209 *
210 * @param filter The filter object to change.
211 * @param type The type for which the bit should be cleared.
212 *
213 * @return @c 1 if bit was set, @c -1 otherwise.
214 */
215 inline static int
coap_option_clrb(coap_opt_filter_t filter,unsigned short type)216 coap_option_clrb(coap_opt_filter_t filter, unsigned short type) {
217 return coap_option_filter_unset(filter, type) ? 1 : -1;
218 }
219
220 /**
221 * Gets the corresponding bit for @p type in @p filter. This function returns @c
222 * 1 if the bit is set @c 0 if not, or @c -1 on error (i.e. when the given type
223 * does not fit in the filter).
224 *
225 * @deprecated Use coap_option_filter_get() instead.
226 *
227 * @param filter The filter object to read bit from.
228 * @param type The type for which the bit should be read.
229 *
230 * @return @c 1 if bit was set, @c 0 if not, @c -1 on error.
231 */
232 inline static int
coap_option_getb(const coap_opt_filter_t filter,unsigned short type)233 coap_option_getb(const coap_opt_filter_t filter, unsigned short type) {
234 return coap_option_filter_get(filter, type);
235 }
236
237 /**
238 * Iterator to run through PDU options. This object must be
239 * initialized with coap_option_iterator_init(). Call
240 * coap_option_next() to walk through the list of options until
241 * coap_option_next() returns @c NULL.
242 *
243 * @code
244 * coap_opt_t *option;
245 * coap_opt_iterator_t opt_iter;
246 * coap_option_iterator_init(pdu, &opt_iter, COAP_OPT_ALL);
247 *
248 * while ((option = coap_option_next(&opt_iter))) {
249 * ... do something with option ...
250 * }
251 * @endcode
252 */
253 typedef struct {
254 size_t length; /**< remaining length of PDU */
255 unsigned short type; /**< decoded option type */
256 unsigned int bad:1; /**< iterator object is ok if not set */
257 unsigned int filtered:1; /**< denotes whether or not filter is used */
258 coap_opt_t *next_option; /**< pointer to the unparsed next option */
259 coap_opt_filter_t filter; /**< option filter */
260 } coap_opt_iterator_t;
261
262 /**
263 * Initializes the given option iterator @p oi to point to the beginning of the
264 * @p pdu's option list. This function returns @p oi on success, @c NULL
265 * otherwise (i.e. when no options exist). Note that a length check on the
266 * option list must be performed before coap_option_iterator_init() is called.
267 *
268 * @param pdu The PDU the options of which should be walked through.
269 * @param oi An iterator object that will be initilized.
270 * @param filter An optional option type filter.
271 * With @p type != @c COAP_OPT_ALL, coap_option_next()
272 * will return only options matching this bitmask.
273 * Fence-post options @c 14, @c 28, @c 42, ... are always
274 * skipped.
275 *
276 * @return The iterator object @p oi on success, @c NULL otherwise.
277 */
278 coap_opt_iterator_t *coap_option_iterator_init(coap_pdu_t *pdu,
279 coap_opt_iterator_t *oi,
280 const coap_opt_filter_t filter);
281
282 /**
283 * Updates the iterator @p oi to point to the next option. This function returns
284 * a pointer to that option or @c NULL if no more options exist. The contents of
285 * @p oi will be updated. In particular, @c oi->n specifies the current option's
286 * ordinal number (counted from @c 1), @c oi->type is the option's type code,
287 * and @c oi->option points to the beginning of the current option itself. When
288 * advanced past the last option, @c oi->option will be @c NULL.
289 *
290 * Note that options are skipped whose corresponding bits in the filter
291 * specified with coap_option_iterator_init() are @c 0. Options with type codes
292 * that do not fit in this filter hence will always be returned.
293 *
294 * @param oi The option iterator to update.
295 *
296 * @return The next option or @c NULL if no more options exist.
297 */
298 coap_opt_t *coap_option_next(coap_opt_iterator_t *oi);
299
300 /**
301 * Retrieves the first option of type @p type from @p pdu. @p oi must point to a
302 * coap_opt_iterator_t object that will be initialized by this function to
303 * filter only options with code @p type. This function returns the first option
304 * with this type, or @c NULL if not found.
305 *
306 * @param pdu The PDU to parse for options.
307 * @param type The option type code to search for.
308 * @param oi An iterator object to use.
309 *
310 * @return A pointer to the first option of type @p type, or @c NULL if
311 * not found.
312 */
313 coap_opt_t *coap_check_option(coap_pdu_t *pdu,
314 unsigned short type,
315 coap_opt_iterator_t *oi);
316
317 /**
318 * Encodes the given delta and length values into @p opt. This function returns
319 * the number of bytes that were required to encode @p delta and @p length or @c
320 * 0 on error. Note that the result indicates by how many bytes @p opt must be
321 * advanced to encode the option value.
322 *
323 * @param opt The option buffer space where @p delta and @p length are
324 * written.
325 * @param maxlen The maximum length of @p opt.
326 * @param delta The actual delta value to encode.
327 * @param length The actual length value to encode.
328 *
329 * @return The number of bytes used or @c 0 on error.
330 */
331 size_t coap_opt_setheader(coap_opt_t *opt,
332 size_t maxlen,
333 unsigned short delta,
334 size_t length);
335
336 /**
337 * Encodes option with given @p delta into @p opt. This function returns the
338 * number of bytes written to @p opt or @c 0 on error. This happens especially
339 * when @p opt does not provide sufficient space to store the option value,
340 * delta, and option jumps when required.
341 *
342 * @param opt The option buffer space where @p val is written.
343 * @param n Maximum length of @p opt.
344 * @param delta The option delta.
345 * @param val The option value to copy into @p opt.
346 * @param length The actual length of @p val.
347 *
348 * @return The number of bytes that have been written to @p opt or @c 0 on
349 * error. The return value will always be less than @p n.
350 */
351 size_t coap_opt_encode(coap_opt_t *opt,
352 size_t n,
353 unsigned short delta,
354 const unsigned char *val,
355 size_t length);
356
357 /**
358 * Decodes the delta value of the next option. This function returns the number
359 * of bytes read or @c 0 on error. The caller of this function must ensure that
360 * it does not read over the boundaries of @p opt (e.g. by calling
361 * coap_opt_check_delta().
362 *
363 * @param opt The option to examine.
364 *
365 * @return The number of bytes read or @c 0 on error.
366 */
367 unsigned short coap_opt_delta(const coap_opt_t *opt);
368
369 /** @deprecated { Use coap_opt_delta() instead. } */
370 #define COAP_OPT_DELTA(opt) coap_opt_delta(opt)
371
372 /** @deprecated { Use coap_opt_encode() instead. } */
373 #define COAP_OPT_SETDELTA(opt,val) \
374 coap_opt_encode((opt), COAP_MAX_PDU_SIZE, (val), NULL, 0)
375
376 /**
377 * Returns the length of the given option. @p opt must point to an option jump
378 * or the beginning of the option. This function returns @c 0 when @p opt is not
379 * an option or the actual length of @p opt (which can be @c 0 as well).
380 *
381 * @note {The rationale for using @c 0 in case of an error is that in most
382 * contexts, the result of this function is used to skip the next
383 * coap_opt_length() bytes.}
384 *
385 * @param opt The option whose length should be returned.
386 *
387 * @return The option's length or @c 0 when undefined.
388 */
389 unsigned short coap_opt_length(const coap_opt_t *opt);
390
391 /** @deprecated { Use coap_opt_length() instead. } */
392 #define COAP_OPT_LENGTH(opt) coap_opt_length(opt)
393
394 /**
395 * Returns a pointer to the value of the given option. @p opt must point to an
396 * option jump or the beginning of the option. This function returns @c NULL if
397 * @p opt is not a valid option.
398 *
399 * @param opt The option whose value should be returned.
400 *
401 * @return A pointer to the option value or @c NULL on error.
402 */
403 unsigned char *coap_opt_value(coap_opt_t *opt);
404
405 /** @deprecated { Use coap_opt_value() instead. } */
406 #define COAP_OPT_VALUE(opt) coap_opt_value((coap_opt_t *)opt)
407
408 /** @} */
409
410 #endif /* _OPTION_H_ */
411