1 /*
2  * Copyright (c) 2011-2014, Wind River Systems, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief Misc utilities
10  *
11  * Misc utilities usable by the kernel and application code.
12  */
13 
14 #ifndef _BLE_MESH_UTIL_H_
15 #define _BLE_MESH_UTIL_H_
16 
17 #include <stddef.h>
18 #include "esp_bit_defs.h"
19 #include "mesh_types.h"
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 /* Helper to pass a int as a pointer or vice-versa.
26  * Those are available for 32 bits architectures:
27  */
28 #ifndef POINTER_TO_UINT
29 #define POINTER_TO_UINT(x) ((uint32_t)  (x))
30 #endif
31 #ifndef UINT_TO_POINTER
32 #define UINT_TO_POINTER(x) ((void *) (x))
33 #endif
34 #ifndef POINTER_TO_INT
35 #define POINTER_TO_INT(x)  ((int32_t)  (x))
36 #endif
37 #ifndef INT_TO_POINTER
38 #define INT_TO_POINTER(x)  ((void *) (x))
39 #endif
40 
41 /* Evaluates to 0 if cond is true-ish; compile error otherwise */
42 #ifndef ZERO_OR_COMPILE_ERROR
43 #define ZERO_OR_COMPILE_ERROR(cond) ((int) sizeof(char[1 - 2 * !(cond)]) - 1)
44 #endif
45 
46 /* Evaluates to 0 if array is an array; compile error if not array (e.g.
47  * pointer)
48  */
49 #ifndef IS_ARRAY
50 #define IS_ARRAY(array) \
51         ZERO_OR_COMPILE_ERROR( \
52         !__builtin_types_compatible_p(__typeof__(array), \
53             __typeof__(&(array)[0])))
54 #endif
55 
56 /* Evaluates to number of elements in an array; compile error if not
57  * an array (e.g. pointer)
58  */
59 #ifndef ARRAY_SIZE
60 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
61 #endif
62 
63 /* Evaluates to 1 if ptr is part of array, 0 otherwise; compile error if
64  * "array" argument is not an array (e.g. "ptr" and "array" mixed up)
65  */
66 #ifndef PART_OF_ARRAY
67 #define PART_OF_ARRAY(array, ptr) \
68         ((ptr) && ((ptr) >= &array[0] && (ptr) < &array[ARRAY_SIZE(array)]))
69 #endif
70 
71 #ifndef CONTAINER_OF
72 #define CONTAINER_OF(ptr, type, field) \
73         ((type *)(((char *)(ptr)) - offsetof(type, field)))
74 #endif
75 
76 /* round "x" up/down to next multiple of "align" (which must be a power of 2) */
77 #ifndef ROUND_UP
78 #define ROUND_UP(x, align) \
79         (((unsigned long)(x) + ((unsigned long)align - 1)) & \
80         ~((unsigned long)align - 1))
81 #endif
82 
83 #ifndef ROUND_DOWN
84 #define ROUND_DOWN(x, align) ((unsigned long)(x) & ~((unsigned long)align - 1))
85 #endif
86 
87 /* round up/down to the next word boundary */
88 #ifndef WB_UP
89 #define WB_UP(x) ROUND_UP(x, sizeof(void *))
90 #endif
91 
92 #ifndef WB_DN
93 #define WB_DN(x) ROUND_DOWN(x, sizeof(void *))
94 #endif
95 
96 #ifndef ceiling_fraction
97 #define ceiling_fraction(numerator, divider) \
98         (((numerator) + ((divider) - 1)) / (divider))
99 #endif
100 
101 #ifndef CHECKIF
102 #define CHECKIF(expr)   if (expr)
103 #endif
104 
105 /** @brief Return larger value of two provided expressions.
106  *
107  * @note Arguments are evaluated twice. See Z_MAX for GCC only, single
108  * evaluation version.
109  */
110 #ifndef MAX
111 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
112 #endif
113 
114 /** @brief Return smaller value of two provided expressions.
115  *
116  * @note Arguments are evaluated twice. See Z_MIN for GCC only, single
117  * evaluation version.
118  */
119 #ifndef MIN
120 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
121 #endif
122 
123 #ifndef BIT
124 #define BIT(n)      (1UL << (n))
125 #endif
126 
127 #ifndef BIT_MASK
128 #define BIT_MASK(n) (BIT(n) - 1)
129 #endif
130 
131 /**
132  * @brief Check for macro definition in compiler-visible expressions
133  *
134  * This trick was pioneered in Linux as the config_enabled() macro.
135  * The madness has the effect of taking a macro value that may be
136  * defined to "1" (e.g. CONFIG_MYFEATURE), or may not be defined at
137  * all and turning it into a literal expression that can be used at
138  * "runtime".  That is, it works similarly to
139  * "defined(CONFIG_MYFEATURE)" does except that it is an expansion
140  * that can exist in a standard expression and be seen by the compiler
141  * and optimizer.  Thus much ifdef usage can be replaced with cleaner
142  * expressions like:
143  *
144  *     if (IS_ENABLED(CONFIG_MYFEATURE))
145  *             myfeature_enable();
146  *
147  * INTERNAL
148  * First pass just to expand any existing macros, we need the macro
149  * value to be e.g. a literal "1" at expansion time in the next macro,
150  * not "(1)", etc...  Standard recursive expansion does not work.
151  */
152 #define IS_ENABLED(config_macro) Z_IS_ENABLED1(config_macro)
153 
154 /* Now stick on a "_XXXX" prefix, it will now be "_XXXX1" if config_macro
155  * is "1", or just "_XXXX" if it's undefined.
156  *   ENABLED:   Z_IS_ENABLED2(_XXXX1)
157  *   DISABLED   Z_IS_ENABLED2(_XXXX)
158  */
159 #define Z_IS_ENABLED1(config_macro) Z_IS_ENABLED2(_XXXX##config_macro)
160 
161 /* Here's the core trick, we map "_XXXX1" to "_YYYY," (i.e. a string
162  * with a trailing comma), so it has the effect of making this a
163  * two-argument tuple to the preprocessor only in the case where the
164  * value is defined to "1"
165  *   ENABLED:    _YYYY,    <--- note comma!
166  *   DISABLED:   _XXXX
167  */
168 #define _XXXX1 _YYYY,
169 
170 /* Then we append an extra argument to fool the gcc preprocessor into
171  * accepting it as a varargs macro.
172  *                         arg1   arg2  arg3
173  *   ENABLED:   Z_IS_ENABLED3(_YYYY,    1,    0)
174  *   DISABLED   Z_IS_ENABLED3(_XXXX 1,  0)
175  */
176 #define Z_IS_ENABLED2(one_or_two_args) Z_IS_ENABLED3(one_or_two_args true, false)
177 
178 /* And our second argument is thus now cooked to be 1 in the case
179  * where the value is defined to 1, and 0 if not:
180  */
181 #define Z_IS_ENABLED3(ignore_this, val, ...) val
182 
183 const char *bt_hex(const void *buf, size_t len);
184 
185 void mem_rcopy(uint8_t *dst, uint8_t const *src, uint16_t len);
186 
187 #ifdef __cplusplus
188 }
189 #endif
190 
191 #endif /* _BLE_MESH_UTIL_H_ */
192