1 /* 2 * SPDX-FileCopyrightText: 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 #include "mesh_utils_loops.h" 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 /* Helper to pass a int as a pointer or vice-versa. 27 * Those are available for 32 bits architectures: 28 */ 29 #ifndef POINTER_TO_UINT 30 #define POINTER_TO_UINT(x) ((uint32_t) (x)) 31 #endif 32 #ifndef UINT_TO_POINTER 33 #define UINT_TO_POINTER(x) ((void *) (x)) 34 #endif 35 #ifndef POINTER_TO_INT 36 #define POINTER_TO_INT(x) ((int32_t) (x)) 37 #endif 38 #ifndef INT_TO_POINTER 39 #define INT_TO_POINTER(x) ((void *) (x)) 40 #endif 41 42 /* Evaluates to 0 if cond is true-ish; compile error otherwise */ 43 #ifndef ZERO_OR_COMPILE_ERROR 44 #define ZERO_OR_COMPILE_ERROR(cond) ((int) sizeof(char[1 - 2 * !(cond)]) - 1) 45 #endif 46 47 /* Evaluates to 0 if array is an array; compile error if not array (e.g. 48 * pointer) 49 */ 50 #ifndef IS_ARRAY 51 #define IS_ARRAY(array) \ 52 ZERO_OR_COMPILE_ERROR( \ 53 !__builtin_types_compatible_p(__typeof__(array), \ 54 __typeof__(&(array)[0]))) 55 #endif 56 57 /* Evaluates to number of elements in an array; compile error if not 58 * an array (e.g. pointer) 59 */ 60 #ifndef ARRAY_SIZE 61 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) 62 #endif 63 64 /* Evaluates to 1 if ptr is part of array, 0 otherwise; compile error if 65 * "array" argument is not an array (e.g. "ptr" and "array" mixed up) 66 */ 67 #ifndef PART_OF_ARRAY 68 #define PART_OF_ARRAY(array, ptr) \ 69 ((ptr) && ((ptr) >= &array[0] && (ptr) < &array[ARRAY_SIZE(array)])) 70 #endif 71 72 #ifndef CONTAINER_OF 73 #define CONTAINER_OF(ptr, type, field) \ 74 ((type *)(((char *)(ptr)) - offsetof(type, field))) 75 #endif 76 77 /* round "x" up/down to next multiple of "align" (which must be a power of 2) */ 78 #ifndef ROUND_UP 79 #define ROUND_UP(x, align) \ 80 (((unsigned long)(x) + ((unsigned long)align - 1)) & \ 81 ~((unsigned long)align - 1)) 82 #endif 83 84 #ifndef ROUND_DOWN 85 #define ROUND_DOWN(x, align) ((unsigned long)(x) & ~((unsigned long)align - 1)) 86 #endif 87 88 /* round up/down to the next word boundary */ 89 #ifndef WB_UP 90 #define WB_UP(x) ROUND_UP(x, sizeof(void *)) 91 #endif 92 93 #ifndef WB_DN 94 #define WB_DN(x) ROUND_DOWN(x, sizeof(void *)) 95 #endif 96 97 #ifndef ceiling_fraction 98 #define ceiling_fraction(numerator, divider) \ 99 (((numerator) + ((divider) - 1)) / (divider)) 100 #endif 101 102 #ifndef CHECKIF 103 #define CHECKIF(expr) if (expr) 104 #endif 105 106 /** @brief Return larger value of two provided expressions. 107 * 108 * @note Arguments are evaluated twice. See Z_MAX for GCC only, single 109 * evaluation version. 110 */ 111 #ifndef MAX 112 #define MAX(a, b) (((a) > (b)) ? (a) : (b)) 113 #endif 114 115 /** @brief Return smaller value of two provided expressions. 116 * 117 * @note Arguments are evaluated twice. See Z_MIN for GCC only, single 118 * evaluation version. 119 */ 120 #ifndef MIN 121 #define MIN(a, b) (((a) < (b)) ? (a) : (b)) 122 #endif 123 124 #ifndef BIT 125 #define BIT(n) (1UL << (n)) 126 #endif 127 128 #ifndef BIT_MASK 129 #define BIT_MASK(n) (BIT(n) - 1) 130 #endif 131 132 /** 133 * @brief Check for macro definition in compiler-visible expressions 134 * 135 * This trick was pioneered in Linux as the config_enabled() macro. 136 * The madness has the effect of taking a macro value that may be 137 * defined to "1" (e.g. CONFIG_MYFEATURE), or may not be defined at 138 * all and turning it into a literal expression that can be used at 139 * "runtime". That is, it works similarly to 140 * "defined(CONFIG_MYFEATURE)" does except that it is an expansion 141 * that can exist in a standard expression and be seen by the compiler 142 * and optimizer. Thus much ifdef usage can be replaced with cleaner 143 * expressions like: 144 * 145 * if (IS_ENABLED(CONFIG_MYFEATURE)) 146 * myfeature_enable(); 147 * 148 * INTERNAL 149 * First pass just to expand any existing macros, we need the macro 150 * value to be e.g. a literal "1" at expansion time in the next macro, 151 * not "(1)", etc... Standard recursive expansion does not work. 152 */ 153 #define IS_ENABLED(config_macro) Z_IS_ENABLED1(config_macro) 154 155 /* Now stick on a "_XXXX" prefix, it will now be "_XXXX1" if config_macro 156 * is "1", or just "_XXXX" if it's undefined. 157 * ENABLED: Z_IS_ENABLED2(_XXXX1) 158 * DISABLED Z_IS_ENABLED2(_XXXX) 159 */ 160 #define Z_IS_ENABLED1(config_macro) Z_IS_ENABLED2(_XXXX##config_macro) 161 162 /* Here's the core trick, we map "_XXXX1" to "_YYYY," (i.e. a string 163 * with a trailing comma), so it has the effect of making this a 164 * two-argument tuple to the preprocessor only in the case where the 165 * value is defined to "1" 166 * ENABLED: _YYYY, <--- note comma! 167 * DISABLED: _XXXX 168 */ 169 #define _XXXX1 _YYYY, 170 171 /* Then we append an extra argument to fool the gcc preprocessor into 172 * accepting it as a varargs macro. 173 * arg1 arg2 arg3 174 * ENABLED: Z_IS_ENABLED3(_YYYY, 1, 0) 175 * DISABLED Z_IS_ENABLED3(_XXXX 1, 0) 176 */ 177 #define Z_IS_ENABLED2(one_or_two_args) Z_IS_ENABLED3(one_or_two_args true, false) 178 179 /* And our second argument is thus now cooked to be 1 in the case 180 * where the value is defined to 1, and 0 if not: 181 */ 182 #define Z_IS_ENABLED3(ignore_this, val, ...) val 183 184 /* Used to remove brackets from around a single argument. */ 185 #define __DEBRACKET(...) __VA_ARGS__ 186 187 #define UTIL_CAT(a, ...) UTIL_PRIMITIVE_CAT(a, __VA_ARGS__) 188 #define UTIL_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__ 189 190 /** 191 * @brief Generates a sequence of code with configurable separator. 192 * 193 * Example: 194 * 195 * #define FOO(i, _) MY_PWM ## i 196 * { LISTIFY(PWM_COUNT, FOO, (,)) } 197 * 198 * The above two lines expand to: 199 * 200 * { MY_PWM0 , MY_PWM1 } 201 * 202 * @param LEN The length of the sequence. Must be an integer literal less 203 * than 255. 204 * @param F A macro function that accepts at least two arguments: 205 * <tt>F(i, ...)</tt>. @p F is called repeatedly in the expansion. 206 * Its first argument @p i is the index in the sequence, and 207 * the variable list of arguments passed to LISTIFY are passed 208 * through to @p F. 209 * 210 * @param sep Separator (e.g. comma or semicolon). Must be in parentheses; 211 * this is required to enable providing a comma as separator. 212 * 213 * @note Calling LISTIFY with undefined arguments has undefined 214 * behavior. 215 */ 216 #define LISTIFY(LEN, F, sep, ...) UTIL_CAT(Z_UTIL_LISTIFY_, LEN)(F, sep, __VA_ARGS__) 217 218 const char *bt_hex(const void *buf, size_t len); 219 220 void mem_rcopy(uint8_t *dst, uint8_t const *src, uint16_t len); 221 222 #ifdef __cplusplus 223 } 224 #endif 225 226 #endif /* _BLE_MESH_UTIL_H_ */ 227