Loading...
Searching...
No Matches
base.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024-2026 Carl Seifert
3 * SPDX-FileCopyrightText: 2024-2026 TU Dresden
4 * SPDX-License-Identifier: LGPL-2.1-only
5 */
6
7#pragma once
8
9#include <stdint.h>
10#include <stdbool.h>
11#include <string.h>
12#include <assert.h>
13#include <errno.h>
14#include <sys/types.h>
15
16#include "byteorder.h"
17
20
52
58
59#ifdef __cplusplus
60extern "C" {
61#endif
62
63/* MARK: - Essentials */
71typedef struct {
76 uint8_t* data;
77
81 uint16_t size;
82
88
97typedef struct {
98 /* TODO: OSCORE: read-only due to options stored in two different buffers */
99
104
111
119
127
136static inline void unicoap_options_init(unicoap_options_t* options, uint8_t* storage,
137 size_t capacity)
138{
139 options->entries->data = storage;
140 options->option_count = 0;
141 options->storage_size = 0;
142 options->storage_capacity = capacity;
143}
144
157
164static inline void unicoap_options_clear(unicoap_options_t* options)
165{
166 options->option_count = 0;
167 options->storage_size = 0;
168}
169
170
171/* MARK: - Allocating option buffers */
176#ifndef DOXYGEN
177# define _UNICOAP_OPTIONS_ALLOC(_buf, _name, capacity, _static) \
178 _static uint8_t _buf[capacity]; \
179 _static unicoap_options_t _name = { \
180 .entries = { { .data = _buf } }, \
181 .storage_capacity = capacity, \
182 };
183#endif
184
197#define UNICOAP_OPTIONS_ALLOC(name, capacity) \
198 _UNICOAP_OPTIONS_ALLOC(_CONCAT3(name, _storage, __LINE__), name, capacity,)
199
212#define UNICOAP_OPTIONS_ALLOC_STATIC(name, capacity) \
213 _UNICOAP_OPTIONS_ALLOC(_CONCAT3(name, _storage, __LINE__), name, capacity, static)
214
226#define UNICOAP_OPTIONS_ALLOC_DEFAULT(name) \
227 UNICOAP_OPTIONS_ALLOC(name, CONFIG_UNICOAP_OPTIONS_BUFFER_DEFAULT_CAPACITY)
228
240#define UNICOAP_OPTIONS_ALLOC_STATIC_DEFAULT(name) \
241 UNICOAP_OPTIONS_ALLOC_STATIC(name, CONFIG_UNICOAP_OPTIONS_BUFFER_DEFAULT_CAPACITY)
242
243
244/* MARK: - Option characteristics */
260{
261 return option_number & 1;
262}
263
273{
274 return (option_number & 2) == 0;
275}
276
288{
289 return ((option_number & 0x1e) == 0x1c);
290}
291
303{
304 return ((option_number & 0x1e) != 0x1c);
305}
306
307
308/* MARK: - Tools */
319
332ssize_t unicoap_options_swap_storage(unicoap_options_t* options, uint8_t* destination,
333 size_t capacity);
334
342static inline uint8_t* unicoap_options_data(const unicoap_options_t* options)
343{
344 return options->entries->data;
345}
346
354static inline size_t unicoap_options_size(const unicoap_options_t* options)
355{
356 return options->storage_size;
357}
358
359
360/* MARK: - Auxiliary constants */
366#if !defined(EBADOPT) || defined(DOXYGEN)
367# define EBADOPT 151
368#endif
369
371#if !defined(EPAYLD) || defined(DOXYGEN)
372# define EPAYLD 152
373#endif
374
376#define UNICOAP_UINT24_MAX (0xffffff)
377
379#define UNICOAP_UINT24_SIZE (3)
380
387#define UNICOAP_UINT_MAX (14 + 255 + 0xffff)
389
390/* MARK: - Generic Option Methods - */
397/* MARK: - Repeatable options */
420 const uint8_t* value, size_t value_size);
421
443 const uint8_t* buffer, size_t size, uint8_t separator);
444
465 unicoap_option_number_t number, uint8_t* buffer,
466 size_t capacity, uint8_t separator);
467
483
484/* MARK: - Non-repeatable options */
504 const uint8_t** value);
505
521 uint8_t* dest, size_t capacity);
522
536 const uint8_t* value, size_t value_size);
537
550{
551 /* reuse unicoap_options_remove_all, helps decrease binary size */
552 return unicoap_options_remove_all(options, number);
553}
554
555
556/* MARK: - Enumerating options */
590
600{
601 assert(iterator);
603 assert(options->entries->data);
604 iterator->options = options;
605 iterator->index = 0;
606}
607
623 unicoap_option_number_t* number, const uint8_t** value);
624
641 unicoap_option_number_t number, const uint8_t** value);
642
671 const char* name, size_t length,
672 const char** value);
673
699static inline
701 unicoap_option_number_t number, const char* name,
702 const char** value)
703{
704 return unicoap_options_get_next_query_by_name(iterator, number, name, strlen(name), value);
705}
706
714
724
725/* MARK: - Strings */
746 unicoap_option_number_t number, const char* string,
747 size_t count)
748{
749 return unicoap_options_set(options, number, (uint8_t*)string,
750 ((count > 0) && string) ? count : strlen(string));
751}
752
772 unicoap_option_number_t number, const char* string,
773 size_t count)
774{
775 return unicoap_options_add(options, number, (uint8_t*)string,
776 ((count > 0) && string) ? count : strlen(string));
777}
778
779
780/* MARK: - Unsigned integers */
785#ifndef DOXYGEN
802ssize_t _unicoap_options_get_variable_uint(const unicoap_options_t* options,
803 unicoap_option_number_t number, uint32_t* uint,
804 size_t max_size);
805#endif
806
824static inline ssize_t unicoap_options_get_uint32(const unicoap_options_t* options,
825 unicoap_option_number_t number, uint32_t* uint)
826{
827 return _unicoap_options_get_variable_uint(options, number, uint, sizeof(uint32_t));
828}
829
847static inline ssize_t unicoap_options_get_uint24(const unicoap_options_t* options,
848 unicoap_option_number_t number, uint32_t* uint)
849{
850 return _unicoap_options_get_variable_uint(options, number, uint, UNICOAP_UINT24_SIZE);
851}
852
870static inline ssize_t unicoap_options_get_uint16(const unicoap_options_t* options,
871 unicoap_option_number_t number, uint16_t* uint)
872{
873 uint32_t _uint = 0;
874 int res = _unicoap_options_get_variable_uint(options, number, &_uint, sizeof(uint16_t));
875 *uint = (uint16_t)_uint;
876 return res;
877}
878
897static inline ssize_t unicoap_options_get_uint8(const unicoap_options_t* options,
898 unicoap_option_number_t number, uint8_t* uint)
899{
900 return unicoap_options_copy_value(options, number, uint, sizeof(uint8_t));
901}
902
918 uint32_t value);
919
938 uint32_t value);
941
942
943
944#ifdef __cplusplus
945}
946#endif
947
POSIX.1-2008 compliant version of the assert macro.
#define assert(cond)
abort the program if assertion is false
Definition assert.h:143
Functions to work with different byte orders.
Constants used in CoAP such as option numbers and message codes.
#define CONFIG_UNICOAP_OPTIONS_MAX
Maximum number of options that can be present in a request or response.
Definition config.h:139
void unicoap_options_print_uri_path(const unicoap_options_t *options)
Iterates over all Uri-Path options and prints the resulting path using printf.
static ssize_t unicoap_options_get_uint8(const unicoap_options_t *options, unicoap_option_number_t number, uint8_t *uint)
Retrieves an unsigned option value that takes up at most one bytes.
Definition base.h:897
static ssize_t unicoap_options_get_uint16(const unicoap_options_t *options, unicoap_option_number_t number, uint16_t *uint)
Retrieves an unsigned option value that takes up at most 2 bytes.
Definition base.h:870
ssize_t unicoap_options_copy_values_joined(const unicoap_options_t *options, unicoap_option_number_t number, uint8_t *buffer, size_t capacity, uint8_t separator)
Copies the values of all options with the given number joined by the given separator.
ssize_t unicoap_options_get(const unicoap_options_t *options, unicoap_option_number_t number, const uint8_t **value)
Retrieves the value of the option with given value, if present.
static ssize_t unicoap_options_get_next_query_by_name_string(unicoap_options_iterator_t *iterator, unicoap_option_number_t number, const char *name, const char **value)
Gets the next query option matching a given null-terminated name string, potentially skipping any opt...
Definition base.h:700
void unicoap_options_dump_all(const unicoap_options_t *options)
Iterates and dumps all options using printf
int unicoap_options_remove_all(unicoap_options_t *options, unicoap_option_number_t number)
Removes all options with the given number, if any.
static void unicoap_options_iterator_init(unicoap_options_iterator_t *iterator, unicoap_options_t *options)
Initializes the given iterator structure.
Definition base.h:598
static ssize_t unicoap_options_get_uint24(const unicoap_options_t *options, unicoap_option_number_t number, uint32_t *uint)
Retrieves an unsigned option value that takes up at most 3 bytes.
Definition base.h:847
ssize_t unicoap_options_copy_value(const unicoap_options_t *options, unicoap_option_number_t number, uint8_t *dest, size_t capacity)
Copies the value of the option with given value, if present, into a buffer.
int unicoap_options_add(unicoap_options_t *options, unicoap_option_number_t number, const uint8_t *value, size_t value_size)
Adds a repeatable option with the given value.
ssize_t unicoap_options_get_next(unicoap_options_iterator_t *iterator, unicoap_option_number_t *number, const uint8_t **value)
Gets the next option provided by the given iterator.
int unicoap_options_set(unicoap_options_t *options, unicoap_option_number_t number, const uint8_t *value, size_t value_size)
Sets the option with the given number.
int unicoap_options_set_uint(unicoap_options_t *options, unicoap_option_number_t number, uint32_t value)
Sets the option with the given number to the unsigned integer value passed.
ssize_t unicoap_options_get_next_by_number(unicoap_options_iterator_t *iterator, unicoap_option_number_t number, const uint8_t **value)
Gets the next option with the given number, potentially skipping any options in between.
static int unicoap_options_remove(unicoap_options_t *options, unicoap_option_number_t number)
Removes option with the given number, if present.
Definition base.h:549
static int unicoap_options_add_string(unicoap_options_t *options, unicoap_option_number_t number, const char *string, size_t count)
Adds a repeatable option with the given string value.
Definition base.h:771
int unicoap_options_add_uint(unicoap_options_t *options, unicoap_option_number_t number, uint32_t value)
Adds a repeatable option with the given unsigned integer value.
static int unicoap_options_set_string(unicoap_options_t *options, unicoap_option_number_t number, const char *string, size_t count)
Sets a non-repeatable option to the given string value.
Definition base.h:745
static ssize_t unicoap_options_get_uint32(const unicoap_options_t *options, unicoap_option_number_t number, uint32_t *uint)
Retrieves an unsigned option value that takes up at most 4 bytes.
Definition base.h:824
int unicoap_options_add_values_joined(unicoap_options_t *options, unicoap_option_number_t number, const uint8_t *buffer, size_t size, uint8_t separator)
Splits the given value into separate values and adds them as option values.
ssize_t unicoap_options_get_next_query_by_name(unicoap_options_iterator_t *iterator, unicoap_option_number_t number, const char *name, size_t length, const char **value)
Gets the next query option matching the given name, potentially skipping any options in between.
unicoap_option_number_t
CoAP option number.
Definition constants.h:414
#define UNICOAP_UINT24_SIZE
Size in bytes of number representable with 24 bits (3 bytes)
Definition base.h:379
static uint8_t * unicoap_options_data(const unicoap_options_t *options)
Retrieves storage buffer.
Definition base.h:342
static void unicoap_options_clear(unicoap_options_t *options)
Removes all options.
Definition base.h:164
static size_t unicoap_options_size(const unicoap_options_t *options)
Retrieves total size of options in buffer.
Definition base.h:354
static bool unicoap_option_is_no_cache_key(unicoap_option_number_t option_number)
Determines whether the given option is not intended to be part of the cache key.
Definition base.h:287
static bool unicoap_option_is_critical(unicoap_option_number_t option_number)
Determines whether the given option is considered critical.
Definition base.h:259
static void unicoap_options_init(unicoap_options_t *options, uint8_t *storage, size_t capacity)
Initializes the given options structure.
Definition base.h:136
ssize_t unicoap_options_swap_storage(unicoap_options_t *options, uint8_t *destination, size_t capacity)
Copies storage and adjusts options struct.
static bool unicoap_option_is_safe_to_forward(unicoap_option_number_t option_number)
Determines whether the given option is safe to forward.
Definition base.h:272
bool unicoap_options_contains(const unicoap_options_t *options, unicoap_option_number_t number)
Determines whether the given options container has one or more options with the given number.
static bool unicoap_option_is_cache_key(unicoap_option_number_t option_number)
Determines whether the given option is intended to be part of the cache key.
Definition base.h:302
const char * unicoap_string_from_option_number(unicoap_option_number_t number)
Returns label of option corresponding to the given number.
Helper struct for options parser.
Definition base.h:71
uint16_t size
Number of bytes this option is comprised of.
Definition base.h:81
uint8_t * data
Pointer into options storage where this option starts.
Definition base.h:76
unicoap_option_number_t number
Option number.
Definition base.h:86
The iterator you use to retrieve option values in-order.
Definition base.h:579
size_t index
Current option's index.
Definition base.h:588
unicoap_options_t * options
Options.
Definition base.h:583
CoAP options container.
Definition base.h:97
size_t storage_size
Current size of encoded options.
Definition base.h:103
size_t option_count
Number of options present.
Definition base.h:125
unicoap_option_entry_t entries[CONFIG_UNICOAP_OPTIONS_MAX]
Helper array used to encode and decode options into options storage.
Definition base.h:118
size_t storage_capacity
Available capacity in options storage buffer.
Definition base.h:110
Utility macros for unicoap