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