summaryrefslogtreecommitdiff
path: root/lib/bt/esp_ble_mesh/common/include
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2024-03-28 14:32:49 +1100
committerjacqueline <me@jacqueline.id.au>2024-03-28 14:32:49 +1100
commitee29c25b29eaa4fac4e897442634b69ecc8d8125 (patch)
tree8c5f1a140463f20f104316fa3492984e191154e9 /lib/bt/esp_ble_mesh/common/include
parent239e6d89507a24c849385f4bfa93ac4ad58e5de5 (diff)
downloadtangara-fw-ee29c25b29eaa4fac4e897442634b69ecc8d8125.tar.gz
Fork ESP-IDF's bluetooth component
i want better sbc encoding, and no cla will stop me
Diffstat (limited to 'lib/bt/esp_ble_mesh/common/include')
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/atomic.h305
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/buf.h1758
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/byteorder.h599
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/common.h62
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/compiler.h80
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/config.h61
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/dlist.h498
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/ffs.h60
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/kernel.h59
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/mutex.h54
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/slist.h467
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/timer.h278
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/trace.h173
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/types.h33
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/utils.h226
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/utils_loops.h1051
16 files changed, 5764 insertions, 0 deletions
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/atomic.h b/lib/bt/esp_ble_mesh/common/include/mesh/atomic.h
new file mode 100644
index 00000000..f7283436
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/atomic.h
@@ -0,0 +1,305 @@
+/* atomic operations */
+
+/*
+ * SPDX-FileCopyrightText: 1997-2015 Wind River Systems, Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _BLE_MESH_ATOMIC_H_
+#define _BLE_MESH_ATOMIC_H_
+
+#include "mesh/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef bt_mesh_atomic_t bt_mesh_atomic_val_t;
+
+/**
+ * @defgroup atomic_apis Atomic Services APIs
+ * @ingroup kernel_apis
+ * @{
+ */
+
+/**
+ *
+ * @brief Atomic increment.
+ *
+ * This routine performs an atomic increment by 1 on @a target.
+ *
+ * @param target Address of atomic variable.
+ *
+ * @return Previous value of @a target.
+ */
+#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
+static inline bt_mesh_atomic_val_t bt_mesh_atomic_inc(bt_mesh_atomic_t *target)
+{
+ return bt_mesh_atomic_add(target, 1);
+}
+#else
+extern bt_mesh_atomic_val_t bt_mesh_atomic_inc(bt_mesh_atomic_t *target);
+#endif
+
+/**
+ *
+ * @brief Atomic decrement.
+ *
+ * This routine performs an atomic decrement by 1 on @a target.
+ *
+ * @param target Address of atomic variable.
+ *
+ * @return Previous value of @a target.
+ */
+#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
+static inline bt_mesh_atomic_val_t bt_mesh_atomic_dec(bt_mesh_atomic_t *target)
+{
+ return bt_mesh_atomic_sub(target, 1);
+}
+#else
+extern bt_mesh_atomic_val_t bt_mesh_atomic_dec(bt_mesh_atomic_t *target);
+#endif
+
+/**
+ *
+ * @brief Atomic get.
+ *
+ * This routine performs an atomic read on @a target.
+ *
+ * @param target Address of atomic variable.
+ *
+ * @return Value of @a target.
+ */
+#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
+static inline bt_mesh_atomic_val_t bt_mesh_atomic_get(const bt_mesh_atomic_t *target)
+{
+ return __atomic_load_n(target, __ATOMIC_SEQ_CST);
+}
+#else
+extern bt_mesh_atomic_val_t bt_mesh_atomic_get(const bt_mesh_atomic_t *target);
+#endif
+
+/**
+ *
+ * @brief Atomic get-and-set.
+ *
+ * This routine atomically sets @a target to @a value and returns
+ * the previous value of @a target.
+ *
+ * @param target Address of atomic variable.
+ * @param value Value to write to @a target.
+ *
+ * @return Previous value of @a target.
+ */
+#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
+static inline bt_mesh_atomic_val_t bt_mesh_atomic_set(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
+{
+ /* This builtin, as described by Intel, is not a traditional
+ * test-and-set operation, but rather an atomic exchange operation. It
+ * writes value into *ptr, and returns the previous contents of *ptr.
+ */
+ return __atomic_exchange_n(target, value, __ATOMIC_SEQ_CST);
+}
+#else
+extern bt_mesh_atomic_val_t bt_mesh_atomic_set(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value);
+#endif
+
+/**
+ *
+ * @brief Atomic bitwise inclusive OR.
+ *
+ * This routine atomically sets @a target to the bitwise inclusive OR of
+ * @a target and @a value.
+ *
+ * @param target Address of atomic variable.
+ * @param value Value to OR.
+ *
+ * @return Previous value of @a target.
+ */
+#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
+static inline bt_mesh_atomic_val_t bt_mesh_atomic_or(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
+{
+ return __atomic_fetch_or(target, value, __ATOMIC_SEQ_CST);
+}
+#else
+extern bt_mesh_atomic_val_t bt_mesh_atomic_or(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value);
+#endif
+
+/**
+ *
+ * @brief Atomic bitwise AND.
+ *
+ * This routine atomically sets @a target to the bitwise AND of @a target
+ * and @a value.
+ *
+ * @param target Address of atomic variable.
+ * @param value Value to AND.
+ *
+ * @return Previous value of @a target.
+ */
+#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
+static inline bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
+{
+ return __atomic_fetch_and(target, value, __ATOMIC_SEQ_CST);
+}
+#else
+extern bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value);
+#endif
+
+/**
+ * @cond INTERNAL_HIDDEN
+ */
+
+#define BLE_MESH_ATOMIC_BITS (sizeof(bt_mesh_atomic_val_t) * 8)
+#define BLE_MESH_ATOMIC_MASK(bit) (1 << ((bit) & (BLE_MESH_ATOMIC_BITS - 1)))
+#define BLE_MESH_ATOMIC_ELEM(addr, bit) ((addr) + ((bit) / BLE_MESH_ATOMIC_BITS))
+
+/**
+ * INTERNAL_HIDDEN @endcond
+ */
+
+/**
+ * @brief Define an array of atomic variables.
+ *
+ * This macro defines an array of atomic variables containing at least
+ * @a num_bits bits.
+ *
+ * @note
+ * If used from file scope, the bits of the array are initialized to zero;
+ * if used from within a function, the bits are left uninitialized.
+ *
+ * @param name Name of array of atomic variables.
+ * @param num_bits Number of bits needed.
+ */
+#define BLE_MESH_ATOMIC_DEFINE(name, num_bits) \
+ bt_mesh_atomic_t name[1 + ((num_bits) - 1) / BLE_MESH_ATOMIC_BITS]
+
+/**
+ * @brief Atomically test a bit.
+ *
+ * This routine tests whether bit number @a bit of @a target is set or not.
+ * The target may be a single atomic variable or an array of them.
+ *
+ * @param target Address of atomic variable or array.
+ * @param bit Bit number (starting from 0).
+ *
+ * @return 1 if the bit was set, 0 if it wasn't.
+ */
+static inline int bt_mesh_atomic_test_bit(const bt_mesh_atomic_t *target, int bit)
+{
+ bt_mesh_atomic_val_t val = bt_mesh_atomic_get(BLE_MESH_ATOMIC_ELEM(target, bit));
+
+ return (1 & (val >> (bit & (BLE_MESH_ATOMIC_BITS - 1))));
+}
+
+/**
+ * @brief Atomically test and clear a bit.
+ *
+ * Atomically clear bit number @a bit of @a target and return its old value.
+ * The target may be a single atomic variable or an array of them.
+ *
+ * @param target Address of atomic variable or array.
+ * @param bit Bit number (starting from 0).
+ *
+ * @return 1 if the bit was set, 0 if it wasn't.
+ */
+static inline int bt_mesh_atomic_test_and_clear_bit(bt_mesh_atomic_t *target, int bit)
+{
+ bt_mesh_atomic_val_t mask = BLE_MESH_ATOMIC_MASK(bit);
+ bt_mesh_atomic_val_t old;
+
+ old = bt_mesh_atomic_and(BLE_MESH_ATOMIC_ELEM(target, bit), ~mask);
+
+ return (old & mask) != 0;
+}
+
+/**
+ * @brief Atomically set a bit.
+ *
+ * Atomically set bit number @a bit of @a target and return its old value.
+ * The target may be a single atomic variable or an array of them.
+ *
+ * @param target Address of atomic variable or array.
+ * @param bit Bit number (starting from 0).
+ *
+ * @return 1 if the bit was set, 0 if it wasn't.
+ */
+static inline int bt_mesh_atomic_test_and_set_bit(bt_mesh_atomic_t *target, int bit)
+{
+ bt_mesh_atomic_val_t mask = BLE_MESH_ATOMIC_MASK(bit);
+ bt_mesh_atomic_val_t old;
+
+ old = bt_mesh_atomic_or(BLE_MESH_ATOMIC_ELEM(target, bit), mask);
+
+ return (old & mask) != 0;
+}
+
+/**
+ * @brief Atomically clear a bit.
+ *
+ * Atomically clear bit number @a bit of @a target.
+ * The target may be a single atomic variable or an array of them.
+ *
+ * @param target Address of atomic variable or array.
+ * @param bit Bit number (starting from 0).
+ *
+ * @return N/A
+ */
+static inline void bt_mesh_atomic_clear_bit(bt_mesh_atomic_t *target, int bit)
+{
+ bt_mesh_atomic_val_t mask = BLE_MESH_ATOMIC_MASK(bit);
+
+ (void)bt_mesh_atomic_and(BLE_MESH_ATOMIC_ELEM(target, bit), ~mask);
+}
+
+/**
+ * @brief Atomically set a bit.
+ *
+ * Atomically set bit number @a bit of @a target.
+ * The target may be a single atomic variable or an array of them.
+ *
+ * @param target Address of atomic variable or array.
+ * @param bit Bit number (starting from 0).
+ *
+ * @return N/A
+ */
+static inline void bt_mesh_atomic_set_bit(bt_mesh_atomic_t *target, int bit)
+{
+ bt_mesh_atomic_val_t mask = BLE_MESH_ATOMIC_MASK(bit);
+
+ (void)bt_mesh_atomic_or(BLE_MESH_ATOMIC_ELEM(target, bit), mask);
+}
+
+/**
+ * @brief Atomically set a bit to a given value.
+ *
+ * Atomically set bit number @a bit of @a target to value @a val.
+ * The target may be a single atomic variable or an array of them.
+ *
+ * @param target Address of atomic variable or array.
+ * @param bit Bit number (starting from 0).
+ * @param val true for 1, false for 0.
+ *
+ * @return N/A
+ */
+static inline void bt_mesh_atomic_set_bit_to(bt_mesh_atomic_t *target, int bit, bool val)
+{
+ bt_mesh_atomic_val_t mask = BLE_MESH_ATOMIC_MASK(bit);
+
+ if (val) {
+ (void)bt_mesh_atomic_or(BLE_MESH_ATOMIC_ELEM(target, bit), mask);
+ } else {
+ (void)bt_mesh_atomic_and(BLE_MESH_ATOMIC_ELEM(target, bit), ~mask);
+ }
+}
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_ATOMIC_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/buf.h b/lib/bt/esp_ble_mesh/common/include/mesh/buf.h
new file mode 100644
index 00000000..da4200a0
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/buf.h
@@ -0,0 +1,1758 @@
+/** @file
+ * @brief Buffer management.
+ */
+
+/*
+ * SPDX-FileCopyrightText: 2015 Intel Corporation
+ * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef _BLE_MESH_BUF_H_
+#define _BLE_MESH_BUF_H_
+
+#include "mesh/config.h"
+#include "mesh/types.h"
+#include "mesh/slist.h"
+#include "mesh/compiler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Unaligned access */
+#define UNALIGNED_GET(p) \
+__extension__ ({ \
+ struct __attribute__((__packed__)) { \
+ __typeof__(*(p)) __v; \
+ } *__p = (__typeof__(__p)) (p); \
+ __p->__v; \
+})
+
+#define BLE_MESH_NET_BUF_USER_DATA_SIZE 4
+
+/**
+ * @brief Network buffer library
+ * @defgroup net_buf Network Buffer Library
+ * @ingroup networking
+ * @{
+ */
+
+/* Alignment needed for various parts of the buffer definition */
+#define __net_buf_align __aligned(sizeof(int))
+
+/**
+ * @def NET_BUF_SIMPLE_DEFINE
+ * @brief Define a net_buf_simple stack variable.
+ *
+ * This is a helper macro which is used to define a net_buf_simple object
+ * on the stack.
+ *
+ * @param _name Name of the net_buf_simple object.
+ * @param _size Maximum data storage for the buffer.
+ */
+#define NET_BUF_SIMPLE_DEFINE(_name, _size) \
+ uint8_t net_buf_data_##_name[_size]; \
+ struct net_buf_simple _name = { \
+ .data = net_buf_data_##_name, \
+ .len = 0, \
+ .size = _size, \
+ .__buf = net_buf_data_##_name, \
+ }
+
+/**
+ * @def NET_BUF_SIMPLE_DEFINE_STATIC
+ * @brief Define a static net_buf_simple variable.
+ *
+ * This is a helper macro which is used to define a static net_buf_simple
+ * object.
+ *
+ * @param _name Name of the net_buf_simple object.
+ * @param _size Maximum data storage for the buffer.
+ */
+#define NET_BUF_SIMPLE_DEFINE_STATIC(_name, _size) \
+ static uint8_t net_buf_data_##_name[_size]; \
+ static struct net_buf_simple _name = { \
+ .data = net_buf_data_##_name, \
+ .len = 0, \
+ .size = _size, \
+ .__buf = net_buf_data_##_name, \
+ }
+
+/**
+ * @brief Simple network buffer representation.
+ *
+ * This is a simpler variant of the net_buf object (in fact net_buf uses
+ * net_buf_simple internally). It doesn't provide any kind of reference
+ * counting, user data, dynamic allocation, or in general the ability to
+ * pass through kernel objects such as FIFOs.
+ *
+ * The main use of this is for scenarios where the meta-data of the normal
+ * net_buf isn't needed and causes too much overhead. This could be e.g.
+ * when the buffer only needs to be allocated on the stack or when the
+ * access to and lifetime of the buffer is well controlled and constrained.
+ */
+struct net_buf_simple {
+ /** Pointer to the start of data in the buffer. */
+ uint8_t *data;
+
+ /** Length of the data behind the data pointer. */
+ uint16_t len;
+
+ /** Amount of data that this buffer can store. */
+ uint16_t size;
+
+ /** Start of the data storage. Not to be accessed directly
+ * (the data pointer should be used instead).
+ */
+ uint8_t *__buf;
+};
+
+/**
+ * @def NET_BUF_SIMPLE
+ * @brief Define a net_buf_simple stack variable and get a pointer to it.
+ *
+ * This is a helper macro which is used to define a net_buf_simple object on
+ * the stack and the get a pointer to it as follows:
+ *
+ * struct net_buf_simple *my_buf = NET_BUF_SIMPLE(10);
+ *
+ * After creating the object it needs to be initialized by calling
+ * net_buf_simple_init().
+ *
+ * @param _size Maximum data storage for the buffer.
+ *
+ * @return Pointer to stack-allocated net_buf_simple object.
+ */
+#define NET_BUF_SIMPLE(_size) \
+ ((struct net_buf_simple *)(&(struct { \
+ struct net_buf_simple buf; \
+ uint8_t data[_size] __net_buf_align; \
+ }) { \
+ .buf.size = _size, \
+ .buf.__buf = NULL, \
+ }))
+
+/**
+ * @brief Initialize a net_buf_simple object.
+ *
+ * This needs to be called after creating a net_buf_simple object using
+ * the NET_BUF_SIMPLE macro.
+ *
+ * @param buf Buffer to initialize.
+ * @param reserve_head Headroom to reserve.
+ */
+static inline void net_buf_simple_init(struct net_buf_simple *buf,
+ size_t reserve_head)
+{
+ if (!buf->__buf) {
+ buf->__buf = (uint8_t *)buf + sizeof(*buf);
+ }
+
+ buf->data = buf->__buf + reserve_head;
+ buf->len = 0;
+}
+
+/**
+ * @brief Initialize a net_buf_simple object with data.
+ *
+ * Initialized buffer object with external data.
+ *
+ * @param buf Buffer to initialize.
+ * @param data External data pointer
+ * @param size Amount of data the pointed data buffer if able to fit.
+ */
+void net_buf_simple_init_with_data(struct net_buf_simple *buf,
+ void *data, size_t size);
+
+/**
+ * @brief Reset buffer
+ *
+ * Reset buffer data so it can be reused for other purposes.
+ *
+ * @param buf Buffer to reset.
+ */
+static inline void net_buf_simple_reset(struct net_buf_simple *buf)
+{
+ buf->len = 0;
+ buf->data = buf->__buf;
+}
+
+/**
+ * Clone buffer state, using the same data buffer.
+ *
+ * Initializes a buffer to point to the same data as an existing buffer.
+ * Allows operations on the same data without altering the length and
+ * offset of the original.
+ *
+ * @param original Buffer to clone.
+ * @param clone The new clone.
+ */
+void net_buf_simple_clone(const struct net_buf_simple *original,
+ struct net_buf_simple *clone);
+
+/**
+ * @brief Prepare data to be added at the end of the buffer
+ *
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param len Number of bytes to increment the length with.
+ *
+ * @return The original tail of the buffer.
+ */
+void *net_buf_simple_add(struct net_buf_simple *buf, size_t len);
+
+/**
+ * @brief Copy given number of bytes from memory to the end of the buffer
+ *
+ * Increments the data length of the buffer to account for more data at the
+ * end.
+ *
+ * @param buf Buffer to update.
+ * @param mem Location of data to be added.
+ * @param len Length of data to be added
+ *
+ * @return The original tail of the buffer.
+ */
+void *net_buf_simple_add_mem(struct net_buf_simple *buf, const void *mem,
+ size_t len);
+
+/**
+ * @brief Add (8-bit) byte at the end of the buffer
+ *
+ * Increments the data length of the buffer to account for more data at the
+ * end.
+ *
+ * @param buf Buffer to update.
+ * @param val byte value to be added.
+ *
+ * @return Pointer to the value added
+ */
+uint8_t *net_buf_simple_add_u8(struct net_buf_simple *buf, uint8_t val);
+
+/**
+ * @brief Add 16-bit value at the end of the buffer
+ *
+ * Adds 16-bit value in little endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 16-bit value to be added.
+ */
+void net_buf_simple_add_le16(struct net_buf_simple *buf, uint16_t val);
+
+/**
+ * @brief Add 16-bit value at the end of the buffer
+ *
+ * Adds 16-bit value in big endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 16-bit value to be added.
+ */
+void net_buf_simple_add_be16(struct net_buf_simple *buf, uint16_t val);
+
+/**
+ * @brief Add 24-bit value at the end of the buffer
+ *
+ * Adds 24-bit value in little endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 24-bit value to be added.
+ */
+void net_buf_simple_add_le24(struct net_buf_simple *buf, uint32_t val);
+
+/**
+ * @brief Add 24-bit value at the end of the buffer
+ *
+ * Adds 24-bit value in big endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 24-bit value to be added.
+ */
+void net_buf_simple_add_be24(struct net_buf_simple *buf, uint32_t val);
+
+/**
+ * @brief Add 32-bit value at the end of the buffer
+ *
+ * Adds 32-bit value in little endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 32-bit value to be added.
+ */
+void net_buf_simple_add_le32(struct net_buf_simple *buf, uint32_t val);
+
+/**
+ * @brief Add 32-bit value at the end of the buffer
+ *
+ * Adds 32-bit value in big endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 32-bit value to be added.
+ */
+void net_buf_simple_add_be32(struct net_buf_simple *buf, uint32_t val);
+
+/**
+ * @brief Add 48-bit value at the end of the buffer
+ *
+ * Adds 48-bit value in little endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 48-bit value to be added.
+ */
+void net_buf_simple_add_le48(struct net_buf_simple *buf, uint64_t val);
+
+/**
+ * @brief Add 48-bit value at the end of the buffer
+ *
+ * Adds 48-bit value in big endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 48-bit value to be added.
+ */
+void net_buf_simple_add_be48(struct net_buf_simple *buf, uint64_t val);
+
+/**
+ * @brief Add 64-bit value at the end of the buffer
+ *
+ * Adds 64-bit value in little endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 64-bit value to be added.
+ */
+void net_buf_simple_add_le64(struct net_buf_simple *buf, uint64_t val);
+
+/**
+ * @brief Add 64-bit value at the end of the buffer
+ *
+ * Adds 64-bit value in big endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 64-bit value to be added.
+ */
+void net_buf_simple_add_be64(struct net_buf_simple *buf, uint64_t val);
+
+/**
+ * @brief Push data to the beginning of the buffer.
+ *
+ * Modifies the data pointer and buffer length to account for more data
+ * in the beginning of the buffer.
+ *
+ * @param buf Buffer to update.
+ * @param len Number of bytes to add to the beginning.
+ *
+ * @return The new beginning of the buffer data.
+ */
+void *net_buf_simple_push(struct net_buf_simple *buf, size_t len);
+
+/**
+ * @brief Push 16-bit value to the beginning of the buffer
+ *
+ * Adds 16-bit value in little endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 16-bit value to be pushed to the buffer.
+ */
+void net_buf_simple_push_le16(struct net_buf_simple *buf, uint16_t val);
+
+/**
+ * @brief Push 16-bit value to the beginning of the buffer
+ *
+ * Adds 16-bit value in big endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 16-bit value to be pushed to the buffer.
+ */
+void net_buf_simple_push_be16(struct net_buf_simple *buf, uint16_t val);
+
+/**
+ * @brief Push 8-bit value to the beginning of the buffer
+ *
+ * Adds 8-bit value the beginning of the buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 8-bit value to be pushed to the buffer.
+ */
+void net_buf_simple_push_u8(struct net_buf_simple *buf, uint8_t val);
+
+/**
+ * @brief Push 24-bit value to the beginning of the buffer
+ *
+ * Adds 24-bit value in little endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 24-bit value to be pushed to the buffer.
+ */
+void net_buf_simple_push_le24(struct net_buf_simple *buf, uint32_t val);
+
+/**
+ * @brief Push 24-bit value to the beginning of the buffer
+ *
+ * Adds 24-bit value in big endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 24-bit value to be pushed to the buffer.
+ */
+void net_buf_simple_push_be24(struct net_buf_simple *buf, uint32_t val);
+
+/**
+ * @brief Push 32-bit value to the beginning of the buffer
+ *
+ * Adds 32-bit value in little endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 32-bit value to be pushed to the buffer.
+ */
+void net_buf_simple_push_le32(struct net_buf_simple *buf, uint32_t val);
+
+/**
+ * @brief Push 32-bit value to the beginning of the buffer
+ *
+ * Adds 32-bit value in big endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 32-bit value to be pushed to the buffer.
+ */
+void net_buf_simple_push_be32(struct net_buf_simple *buf, uint32_t val);
+
+/**
+ * @brief Push 48-bit value to the beginning of the buffer
+ *
+ * Adds 48-bit value in little endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 48-bit value to be pushed to the buffer.
+ */
+void net_buf_simple_push_le48(struct net_buf_simple *buf, uint64_t val);
+
+/**
+ * @brief Push 48-bit value to the beginning of the buffer
+ *
+ * Adds 48-bit value in big endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 48-bit value to be pushed to the buffer.
+ */
+void net_buf_simple_push_be48(struct net_buf_simple *buf, uint64_t val);
+
+/**
+ * @brief Push 64-bit value to the beginning of the buffer
+ *
+ * Adds 64-bit value in little endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 64-bit value to be pushed to the buffer.
+ */
+void net_buf_simple_push_le64(struct net_buf_simple *buf, uint64_t val);
+
+/**
+ * @brief Push 64-bit value to the beginning of the buffer
+ *
+ * Adds 64-bit value in big endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 64-bit value to be pushed to the buffer.
+ */
+void net_buf_simple_push_be64(struct net_buf_simple *buf, uint64_t val);
+
+/**
+ * @brief Remove data from the beginning of the buffer.
+ *
+ * Removes data from the beginning of the buffer by modifying the data
+ * pointer and buffer length.
+ *
+ * @param buf Buffer to update.
+ * @param len Number of bytes to remove.
+ *
+ * @return New beginning of the buffer data.
+ */
+void *net_buf_simple_pull(struct net_buf_simple *buf, size_t len);
+
+/**
+ * @brief Remove data from the beginning of the buffer.
+ *
+ * Removes data from the beginning of the buffer by modifying the data
+ * pointer and buffer length.
+ *
+ * @param buf Buffer to update.
+ * @param len Number of bytes to remove.
+ *
+ * @return Pointer to the old location of the buffer data.
+ */
+void *net_buf_simple_pull_mem(struct net_buf_simple *buf, size_t len);
+
+/**
+ * @brief Remove a 8-bit value from the beginning of the buffer
+ *
+ * Same idea as with net_buf_simple_pull(), but a helper for operating
+ * on 8-bit values.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return The 8-bit removed value
+ */
+uint8_t net_buf_simple_pull_u8(struct net_buf_simple *buf);
+
+/**
+ * @brief Remove and convert 16 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_simple_pull(), but a helper for operating
+ * on 16-bit little endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 16-bit value converted from little endian to host endian.
+ */
+uint16_t net_buf_simple_pull_le16(struct net_buf_simple *buf);
+
+/**
+ * @brief Remove and convert 16 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_simple_pull(), but a helper for operating
+ * on 16-bit big endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 16-bit value converted from big endian to host endian.
+ */
+uint16_t net_buf_simple_pull_be16(struct net_buf_simple *buf);
+
+/**
+ * @brief Remove and convert 24 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_simple_pull(), but a helper for operating
+ * on 24-bit little endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 24-bit value converted from little endian to host endian.
+ */
+uint32_t net_buf_simple_pull_le24(struct net_buf_simple *buf);
+
+/**
+ * @brief Remove and convert 24 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_simple_pull(), but a helper for operating
+ * on 24-bit big endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 24-bit value converted from big endian to host endian.
+ */
+uint32_t net_buf_simple_pull_be24(struct net_buf_simple *buf);
+
+/**
+ * @brief Remove and convert 32 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_simple_pull(), but a helper for operating
+ * on 32-bit little endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 32-bit value converted from little endian to host endian.
+ */
+uint32_t net_buf_simple_pull_le32(struct net_buf_simple *buf);
+
+/**
+ * @brief Remove and convert 32 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_simple_pull(), but a helper for operating
+ * on 32-bit big endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 32-bit value converted from big endian to host endian.
+ */
+uint32_t net_buf_simple_pull_be32(struct net_buf_simple *buf);
+
+/**
+ * @brief Remove and convert 48 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_simple_pull(), but a helper for operating
+ * on 48-bit little endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 48-bit value converted from little endian to host endian.
+ */
+uint64_t net_buf_simple_pull_le48(struct net_buf_simple *buf);
+
+/**
+ * @brief Remove and convert 48 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_simple_pull(), but a helper for operating
+ * on 48-bit big endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 48-bit value converted from big endian to host endian.
+ */
+uint64_t net_buf_simple_pull_be48(struct net_buf_simple *buf);
+
+/**
+ * @brief Remove and convert 64 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_simple_pull(), but a helper for operating
+ * on 64-bit little endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 64-bit value converted from little endian to host endian.
+ */
+uint64_t net_buf_simple_pull_le64(struct net_buf_simple *buf);
+
+/**
+ * @brief Remove and convert 64 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_simple_pull(), but a helper for operating
+ * on 64-bit big endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 64-bit value converted from big endian to host endian.
+ */
+uint64_t net_buf_simple_pull_be64(struct net_buf_simple *buf);
+
+/**
+ * @brief Get the tail pointer for a buffer.
+ *
+ * Get a pointer to the end of the data in a buffer.
+ *
+ * @param buf Buffer.
+ *
+ * @return Tail pointer for the buffer.
+ */
+static inline uint8_t *net_buf_simple_tail(struct net_buf_simple *buf)
+{
+ return buf->data + buf->len;
+}
+
+/**
+ * @brief Check buffer headroom.
+ *
+ * Check how much free space there is in the beginning of the buffer.
+ *
+ * buf A valid pointer on a buffer
+ *
+ * @return Number of bytes available in the beginning of the buffer.
+ */
+size_t net_buf_simple_headroom(struct net_buf_simple *buf);
+
+/**
+ * @brief Check buffer tailroom.
+ *
+ * Check how much free space there is at the end of the buffer.
+ *
+ * @param buf A valid pointer on a buffer
+ *
+ * @return Number of bytes available at the end of the buffer.
+ */
+size_t net_buf_simple_tailroom(struct net_buf_simple *buf);
+
+/**
+ * @brief Parsing state of a buffer.
+ *
+ * This is used for temporarily storing the parsing state of a buffer
+ * while giving control of the parsing to a routine which we don't
+ * control.
+ */
+struct net_buf_simple_state {
+ /** Offset of the data pointer from the beginning of the storage */
+ uint16_t offset;
+ /** Length of data */
+ uint16_t len;
+};
+
+/**
+ * @brief Save the parsing state of a buffer.
+ *
+ * Saves the parsing state of a buffer so it can be restored later.
+ *
+ * @param buf Buffer from which the state should be saved.
+ * @param state Storage for the state.
+ */
+static inline void net_buf_simple_save(struct net_buf_simple *buf,
+ struct net_buf_simple_state *state)
+{
+ state->offset = net_buf_simple_headroom(buf);
+ state->len = buf->len;
+}
+
+/**
+ * @brief Restore the parsing state of a buffer.
+ *
+ * Restores the parsing state of a buffer from a state previously stored
+ * by net_buf_simple_save().
+ *
+ * @param buf Buffer to which the state should be restored.
+ * @param state Stored state.
+ */
+static inline void net_buf_simple_restore(struct net_buf_simple *buf,
+ struct net_buf_simple_state *state)
+{
+ buf->data = buf->__buf + state->offset;
+ buf->len = state->len;
+}
+
+/**
+ * @brief Initialize buffer with the given headroom.
+ *
+ * The buffer is not expected to contain any data when this API is called.
+ *
+ * @param buf Buffer to initialize.
+ * @param reserve How much headroom to reserve.
+ */
+void net_buf_simple_reserve(struct net_buf_simple *buf, size_t reserve);
+
+/**
+ * Flag indicating that the buffer has associated fragments. Only used
+ * internally by the buffer handling code while the buffer is inside a
+ * FIFO, meaning this never needs to be explicitly set or unset by the
+ * net_buf API user. As long as the buffer is outside of a FIFO, i.e.
+ * in practice always for the user for this API, the buf->frags pointer
+ * should be used instead.
+ */
+#define NET_BUF_FRAGS BIT(0)
+
+/**
+ * @brief Network buffer representation.
+ *
+ * This struct is used to represent network buffers. Such buffers are
+ * normally defined through the NET_BUF_POOL_*_DEFINE() APIs and allocated
+ * using the net_buf_alloc() API.
+ */
+struct net_buf {
+ union {
+ /** Allow placing the buffer into sys_slist_t */
+ sys_snode_t node;
+
+ /** Fragments associated with this buffer. */
+ struct net_buf *frags;
+ };
+
+ /** Reference count. */
+ uint8_t ref;
+
+ /** Bit-field of buffer flags. */
+ uint8_t flags;
+
+ /** Where the buffer should go when freed up. */
+ struct net_buf_pool *pool;
+
+ /* Union for convenience access to the net_buf_simple members, also
+ * preserving the old API.
+ */
+ union {
+ /* The ABI of this struct must match net_buf_simple */
+ struct {
+ /** Pointer to the start of data in the buffer. */
+ uint8_t *data;
+
+ /** Length of the data behind the data pointer. */
+ uint16_t len;
+
+ /** Amount of data that this buffer can store. */
+ uint16_t size;
+
+ /** Start of the data storage. Not to be accessed
+ * directly (the data pointer should be used
+ * instead).
+ */
+ uint8_t *__buf;
+ };
+
+ struct net_buf_simple b;
+ };
+
+ /** System metadata for this buffer. */
+ uint8_t user_data[BLE_MESH_NET_BUF_USER_DATA_SIZE] __net_buf_align;
+};
+
+struct net_buf_data_cb {
+ uint8_t *(*alloc)(struct net_buf *buf, size_t *size, int32_t timeout);
+ uint8_t *(*ref)(struct net_buf *buf, uint8_t *data);
+ void (*unref)(struct net_buf *buf, uint8_t *data);
+};
+
+struct net_buf_data_alloc {
+ const struct net_buf_data_cb *cb;
+ void *alloc_data;
+};
+
+struct net_buf_pool {
+ /** Number of buffers in pool */
+ const uint16_t buf_count;
+
+ /** Number of uninitialized buffers */
+ uint16_t uninit_count;
+
+#if CONFIG_BLE_MESH_NET_BUF_POOL_USAGE
+ /** Amount of available buffers in the pool. */
+ int16_t avail_count;
+
+ /** Total size of the pool. */
+ const uint16_t pool_size;
+
+ /** Name of the pool. Used when printing pool information. */
+ const char *name;
+#endif /* CONFIG_BLE_MESH_NET_BUF_POOL_USAGE */
+
+ /** Optional destroy callback when buffer is freed. */
+ void (*const destroy)(struct net_buf *buf);
+
+ /** Data allocation handlers. */
+ const struct net_buf_data_alloc *alloc;
+
+ /** Helper to access the start of storage (for net_buf_pool_init) */
+ struct net_buf *const __bufs;
+};
+
+#if CONFIG_BLE_MESH_NET_BUF_POOL_USAGE
+#define NET_BUF_POOL_INITIALIZER(_pool, _alloc, _bufs, _count, _destroy) \
+ { \
+ .buf_count = _count, \
+ .uninit_count = _count, \
+ .avail_count = _count, \
+ .name = STRINGIFY(_pool), \
+ .destroy = _destroy, \
+ .alloc = _alloc, \
+ .__bufs = (struct net_buf *)_bufs, \
+ }
+#else
+#define NET_BUF_POOL_INITIALIZER(_pool, _alloc, _bufs, _count, _destroy) \
+ { \
+ .buf_count = _count, \
+ .uninit_count = _count, \
+ .destroy = _destroy, \
+ .alloc = _alloc, \
+ .__bufs = (struct net_buf *)_bufs, \
+ }
+#endif /* CONFIG_BLE_MESH_NET_BUF_POOL_USAGE */
+
+struct net_buf_pool_fixed {
+ size_t data_size;
+ uint8_t *data_pool;
+};
+
+/** @cond INTERNAL_HIDDEN */
+extern const struct net_buf_data_cb net_buf_fixed_cb;
+
+/**
+ * @def NET_BUF_POOL_FIXED_DEFINE
+ * @brief Define a new pool for buffers based on fixed-size data
+ *
+ * Defines a net_buf_pool struct and the necessary memory storage (array of
+ * structs) for the needed amount of buffers. After this, the buffers can be
+ * accessed from the pool through net_buf_alloc. The pool is defined as a
+ * static variable, so if it needs to be exported outside the current module
+ * this needs to happen with the help of a separate pointer rather than an
+ * extern declaration.
+ *
+ * The data payload of the buffers will be allocated from a byte array
+ * of fixed sized chunks. This kind of pool does not support blocking on
+ * the data allocation, so the timeout passed to net_buf_alloc will be
+ * always treated as K_NO_WAIT when trying to allocate the data. This means
+ * that allocation failures, i.e. NULL returns, must always be handled
+ * cleanly.
+ *
+ * If provided with a custom destroy callback, this callback is
+ * responsible for eventually calling net_buf_destroy() to complete the
+ * process of returning the buffer to the pool.
+ *
+ * @param _name Name of the pool variable.
+ * @param _count Number of buffers in the pool.
+ * @param _data_size Maximum data payload per buffer.
+ * @param _destroy Optional destroy callback when buffer is freed.
+ */
+#define NET_BUF_POOL_FIXED_DEFINE(_name, _count, _data_size, _destroy) \
+ static struct net_buf net_buf_##_name[_count]; \
+ static uint8_t net_buf_data_##_name[_count][_data_size]; \
+ static const struct net_buf_pool_fixed net_buf_fixed_##_name = { \
+ .data_size = _data_size, \
+ .data_pool = (uint8_t *)net_buf_data_##_name, \
+ }; \
+ static const struct net_buf_data_alloc net_buf_fixed_alloc_##_name = { \
+ .cb = &net_buf_fixed_cb, \
+ .alloc_data = (void *)&net_buf_fixed_##_name, \
+ }; \
+ struct net_buf_pool _name __net_buf_align \
+ __in_section(_net_buf_pool, static, _name) = \
+ NET_BUF_POOL_INITIALIZER(_name, &net_buf_fixed_alloc_##_name, \
+ net_buf_##_name, _count, _destroy)
+
+/**
+ * @def NET_BUF_POOL_DEFINE
+ * @brief Define a new pool for buffers
+ *
+ * Defines a net_buf_pool struct and the necessary memory storage (array of
+ * structs) for the needed amount of buffers. After this,the buffers can be
+ * accessed from the pool through net_buf_alloc. The pool is defined as a
+ * static variable, so if it needs to be exported outside the current module
+ * this needs to happen with the help of a separate pointer rather than an
+ * extern declaration.
+ *
+ * If provided with a custom destroy callback this callback is
+ * responsible for eventually calling net_buf_destroy() to complete the
+ * process of returning the buffer to the pool.
+ *
+ * @param _name Name of the pool variable.
+ * @param _count Number of buffers in the pool.
+ * @param _size Maximum data size for each buffer.
+ * @param _ud_size Amount of user data space to reserve.
+ * @param _destroy Optional destroy callback when buffer is freed.
+ */
+#define NET_BUF_POOL_DEFINE(_name, _count, _size, _ud_size, _destroy) \
+ NET_BUF_POOL_FIXED_DEFINE(_name, _count, _size, _destroy)
+
+/**
+ * @brief Get a zero-based index for a buffer.
+ *
+ * This function will translate a buffer into a zero-based index,
+ * based on its placement in its buffer pool. This can be useful if you
+ * want to associate an external array of meta-data contexts with the
+ * buffers of a pool.
+ *
+ * @param buf Network buffer.
+ *
+ * @return Zero-based index for the buffer.
+ */
+int net_buf_id(struct net_buf *buf);
+
+/**
+ * @brief Allocate a new fixed buffer from a pool.
+ *
+ * @param pool Which pool to allocate the buffer from.
+ * @param timeout Affects the action taken should the pool be empty.
+ * If K_NO_WAIT, then return immediately. If K_FOREVER, then
+ * wait as long as necessary. Otherwise, wait up to the specified
+ * number of milliseconds before timing out. Note that some types
+ * of data allocators do not support blocking (such as the HEAP
+ * type). In this case it's still possible for net_buf_alloc() to
+ * fail (return NULL) even if it was given K_FOREVER.
+ *
+ * @return New buffer or NULL if out of buffers.
+ */
+#if CONFIG_BLE_MESH_NET_BUF_LOG
+struct net_buf *net_buf_alloc_fixed_debug(struct net_buf_pool *pool, int32_t timeout,
+ const char *func, int line);
+#define net_buf_alloc_fixed(_pool, _timeout) \
+ net_buf_alloc_fixed_debug(_pool, _timeout, __func__, __LINE__)
+#else
+struct net_buf *net_buf_alloc_fixed(struct net_buf_pool *pool, int32_t timeout);
+#endif
+
+/**
+ * @def net_buf_alloc
+ *
+ * @copydetails net_buf_alloc_fixed
+ */
+#define net_buf_alloc(pool, timeout) net_buf_alloc_fixed(pool, timeout)
+
+/**
+ * @brief Reset buffer
+ *
+ * Reset buffer data and flags so it can be reused for other purposes.
+ *
+ * @param buf Buffer to reset.
+ */
+void net_buf_reset(struct net_buf *buf);
+
+/**
+ * @def net_buf_reserve
+ * @brief Initialize buffer with the given headroom.
+ *
+ * The buffer is not expected to contain any data when this API is called.
+ *
+ * @param buf Buffer to initialize.
+ * @param reserve How much headroom to reserve.
+ */
+#define net_buf_reserve(buf, reserve) net_buf_simple_reserve(&(buf)->b, reserve)
+
+/**
+ * @brief Put a buffer into a list
+ *
+ * Put a buffer to the end of a list. If the buffer contains follow-up
+ * fragments this function will take care of inserting them as well
+ * into the list.
+ *
+ * @param list Which list to append the buffer to.
+ * @param buf Buffer.
+ */
+void net_buf_slist_put(sys_slist_t *list, struct net_buf *buf);
+
+/**
+ * @brief Get a buffer from a list.
+ *
+ * Get buffer from a list. If the buffer had any fragments, these will
+ * automatically be recovered from the list as well and be placed to
+ * the buffer's fragment list.
+ *
+ * @param list Which list to take the buffer from.
+ *
+ * @return New buffer or NULL if the FIFO is empty.
+ */
+struct net_buf *net_buf_slist_get(sys_slist_t *list);
+
+/**
+ * @brief Decrements the reference count of a buffer.
+ *
+ * Decrements the reference count of a buffer and puts it back into the
+ * pool if the count reaches zero.
+ *
+ * @param buf A valid pointer on a buffer
+ */
+#if CONFIG_BLE_MESH_NET_BUF_LOG
+void net_buf_unref_debug(struct net_buf *buf, const char *func, int line);
+#define net_buf_unref(_buf) \
+ net_buf_unref_debug(_buf, __func__, __LINE__)
+#else
+void net_buf_unref(struct net_buf *buf);
+#endif
+
+/**
+ * @brief Increment the reference count of a buffer.
+ *
+ * @param buf A valid pointer on a buffer
+ *
+ * @return the buffer newly referenced
+ */
+struct net_buf *net_buf_ref(struct net_buf *buf);
+
+/**
+ * @brief Get a pointer to the user data of a buffer.
+ *
+ * @param buf A valid pointer on a buffer
+ *
+ * @return Pointer to the user data of the buffer.
+ */
+static inline void *net_buf_user_data(struct net_buf *buf)
+{
+ return (void *)buf->user_data;
+}
+
+/**
+ * @def net_buf_add
+ * @brief Prepare data to be added at the end of the buffer
+ *
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param len Number of bytes to increment the length with.
+ *
+ * @return The original tail of the buffer.
+ */
+#define net_buf_add(buf, len) net_buf_simple_add(&(buf)->b, len)
+
+/**
+ * @def net_buf_add_mem
+ * @brief Copy bytes from memory to the end of the buffer
+ *
+ * Copies the given number of bytes to the end of the buffer. Increments the
+ * data length of the buffer to account for more data at the end.
+ *
+ * @param buf Buffer to update.
+ * @param mem Location of data to be added.
+ * @param len Length of data to be added
+ *
+ * @return The original tail of the buffer.
+ */
+#define net_buf_add_mem(buf, mem, len) net_buf_simple_add_mem(&(buf)->b, mem, len)
+
+/**
+ * @def net_buf_add_u8
+ * @brief Add (8-bit) byte at the end of the buffer
+ *
+ * Adds a byte at the end of the buffer. Increments the data length of
+ * the buffer to account for more data at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val byte value to be added.
+ *
+ * @return Pointer to the value added
+ */
+#define net_buf_add_u8(buf, val) net_buf_simple_add_u8(&(buf)->b, val)
+
+/**
+ * @def net_buf_add_le16
+ * @brief Add 16-bit value at the end of the buffer
+ *
+ * Adds 16-bit value in little endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 16-bit value to be added.
+ */
+#define net_buf_add_le16(buf, val) net_buf_simple_add_le16(&(buf)->b, val)
+
+/**
+ * @def net_buf_add_be16
+ * @brief Add 16-bit value at the end of the buffer
+ *
+ * Adds 16-bit value in big endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 16-bit value to be added.
+ */
+#define net_buf_add_be16(buf, val) net_buf_simple_add_be16(&(buf)->b, val)
+
+/**
+ * @def net_buf_add_le24
+ * @brief Add 24-bit value at the end of the buffer
+ *
+ * Adds 24-bit value in little endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 24-bit value to be added.
+ */
+#define net_buf_add_le24(buf, val) net_buf_simple_add_le24(&(buf)->b, val)
+
+/**
+ * @def net_buf_add_be24
+ * @brief Add 24-bit value at the end of the buffer
+ *
+ * Adds 24-bit value in big endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 24-bit value to be added.
+ */
+#define net_buf_add_be24(buf, val) net_buf_simple_add_be24(&(buf)->b, val)
+
+/**
+ * @def net_buf_add_le32
+ * @brief Add 32-bit value at the end of the buffer
+ *
+ * Adds 32-bit value in little endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 32-bit value to be added.
+ */
+#define net_buf_add_le32(buf, val) net_buf_simple_add_le32(&(buf)->b, val)
+
+/**
+ * @def net_buf_add_be32
+ * @brief Add 32-bit value at the end of the buffer
+ *
+ * Adds 32-bit value in big endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 32-bit value to be added.
+ */
+#define net_buf_add_be32(buf, val) net_buf_simple_add_be32(&(buf)->b, val)
+
+/**
+ * @def net_buf_add_le48
+ * @brief Add 48-bit value at the end of the buffer
+ *
+ * Adds 48-bit value in little endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 48-bit value to be added.
+ */
+#define net_buf_add_le48(buf, val) net_buf_simple_add_le48(&(buf)->b, val)
+
+/**
+ * @def net_buf_add_be48
+ * @brief Add 48-bit value at the end of the buffer
+ *
+ * Adds 48-bit value in big endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 48-bit value to be added.
+ */
+#define net_buf_add_be48(buf, val) net_buf_simple_add_be48(&(buf)->b, val)
+
+/**
+ * @def net_buf_add_le64
+ * @brief Add 64-bit value at the end of the buffer
+ *
+ * Adds 64-bit value in little endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 64-bit value to be added.
+ */
+#define net_buf_add_le64(buf, val) net_buf_simple_add_le64(&(buf)->b, val)
+
+/**
+ * @def net_buf_add_be64
+ * @brief Add 64-bit value at the end of the buffer
+ *
+ * Adds 64-bit value in big endian format at the end of buffer.
+ * Increments the data length of a buffer to account for more data
+ * at the end.
+ *
+ * @param buf Buffer to update.
+ * @param val 64-bit value to be added.
+ */
+#define net_buf_add_be64(buf, val) net_buf_simple_add_be64(&(buf)->b, val)
+
+/**
+ * @def net_buf_push
+ * @brief Push data to the beginning of the buffer.
+ *
+ * Modifies the data pointer and buffer length to account for more data
+ * in the beginning of the buffer.
+ *
+ * @param buf Buffer to update.
+ * @param len Number of bytes to add to the beginning.
+ *
+ * @return The new beginning of the buffer data.
+ */
+#define net_buf_push(buf, len) net_buf_simple_push(&(buf)->b, len)
+
+/**
+ * @def net_buf_push_le16
+ * @brief Push 16-bit value to the beginning of the buffer
+ *
+ * Adds 16-bit value in little endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 16-bit value to be pushed to the buffer.
+ */
+#define net_buf_push_le16(buf, val) net_buf_simple_push_le16(&(buf)->b, val)
+
+/**
+ * @def net_buf_push_be16
+ * @brief Push 16-bit value to the beginning of the buffer
+ *
+ * Adds 16-bit value in little endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 16-bit value to be pushed to the buffer.
+ */
+#define net_buf_push_be16(buf, val) net_buf_simple_push_be16(&(buf)->b, val)
+
+/**
+ * @def net_buf_push_u8
+ * @brief Push 8-bit value to the beginning of the buffer
+ *
+ * Adds 8-bit value the beginning of the buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 8-bit value to be pushed to the buffer.
+ */
+#define net_buf_push_u8(buf, val) net_buf_simple_push_u8(&(buf)->b, val)
+
+/**
+ * @def net_buf_push_le24
+ * @brief Push 24-bit value to the beginning of the buffer
+ *
+ * Adds 24-bit value in little endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 24-bit value to be pushed to the buffer.
+ */
+#define net_buf_push_le24(buf, val) net_buf_simple_push_le24(&(buf)->b, val)
+
+/**
+ * @def net_buf_push_be24
+ * @brief Push 24-bit value to the beginning of the buffer
+ *
+ * Adds 24-bit value in little endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 24-bit value to be pushed to the buffer.
+ */
+#define net_buf_push_be24(buf, val) net_buf_simple_push_be24(&(buf)->b, val)
+
+/**
+ * @def net_buf_push_le32
+ * @brief Push 32-bit value to the beginning of the buffer
+ *
+ * Adds 32-bit value in little endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 32-bit value to be pushed to the buffer.
+ */
+#define net_buf_push_le32(buf, val) net_buf_simple_push_le32(&(buf)->b, val)
+
+/**
+ * @def net_buf_push_be32
+ * @brief Push 32-bit value to the beginning of the buffer
+ *
+ * Adds 32-bit value in little endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 32-bit value to be pushed to the buffer.
+ */
+#define net_buf_push_be32(buf, val) net_buf_simple_push_be32(&(buf)->b, val)
+
+/**
+ * @def net_buf_push_le48
+ * @brief Push 48-bit value to the beginning of the buffer
+ *
+ * Adds 48-bit value in little endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 48-bit value to be pushed to the buffer.
+ */
+#define net_buf_push_le48(buf, val) net_buf_simple_push_le48(&(buf)->b, val)
+
+/**
+ * @def net_buf_push_be48
+ * @brief Push 48-bit value to the beginning of the buffer
+ *
+ * Adds 48-bit value in little endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 48-bit value to be pushed to the buffer.
+ */
+#define net_buf_push_be48(buf, val) net_buf_simple_push_be48(&(buf)->b, val)
+
+/**
+ * @def net_buf_push_le64
+ * @brief Push 64-bit value to the beginning of the buffer
+ *
+ * Adds 64-bit value in little endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 64-bit value to be pushed to the buffer.
+ */
+#define net_buf_push_le64(buf, val) net_buf_simple_push_le64(&(buf)->b, val)
+
+/**
+ * @def net_buf_push_be64
+ * @brief Push 64-bit value to the beginning of the buffer
+ *
+ * Adds 64-bit value in little endian format to the beginning of the
+ * buffer.
+ *
+ * @param buf Buffer to update.
+ * @param val 64-bit value to be pushed to the buffer.
+ */
+#define net_buf_push_be64(buf, val) net_buf_simple_push_be64(&(buf)->b, val)
+
+/**
+ * @def net_buf_pull
+ * @brief Remove data from the beginning of the buffer.
+ *
+ * Removes data from the beginning of the buffer by modifying the data
+ * pointer and buffer length.
+ *
+ * @param buf Buffer to update.
+ * @param len Number of bytes to remove.
+ *
+ * @return New beginning of the buffer data.
+ */
+#define net_buf_pull(buf, len) net_buf_simple_pull(&(buf)->b, len)
+
+/**
+ * @def net_buf_pull_mem
+ * @brief Remove data from the beginning of the buffer.
+ *
+ * Removes data from the beginning of the buffer by modifying the data
+ * pointer and buffer length.
+ *
+ * @param buf Buffer to update.
+ * @param len Number of bytes to remove.
+ *
+ * @return Pointer to the old beginning of the buffer data.
+ */
+#define net_buf_pull_mem(buf, len) net_buf_simple_pull_mem(&(buf)->b, len)
+
+/**
+ * @def net_buf_pull_u8
+ * @brief Remove a 8-bit value from the beginning of the buffer
+ *
+ * Same idea as with net_buf_pull(), but a helper for operating on
+ * 8-bit values.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return The 8-bit removed value
+ */
+#define net_buf_pull_u8(buf) net_buf_simple_pull_u8(&(buf)->b)
+
+/**
+ * @def net_buf_pull_le16
+ * @brief Remove and convert 16 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_pull(), but a helper for operating on
+ * 16-bit little endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 16-bit value converted from little endian to host endian.
+ */
+#define net_buf_pull_le16(buf) net_buf_simple_pull_le16(&(buf)->b)
+
+/**
+ * @def net_buf_pull_be16
+ * @brief Remove and convert 16 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_pull(), but a helper for operating on
+ * 16-bit big endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 16-bit value converted from big endian to host endian.
+ */
+#define net_buf_pull_be16(buf) net_buf_simple_pull_be16(&(buf)->b)
+
+/**
+ * @def net_buf_pull_le24
+ * @brief Remove and convert 24 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_pull(), but a helper for operating on
+ * 24-bit little endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 24-bit value converted from little endian to host endian.
+ */
+#define net_buf_pull_le24(buf) net_buf_simple_pull_le24(&(buf)->b)
+
+/**
+ * @def net_buf_pull_be24
+ * @brief Remove and convert 24 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_pull(), but a helper for operating on
+ * 24-bit big endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 24-bit value converted from big endian to host endian.
+ */
+#define net_buf_pull_be24(buf) net_buf_simple_pull_be24(&(buf)->b)
+
+/**
+ * @def net_buf_pull_le32
+ * @brief Remove and convert 32 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_pull(), but a helper for operating on
+ * 32-bit little endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 32-bit value converted from little endian to host endian.
+ */
+#define net_buf_pull_le32(buf) net_buf_simple_pull_le32(&(buf)->b)
+
+/**
+ * @def net_buf_pull_be32
+ * @brief Remove and convert 32 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_pull(), but a helper for operating on
+ * 32-bit big endian data.
+ *
+ * @param buf A valid pointer on a buffer
+ *
+ * @return 32-bit value converted from big endian to host endian.
+ */
+#define net_buf_pull_be32(buf) net_buf_simple_pull_be32(&(buf)->b)
+
+/**
+ * @def net_buf_pull_le48
+ * @brief Remove and convert 48 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_pull(), but a helper for operating on
+ * 48-bit little endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 48-bit value converted from little endian to host endian.
+ */
+#define net_buf_pull_le48(buf) net_buf_simple_pull_le48(&(buf)->b)
+
+/**
+ * @def net_buf_pull_be48
+ * @brief Remove and convert 48 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_pull(), but a helper for operating on
+ * 48-bit big endian data.
+ *
+ * @param buf A valid pointer on a buffer
+ *
+ * @return 48-bit value converted from big endian to host endian.
+ */
+#define net_buf_pull_be48(buf) net_buf_simple_pull_be48(&(buf)->b)
+
+/**
+ * @def net_buf_pull_le64
+ * @brief Remove and convert 64 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_pull(), but a helper for operating on
+ * 64-bit little endian data.
+ *
+ * @param buf A valid pointer on a buffer.
+ *
+ * @return 64-bit value converted from little endian to host endian.
+ */
+#define net_buf_pull_le64(buf) net_buf_simple_pull_le64(&(buf)->b)
+
+/**
+ * @def net_buf_pull_be64
+ * @brief Remove and convert 64 bits from the beginning of the buffer.
+ *
+ * Same idea as with net_buf_pull(), but a helper for operating on
+ * 64-bit big endian data.
+ *
+ * @param buf A valid pointer on a buffer
+ *
+ * @return 64-bit value converted from big endian to host endian.
+ */
+#define net_buf_pull_be64(buf) net_buf_simple_pull_be64(&(buf)->b)
+
+/**
+ * @def net_buf_tailroom
+ * @brief Check buffer tailroom.
+ *
+ * Check how much free space there is at the end of the buffer.
+ *
+ * @param buf A valid pointer on a buffer
+ *
+ * @return Number of bytes available at the end of the buffer.
+ */
+#define net_buf_tailroom(buf) net_buf_simple_tailroom(&(buf)->b)
+
+/**
+ * @def net_buf_headroom
+ * @brief Check buffer headroom.
+ *
+ * Check how much free space there is in the beginning of the buffer.
+ *
+ * buf A valid pointer on a buffer
+ *
+ * @return Number of bytes available in the beginning of the buffer.
+ */
+#define net_buf_headroom(buf) net_buf_simple_headroom(&(buf)->b)
+
+/**
+ * @def net_buf_tail
+ * @brief Get the tail pointer for a buffer.
+ *
+ * Get a pointer to the end of the data in a buffer.
+ *
+ * @param buf Buffer.
+ *
+ * @return Tail pointer for the buffer.
+ */
+#define net_buf_tail(buf) net_buf_simple_tail(&(buf)->b)
+
+/**
+ * @brief Find the last fragment in the fragment list.
+ *
+ * @return Pointer to last fragment in the list.
+ */
+struct net_buf *net_buf_frag_last(struct net_buf *frags);
+
+/**
+ * @brief Insert a new fragment to a chain of bufs.
+ *
+ * Insert a new fragment into the buffer fragments list after the parent.
+ *
+ * Note: This function takes ownership of the fragment reference so the
+ * caller is not required to unref.
+ *
+ * @param parent Parent buffer/fragment.
+ * @param frag Fragment to insert.
+ */
+void net_buf_frag_insert(struct net_buf *parent, struct net_buf *frag);
+
+/**
+ * @brief Add a new fragment to the end of a chain of bufs.
+ *
+ * Append a new fragment into the buffer fragments list.
+ *
+ * Note: This function takes ownership of the fragment reference so the
+ * caller is not required to unref.
+ *
+ * @param head Head of the fragment chain.
+ * @param frag Fragment to add.
+ *
+ * @return New head of the fragment chain. Either head (if head
+ * was non-NULL) or frag (if head was NULL).
+ */
+struct net_buf *net_buf_frag_add(struct net_buf *head, struct net_buf *frag);
+
+/**
+ * @brief Delete existing fragment from a chain of bufs.
+ *
+ * @param parent Parent buffer/fragment, or NULL if there is no parent.
+ * @param frag Fragment to delete.
+ *
+ * @return Pointer to the buffer following the fragment, or NULL if it
+ * had no further fragments.
+ */
+#if CONFIG_BLE_MESH_NET_BUF_LOG
+struct net_buf *net_buf_frag_del_debug(struct net_buf *parent,
+ struct net_buf *frag,
+ const char *func, int line);
+#define net_buf_frag_del(_parent, _frag) \
+ net_buf_frag_del_debug(_parent, _frag, __func__, __LINE__)
+#else
+struct net_buf *net_buf_frag_del(struct net_buf *parent, struct net_buf *frag);
+#endif
+
+/**
+ * @brief Copy bytes from net_buf chain starting at offset to linear buffer
+ *
+ * Copy (extract) @a len bytes from @a src net_buf chain, starting from @a
+ * offset in it, to a linear buffer @a dst. Return number of bytes actually
+ * copied, which may be less than requested, if net_buf chain doesn't have
+ * enough data, or destination buffer is too small.
+ *
+ * @param dst Destination buffer
+ * @param dst_len Destination buffer length
+ * @param src Source net_buf chain
+ * @param offset Starting offset to copy from
+ * @param len Number of bytes to copy
+ * @return number of bytes actually copied
+ */
+size_t net_buf_linearize(void *dst, size_t dst_len,
+ struct net_buf *src, size_t offset, size_t len);
+
+/**
+ * @typedef net_buf_allocator_cb
+ * @brief Network buffer allocator callback.
+ *
+ * @details The allocator callback is called when net_buf_append_bytes
+ * needs to allocate a new net_buf.
+ *
+ * @param timeout Affects the action taken should the net buf pool be empty.
+ * If K_NO_WAIT, then return immediately. If K_FOREVER, then
+ * wait as long as necessary. Otherwise, wait up to the specified
+ * number of milliseconds before timing out.
+ * @param user_data The user data given in net_buf_append_bytes call.
+ * @return pointer to allocated net_buf or NULL on error.
+ */
+typedef struct net_buf *(*net_buf_allocator_cb)(int32_t timeout, void *user_data);
+
+/**
+ * @brief Append data to a list of net_buf
+ *
+ * @details Append data to a net_buf. If there is not enough space in the
+ * net_buf then more net_buf will be added, unless there are no free net_buf
+ * and timeout occurs.
+ *
+ * @param buf Network buffer.
+ * @param len Total length of input data
+ * @param value Data to be added
+ * @param timeout Timeout is passed to the net_buf allocator callback.
+ * @param allocate_cb When a new net_buf is required, use this callback.
+ * @param user_data A user data pointer to be supplied to the allocate_cb.
+ * This pointer is can be anything from a mem_pool or a net_pkt, the
+ * logic is left up to the allocate_cb function.
+ *
+ * @return Length of data actually added. This may be less than input
+ * length if other timeout than K_FOREVER was used, and there
+ * were no free fragments in a pool to accommodate all data.
+ */
+size_t net_buf_append_bytes(struct net_buf *buf, size_t len,
+ const void *value, int32_t timeout,
+ net_buf_allocator_cb allocate_cb, void *user_data);
+
+/**
+ * @brief Skip N number of bytes in a net_buf
+ *
+ * @details Skip N number of bytes starting from fragment's offset. If the total
+ * length of data is placed in multiple fragments, this function will skip from
+ * all fragments until it reaches N number of bytes. Any fully skipped buffers
+ * are removed from the net_buf list.
+ *
+ * @param buf Network buffer.
+ * @param len Total length of data to be skipped.
+ *
+ * @return Pointer to the fragment or
+ * NULL and pos is 0 after successful skip,
+ * NULL and pos is 0xffff otherwise.
+ */
+static inline struct net_buf *net_buf_skip(struct net_buf *buf, size_t len)
+{
+ while (buf && len--) {
+ net_buf_pull_u8(buf);
+ if (!buf->len) {
+ buf = net_buf_frag_del(NULL, buf);
+ }
+ }
+
+ return buf;
+}
+
+/**
+ * @brief Calculate amount of bytes stored in fragments.
+ *
+ * Calculates the total amount of data stored in the given buffer and the
+ * fragments linked to it.
+ *
+ * @param buf Buffer to start off with.
+ *
+ * @return Number of bytes in the buffer and its fragments.
+ */
+static inline size_t net_buf_frags_len(struct net_buf *buf)
+{
+ size_t bytes = 0;
+
+ while (buf) {
+ bytes += buf->len;
+ buf = buf->frags;
+ }
+
+ return bytes;
+}
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_BUF_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/byteorder.h b/lib/bt/esp_ble_mesh/common/include/mesh/byteorder.h
new file mode 100644
index 00000000..6926b804
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/byteorder.h
@@ -0,0 +1,599 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2016 Intel Corporation.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _BLE_MESH_BYTEORDER_H_
+#define _BLE_MESH_BYTEORDER_H_
+
+#include "mesh/types.h"
+#include "mesh/trace.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Internal helpers only used by the sys_* APIs further below */
+#ifndef __bswap_16
+#define __bswap_16(x) ((uint16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))
+#endif
+
+#ifndef __bswap_24
+#define __bswap_24(x) ((uint32_t) ((((x) >> 16) & 0xff) | \
+ (((x)) & 0xff00) | \
+ (((x) & 0xff) << 16)))
+#endif
+
+#ifndef __bswap_32
+#define __bswap_32(x) ((uint32_t) ((((x) >> 24) & 0xff) | \
+ (((x) >> 8) & 0xff00) | \
+ (((x) & 0xff00) << 8) | \
+ (((x) & 0xff) << 24)))
+#endif
+
+#ifndef __bswap_48
+#define __bswap_48(x) ((uint64_t) ((((x) >> 40) & 0xff) | \
+ (((x) >> 24) & 0xff00) | \
+ (((x) >> 8) & 0xff0000) | \
+ (((x) & 0xff0000) << 8) | \
+ (((x) & 0xff00) << 24) | \
+ (((x) & 0xff) << 40)))
+#endif
+
+#ifndef __bswap_64
+#define __bswap_64(x) ((uint64_t) ((((x) >> 56) & 0xff) | \
+ (((x) >> 40) & 0xff00) | \
+ (((x) >> 24) & 0xff0000) | \
+ (((x) >> 8) & 0xff000000) | \
+ (((x) & 0xff000000) << 8) | \
+ (((x) & 0xff0000) << 24) | \
+ (((x) & 0xff00) << 40) | \
+ (((x) & 0xff) << 56)))
+#endif
+
+/** @def sys_le16_to_cpu
+ * @brief Convert 16-bit integer from little-endian to host endianness.
+ *
+ * @param val 16-bit integer in little-endian format.
+ *
+ * @return 16-bit integer in host endianness.
+ */
+
+/** @def sys_cpu_to_le16
+ * @brief Convert 16-bit integer from host endianness to little-endian.
+ *
+ * @param val 16-bit integer in host endianness.
+ *
+ * @return 16-bit integer in little-endian format.
+ */
+
+/** @def sys_le24_to_cpu
+ * @brief Convert 24-bit integer from little-endian to host endianness.
+ *
+ * @param val 24-bit integer in little-endian format.
+ *
+ * @return 24-bit integer in host endianness.
+ */
+
+/** @def sys_cpu_to_le24
+ * @brief Convert 24-bit integer from host endianness to little-endian.
+ *
+ * @param val 24-bit integer in host endianness.
+ *
+ * @return 24-bit integer in little-endian format.
+ */
+
+/** @def sys_le32_to_cpu
+ * @brief Convert 32-bit integer from little-endian to host endianness.
+ *
+ * @param val 32-bit integer in little-endian format.
+ *
+ * @return 32-bit integer in host endianness.
+ */
+
+/** @def sys_cpu_to_le32
+ * @brief Convert 32-bit integer from host endianness to little-endian.
+ *
+ * @param val 32-bit integer in host endianness.
+ *
+ * @return 32-bit integer in little-endian format.
+ */
+
+/** @def sys_le48_to_cpu
+ * @brief Convert 48-bit integer from little-endian to host endianness.
+ *
+ * @param val 48-bit integer in little-endian format.
+ *
+ * @return 48-bit integer in host endianness.
+ */
+
+/** @def sys_cpu_to_le48
+ * @brief Convert 48-bit integer from host endianness to little-endian.
+ *
+ * @param val 48-bit integer in host endianness.
+ *
+ * @return 48-bit integer in little-endian format.
+ */
+
+/** @def sys_be16_to_cpu
+ * @brief Convert 16-bit integer from big-endian to host endianness.
+ *
+ * @param val 16-bit integer in big-endian format.
+ *
+ * @return 16-bit integer in host endianness.
+ */
+
+/** @def sys_cpu_to_be16
+ * @brief Convert 16-bit integer from host endianness to big-endian.
+ *
+ * @param val 16-bit integer in host endianness.
+ *
+ * @return 16-bit integer in big-endian format.
+ */
+
+/** @def sys_be24_to_cpu
+ * @brief Convert 24-bit integer from big-endian to host endianness.
+ *
+ * @param val 24-bit integer in big-endian format.
+ *
+ * @return 24-bit integer in host endianness.
+ */
+
+/** @def sys_cpu_to_be24
+ * @brief Convert 24-bit integer from host endianness to big-endian.
+ *
+ * @param val 24-bit integer in host endianness.
+ *
+ * @return 24-bit integer in big-endian format.
+ */
+
+/** @def sys_be32_to_cpu
+ * @brief Convert 32-bit integer from big-endian to host endianness.
+ *
+ * @param val 32-bit integer in big-endian format.
+ *
+ * @return 32-bit integer in host endianness.
+ */
+
+/** @def sys_cpu_to_be32
+ * @brief Convert 32-bit integer from host endianness to big-endian.
+ *
+ * @param val 32-bit integer in host endianness.
+ *
+ * @return 32-bit integer in big-endian format.
+ */
+
+/** @def sys_be48_to_cpu
+ * @brief Convert 48-bit integer from big-endian to host endianness.
+ *
+ * @param val 48-bit integer in big-endian format.
+ *
+ * @return 48-bit integer in host endianness.
+ */
+
+/** @def sys_cpu_to_be48
+ * @brief Convert 48-bit integer from host endianness to big-endian.
+ *
+ * @param val 48-bit integer in host endianness.
+ *
+ * @return 48-bit integer in big-endian format.
+ */
+
+#ifndef sys_le16_to_cpu
+#define sys_le16_to_cpu(val) (val)
+#endif
+#ifndef sys_cpu_to_le16
+#define sys_cpu_to_le16(val) (val)
+#endif
+#ifndef sys_le24_to_cpu
+#define sys_le24_to_cpu(val) (val)
+#endif
+#ifndef sys_cpu_to_le24
+#define sys_cpu_to_le24(val) (val)
+#endif
+#ifndef sys_le32_to_cpu
+#define sys_le32_to_cpu(val) (val)
+#endif
+#ifndef sys_cpu_to_le32
+#define sys_cpu_to_le32(val) (val)
+#endif
+#ifndef sys_le48_to_cpu
+#define sys_le48_to_cpu(val) (val)
+#endif
+#ifndef sys_cpu_to_le48
+#define sys_cpu_to_le48(val) (val)
+#endif
+#ifndef sys_le64_to_cpu
+#define sys_le64_to_cpu(val) (val)
+#endif
+#ifndef sys_cpu_to_le64
+#define sys_cpu_to_le64(val) (val)
+#endif
+#ifndef sys_be16_to_cpu
+#define sys_be16_to_cpu(val) __bswap_16(val)
+#endif
+#ifndef sys_cpu_to_be16
+#define sys_cpu_to_be16(val) __bswap_16(val)
+#endif
+#ifndef sys_be24_to_cpu
+#define sys_be24_to_cpu(val) __bswap_24(val)
+#endif
+#ifndef sys_cpu_to_be24
+#define sys_cpu_to_be24(val) __bswap_24(val)
+#endif
+#ifndef sys_be32_to_cpu
+#define sys_be32_to_cpu(val) __bswap_32(val)
+#endif
+#ifndef sys_cpu_to_be32
+#define sys_cpu_to_be32(val) __bswap_32(val)
+#endif
+#ifndef sys_be48_to_cpu
+#define sys_be48_to_cpu(val) __bswap_48(val)
+#endif
+#ifndef sys_cpu_to_be48
+#define sys_cpu_to_be48(val) __bswap_48(val)
+#endif
+#ifndef sys_be64_to_cpu
+#define sys_be64_to_cpu(val) __bswap_64(val)
+#endif
+#ifndef sys_cpu_to_be64
+#define sys_cpu_to_be64(val) __bswap_64(val)
+#endif
+
+/**
+ * @brief Put a 16-bit integer as big-endian to arbitrary location.
+ *
+ * Put a 16-bit integer, originally in host endianness, to a
+ * potentially unaligned memory location in big-endian format.
+ *
+ * @param val 16-bit integer in host endianness.
+ * @param dst Destination memory address to store the result.
+ */
+static inline void sys_put_be16(uint16_t val, uint8_t dst[2])
+{
+ dst[0] = val >> 8;
+ dst[1] = val;
+}
+
+/**
+ * @brief Put a 24-bit integer as big-endian to arbitrary location.
+ *
+ * Put a 24-bit integer, originally in host endianness, to a
+ * potentially unaligned memory location in big-endian format.
+ *
+ * @param val 24-bit integer in host endianness.
+ * @param dst Destination memory address to store the result.
+ */
+static inline void sys_put_be24(uint32_t val, uint8_t dst[3])
+{
+ dst[0] = val >> 16;
+ sys_put_be16(val, &dst[1]);
+}
+
+/**
+ * @brief Put a 32-bit integer as big-endian to arbitrary location.
+ *
+ * Put a 32-bit integer, originally in host endianness, to a
+ * potentially unaligned memory location in big-endian format.
+ *
+ * @param val 32-bit integer in host endianness.
+ * @param dst Destination memory address to store the result.
+ */
+static inline void sys_put_be32(uint32_t val, uint8_t dst[4])
+{
+ sys_put_be16(val >> 16, dst);
+ sys_put_be16(val, &dst[2]);
+}
+
+/**
+ * @brief Put a 48-bit integer as big-endian to arbitrary location.
+ *
+ * Put a 48-bit integer, originally in host endianness, to a
+ * potentially unaligned memory location in big-endian format.
+ *
+ * @param val 48-bit integer in host endianness.
+ * @param dst Destination memory address to store the result.
+ */
+static inline void sys_put_be48(uint64_t val, uint8_t dst[6])
+{
+ sys_put_be16(val >> 32, dst);
+ sys_put_be32(val, &dst[2]);
+}
+
+/**
+ * @brief Put a 64-bit integer as big-endian to arbitrary location.
+ *
+ * Put a 64-bit integer, originally in host endianness, to a
+ * potentially unaligned memory location in big-endian format.
+ *
+ * @param val 64-bit integer in host endianness.
+ * @param dst Destination memory address to store the result.
+ */
+static inline void sys_put_be64(uint64_t val, uint8_t dst[8])
+{
+ sys_put_be32(val >> 32, dst);
+ sys_put_be32(val, &dst[4]);
+}
+
+/**
+ * @brief Put a 16-bit integer as little-endian to arbitrary location.
+ *
+ * Put a 16-bit integer, originally in host endianness, to a
+ * potentially unaligned memory location in little-endian format.
+ *
+ * @param val 16-bit integer in host endianness.
+ * @param dst Destination memory address to store the result.
+ */
+static inline void sys_put_le16(uint16_t val, uint8_t dst[2])
+{
+ dst[0] = val;
+ dst[1] = val >> 8;
+}
+
+/**
+ * @brief Put a 24-bit integer as little-endian to arbitrary location.
+ *
+ * Put a 24-bit integer, originally in host endianness, to a
+ * potentially unaligned memory location in little-endian format.
+ *
+ * @param val 24-bit integer in host endianness.
+ * @param dst Destination memory address to store the result.
+ */
+static inline void sys_put_le24(uint32_t val, uint8_t dst[3])
+{
+ sys_put_le16(val, dst);
+ dst[2] = val >> 16;
+}
+
+/**
+ * @brief Put a 32-bit integer as little-endian to arbitrary location.
+ *
+ * Put a 32-bit integer, originally in host endianness, to a
+ * potentially unaligned memory location in little-endian format.
+ *
+ * @param val 32-bit integer in host endianness.
+ * @param dst Destination memory address to store the result.
+ */
+static inline void sys_put_le32(uint32_t val, uint8_t dst[4])
+{
+ sys_put_le16(val, dst);
+ sys_put_le16(val >> 16, &dst[2]);
+}
+
+/**
+ * @brief Put a 48-bit integer as little-endian to arbitrary location.
+ *
+ * Put a 48-bit integer, originally in host endianness, to a
+ * potentially unaligned memory location in little-endian format.
+ *
+ * @param val 48-bit integer in host endianness.
+ * @param dst Destination memory address to store the result.
+ */
+static inline void sys_put_le48(uint64_t val, uint8_t dst[6])
+{
+ sys_put_le32(val, dst);
+ sys_put_le16(val >> 32, &dst[4]);
+}
+
+/**
+ * @brief Put a 64-bit integer as little-endian to arbitrary location.
+ *
+ * Put a 64-bit integer, originally in host endianness, to a
+ * potentially unaligned memory location in little-endian format.
+ *
+ * @param val 64-bit integer in host endianness.
+ * @param dst Destination memory address to store the result.
+ */
+static inline void sys_put_le64(uint64_t val, uint8_t dst[8])
+{
+ sys_put_le32(val, dst);
+ sys_put_le32(val >> 32, &dst[4]);
+}
+
+/**
+ * @brief Get a 16-bit integer stored in big-endian format.
+ *
+ * Get a 16-bit integer, stored in big-endian format in a potentially
+ * unaligned memory location, and convert it to the host endianness.
+ *
+ * @param src Location of the big-endian 16-bit integer to get.
+ *
+ * @return 16-bit integer in host endianness.
+ */
+static inline uint16_t sys_get_be16(const uint8_t src[2])
+{
+ return ((uint16_t)src[0] << 8) | src[1];
+}
+
+/**
+ * @brief Get a 24-bit integer stored in big-endian format.
+ *
+ * Get a 24-bit integer, stored in big-endian format in a potentially
+ * unaligned memory location, and convert it to the host endianness.
+ *
+ * @param src Location of the big-endian 24-bit integer to get.
+ *
+ * @return 24-bit integer in host endianness.
+ */
+static inline uint32_t sys_get_be24(const uint8_t src[3])
+{
+ return ((uint32_t)src[0] << 16) | sys_get_be16(&src[1]);
+}
+
+/**
+ * @brief Get a 32-bit integer stored in big-endian format.
+ *
+ * Get a 32-bit integer, stored in big-endian format in a potentially
+ * unaligned memory location, and convert it to the host endianness.
+ *
+ * @param src Location of the big-endian 32-bit integer to get.
+ *
+ * @return 32-bit integer in host endianness.
+ */
+static inline uint32_t sys_get_be32(const uint8_t src[4])
+{
+ return ((uint32_t)sys_get_be16(&src[0]) << 16) | sys_get_be16(&src[2]);
+}
+
+/**
+ * @brief Get a 48-bit integer stored in big-endian format.
+ *
+ * Get a 48-bit integer, stored in big-endian format in a potentially
+ * unaligned memory location, and convert it to the host endianness.
+ *
+ * @param src Location of the big-endian 48-bit integer to get.
+ *
+ * @return 48-bit integer in host endianness.
+ */
+static inline uint64_t sys_get_be48(const uint8_t src[6])
+{
+ return ((uint64_t)sys_get_be32(&src[0]) << 32) | sys_get_be16(&src[4]);
+}
+
+/**
+ * @brief Get a 64-bit integer stored in big-endian format.
+ *
+ * Get a 64-bit integer, stored in big-endian format in a potentially
+ * unaligned memory location, and convert it to the host endianness.
+ *
+ * @param src Location of the big-endian 64-bit integer to get.
+ *
+ * @return 64-bit integer in host endianness.
+ */
+static inline uint64_t sys_get_be64(const uint8_t src[8])
+{
+ return ((uint64_t)sys_get_be32(&src[0]) << 32) | sys_get_be32(&src[4]);
+}
+
+/**
+ * @brief Get a 16-bit integer stored in little-endian format.
+ *
+ * Get a 16-bit integer, stored in little-endian format in a potentially
+ * unaligned memory location, and convert it to the host endianness.
+ *
+ * @param src Location of the little-endian 16-bit integer to get.
+ *
+ * @return 16-bit integer in host endianness.
+ */
+static inline uint16_t sys_get_le16(const uint8_t src[2])
+{
+ return ((uint16_t)src[1] << 8) | src[0];
+}
+
+/**
+ * @brief Get a 24-bit integer stored in big-endian format.
+ *
+ * Get a 24-bit integer, stored in big-endian format in a potentially
+ * unaligned memory location, and convert it to the host endianness.
+ *
+ * @param src Location of the big-endian 24-bit integer to get.
+ *
+ * @return 24-bit integer in host endianness.
+ */
+static inline uint32_t sys_get_le24(const uint8_t src[3])
+{
+ return ((uint32_t)src[2] << 16) | sys_get_le16(&src[0]);
+}
+
+/**
+ * @brief Get a 32-bit integer stored in little-endian format.
+ *
+ * Get a 32-bit integer, stored in little-endian format in a potentially
+ * unaligned memory location, and convert it to the host endianness.
+ *
+ * @param src Location of the little-endian 32-bit integer to get.
+ *
+ * @return 32-bit integer in host endianness.
+ */
+static inline uint32_t sys_get_le32(const uint8_t src[4])
+{
+ return ((uint32_t)sys_get_le16(&src[2]) << 16) | sys_get_le16(&src[0]);
+}
+
+/**
+ * @brief Get a 48-bit integer stored in little-endian format.
+ *
+ * Get a 48-bit integer, stored in little-endian format in a potentially
+ * unaligned memory location, and convert it to the host endianness.
+ *
+ * @param src Location of the little-endian 48-bit integer to get.
+ *
+ * @return 48-bit integer in host endianness.
+ */
+static inline uint64_t sys_get_le48(const uint8_t src[6])
+{
+ return ((uint64_t)sys_get_le32(&src[2]) << 32) | sys_get_le16(&src[0]);
+}
+
+/**
+ * @brief Get a 64-bit integer stored in little-endian format.
+ *
+ * Get a 64-bit integer, stored in little-endian format in a potentially
+ * unaligned memory location, and convert it to the host endianness.
+ *
+ * @param src Location of the little-endian 64-bit integer to get.
+ *
+ * @return 64-bit integer in host endianness.
+ */
+static inline uint64_t sys_get_le64(const uint8_t src[8])
+{
+ return ((uint64_t)sys_get_le32(&src[4]) << 32) | sys_get_le32(&src[0]);
+}
+
+/**
+ * @brief Swap one buffer content into another
+ *
+ * Copy the content of src buffer into dst buffer in reversed order,
+ * i.e.: src[n] will be put in dst[end-n]
+ * Where n is an index and 'end' the last index in both arrays.
+ * The 2 memory pointers must be pointing to different areas, and have
+ * a minimum size of given length.
+ *
+ * @param dst A valid pointer on a memory area where to copy the data in
+ * @param src A valid pointer on a memory area where to copy the data from
+ * @param length Size of both dst and src memory areas
+ */
+static inline void sys_memcpy_swap(void *dst, const void *src, size_t length)
+{
+ uint8_t *pdst = (uint8_t *)dst;
+ const uint8_t *psrc = (const uint8_t *)src;
+
+ __ASSERT(((psrc < pdst && (psrc + length) <= pdst) ||
+ (psrc > pdst && (pdst + length) <= psrc)),
+ "Source and destination buffers must not overlap");
+
+ psrc += length - 1;
+
+ for (; length > 0; length--) {
+ *pdst++ = *psrc--;
+ }
+}
+
+/**
+ * @brief Swap buffer content
+ *
+ * In-place memory swap, where final content will be reversed.
+ * I.e.: buf[n] will be put in buf[end-n]
+ * Where n is an index and 'end' the last index of buf.
+ *
+ * @param buf A valid pointer on a memory area to swap
+ * @param length Size of buf memory area
+ */
+static inline void sys_mem_swap(void *buf, size_t length)
+{
+ size_t i;
+
+ for (i = 0; i < (length / 2); i++) {
+ uint8_t tmp = ((uint8_t *)buf)[i];
+
+ ((uint8_t *)buf)[i] = ((uint8_t *)buf)[length - 1 - i];
+ ((uint8_t *)buf)[length - 1 - i] = tmp;
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_BYTEORDER_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/common.h b/lib/bt/esp_ble_mesh/common/include/mesh/common.h
new file mode 100644
index 00000000..a1cfa673
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/common.h
@@ -0,0 +1,62 @@
+/*
+ * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/** @file
+ * @brief Bluetooth Mesh Model Common APIs.
+ */
+
+#ifndef _BLE_MESH_COMMON_H_
+#define _BLE_MESH_COMMON_H_
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "esp_attr.h"
+#include "esp_heap_caps.h"
+
+#include "mesh/byteorder.h"
+#include "mesh/ffs.h"
+#include "mesh/trace.h"
+#include "mesh/mutex.h"
+#include "mesh/access.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *bt_mesh_malloc(size_t size);
+
+void *bt_mesh_calloc(size_t size);
+
+void bt_mesh_free(void *ptr);
+
+/**
+ * @brief This function allocates memory to store outgoing message.
+ *
+ * @param[in] size: Length of memory allocated to store message value
+ *
+ * @return NULL-fail, pointer of a net_buf_simple structure-success
+ */
+struct net_buf_simple *bt_mesh_alloc_buf(uint16_t size);
+
+/**
+ * @brief This function releases the memory allocated for the outgoing message.
+ *
+ * @param[in] buf: Pointer to the net_buf_simple structure to be freed
+ *
+ * @return none
+ */
+void bt_mesh_free_buf(struct net_buf_simple *buf);
+
+int bt_mesh_rand(void *buf, size_t len);
+
+uint32_t bt_mesh_get_rand(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_COMMON_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/compiler.h b/lib/bt/esp_ble_mesh/common/include/mesh/compiler.h
new file mode 100644
index 00000000..c73e8dfb
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/compiler.h
@@ -0,0 +1,80 @@
+/*
+ * SPDX-FileCopyrightText: 2010-2014,2017 Wind River Systems, Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _BLE_MESH_COMPILER_H_
+#define _BLE_MESH_COMPILER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ___in_section(a, b, c)
+
+#define __in_section(a, b, c) ___in_section(a, b, c)
+
+#define __in_section_unique(seg) ___in_section(seg, __FILE__, __COUNTER__)
+
+#ifndef __packed
+#define __packed __attribute__((__packed__))
+#endif
+
+#ifndef __aligned
+#define __aligned(x) __attribute__((__aligned__(x)))
+#endif
+
+#ifndef __used
+#define __used __attribute__((__used__))
+#endif
+
+#ifndef ARG_UNUSED
+#define ARG_UNUSED(x) (void)(x)
+#endif
+
+#ifndef popcount
+#define popcount(x) __builtin_popcount(x)
+#endif
+
+#ifndef ALWAYS_INLINE
+#define ALWAYS_INLINE inline __attribute__((always_inline))
+#endif
+
+
+/*
+ * This is meant to be used in conjunction with __in_section() and similar
+ * where scattered structure instances are concatened together by the linker
+ * and walked by the code at run time just like a contiguous array of such
+ * structures.
+ *
+ * Assemblers and linkers may insert alignment padding by default whose
+ * size is larger than the natural alignment for those structures when
+ * gathering various section segments together, messing up the array walk.
+ * To prevent this, we need to provide an explicit alignment not to rely
+ * on the default that might just work by luck.
+ *
+ * Alignment statements in linker scripts are not sufficient as
+ * the assembler may add padding by itself to each segment when switching
+ * between sections within the same file even if it merges many such segments
+ * into a single section in the end.
+ */
+#ifndef Z_DECL_ALIGN
+#define Z_DECL_ALIGN(type) __aligned(__alignof(type)) type
+#endif
+
+/*
+ * Convenience helper combining __in_section() and Z_DECL_ALIGN().
+ * The section name is the struct type prepended with an underscore.
+ * The subsection is "static" and the subsubsection is the variable name.
+ */
+#ifndef Z_STRUCT_SECTION_ITERABLE
+#define Z_STRUCT_SECTION_ITERABLE(struct_type, name) \
+ Z_DECL_ALIGN(struct struct_type) name
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_COMPILER_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/config.h b/lib/bt/esp_ble_mesh/common/include/mesh/config.h
new file mode 100644
index 00000000..ab06eda8
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/config.h
@@ -0,0 +1,61 @@
+/*
+ * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _BLE_MESH_CONFIG_H_
+#define _BLE_MESH_CONFIG_H_
+
+#include "sdkconfig.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef CONFIG_BLE_MESH_PBA_SAME_TIME
+#define CONFIG_BLE_MESH_PBA_SAME_TIME 0
+#endif
+
+#ifndef CONFIG_BLE_MESH_PBG_SAME_TIME
+#define CONFIG_BLE_MESH_PBG_SAME_TIME 0
+#endif
+
+#define CONFIG_BLE_MESH_PRIVATE_BEACON (CONFIG_BLE_MESH_PRB_SRV || \
+ CONFIG_BLE_MESH_PRB_CLI)
+
+#define CONFIG_BLE_MESH_GENERIC_CLIENT (CONFIG_BLE_MESH_GENERIC_ONOFF_CLI || \
+ CONFIG_BLE_MESH_GENERIC_LEVEL_CLI || \
+ CONFIG_BLE_MESH_GENERIC_DEF_TRANS_TIME_CLI || \
+ CONFIG_BLE_MESH_GENERIC_POWER_ONOFF_CLI || \
+ CONFIG_BLE_MESH_GENERIC_POWER_LEVEL_CLI || \
+ CONFIG_BLE_MESH_GENERIC_BATTERY_CLI || \
+ CONFIG_BLE_MESH_GENERIC_LOCATION_CLI || \
+ CONFIG_BLE_MESH_GENERIC_PROPERTY_CLI)
+
+#define CONFIG_BLE_MESH_TIME_SCENE_CLIENT (CONFIG_BLE_MESH_TIME_CLI || \
+ CONFIG_BLE_MESH_SCENE_CLI || \
+ CONFIG_BLE_MESH_SCHEDULER_CLI)
+
+#define CONFIG_BLE_MESH_LIGHTING_CLIENT (CONFIG_BLE_MESH_LIGHT_LIGHTNESS_CLI || \
+ CONFIG_BLE_MESH_LIGHT_CTL_CLI || \
+ CONFIG_BLE_MESH_LIGHT_HSL_CLI || \
+ CONFIG_BLE_MESH_LIGHT_XYL_CLI || \
+ CONFIG_BLE_MESH_LIGHT_LC_CLI)
+
+#define CONFIG_BLE_MESH_SERVER_MODEL (CONFIG_BLE_MESH_GENERIC_SERVER || \
+ CONFIG_BLE_MESH_SENSOR_SERVER || \
+ CONFIG_BLE_MESH_TIME_SCENE_SERVER || \
+ CONFIG_BLE_MESH_LIGHTING_SERVER)
+
+#define CONFIG_BLE_MESH_BLE_COEX_SUPPORT (CONFIG_BLE_MESH_SUPPORT_BLE_ADV || \
+ CONFIG_BLE_MESH_SUPPORT_BLE_SCAN)
+
+#define CONFIG_BLE_MESH_PROXY_SOLIC (CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX || \
+ CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_CONFIG_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/dlist.h b/lib/bt/esp_ble_mesh/common/include/mesh/dlist.h
new file mode 100644
index 00000000..01e35f40
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/dlist.h
@@ -0,0 +1,498 @@
+/*
+ * SPDX-FileCopyrightText: 2013-2015 Wind River Systems, Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/**
+ * @file
+ * @brief Doubly-linked list implementation
+ *
+ * Doubly-linked list implementation using inline macros/functions.
+ * This API is not thread safe, and thus if a list is used across threads,
+ * calls to functions must be protected with synchronization primitives.
+ *
+ * The lists are expected to be initialized such that both the head and tail
+ * pointers point to the list itself. Initializing the lists in such a fashion
+ * simplifies the adding and removing of nodes to/from the list.
+ */
+
+#ifndef _BLE_MESH_DLIST_H_
+#define _BLE_MESH_DLIST_H_
+
+#include <stddef.h>
+#include "mesh/utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct _dnode {
+ union {
+ struct _dnode *head; /* ptr to head of list (sys_dlist_t) */
+ struct _dnode *next; /* ptr to next node (sys_dnode_t) */
+ };
+ union {
+ struct _dnode *tail; /* ptr to tail of list (sys_dlist_t) */
+ struct _dnode *prev; /* ptr to previous node (sys_dnode_t) */
+ };
+};
+
+typedef struct _dnode sys_dlist_t;
+typedef struct _dnode sys_dnode_t;
+
+/**
+ * @brief Provide the primitive to iterate on a list
+ * Note: the loop is unsafe and thus __dn should not be removed
+ *
+ * User _MUST_ add the loop statement curly braces enclosing its own code:
+ *
+ * SYS_DLIST_FOR_EACH_NODE(l, n) {
+ * <user code>
+ * }
+ *
+ * This and other SYS_DLIST_*() macros are not thread safe.
+ *
+ * @param __dl A pointer on a sys_dlist_t to iterate on
+ * @param __dn A sys_dnode_t pointer to peek each node of the list
+ */
+#define SYS_DLIST_FOR_EACH_NODE(__dl, __dn) \
+ for (__dn = sys_dlist_peek_head(__dl); __dn; \
+ __dn = sys_dlist_peek_next(__dl, __dn))
+
+/**
+ * @brief Provide the primitive to iterate on a list, from a node in the list
+ * Note: the loop is unsafe and thus __dn should not be removed
+ *
+ * User _MUST_ add the loop statement curly braces enclosing its own code:
+ *
+ * SYS_DLIST_ITERATE_FROM_NODE(l, n) {
+ * <user code>
+ * }
+ *
+ * Like SYS_DLIST_FOR_EACH_NODE(), but __dn already contains a node in the list
+ * where to start searching for the next entry from. If NULL, it starts from
+ * the head.
+ *
+ * This and other SYS_DLIST_*() macros are not thread safe.
+ *
+ * @param __dl A pointer on a sys_dlist_t to iterate on
+ * @param __dn A sys_dnode_t pointer to peek each node of the list;
+ * it contains the starting node, or NULL to start from the head
+ */
+#define SYS_DLIST_ITERATE_FROM_NODE(__dl, __dn) \
+ for (__dn = __dn ? sys_dlist_peek_next_no_check(__dl, __dn) \
+ : sys_dlist_peek_head(__dl); \
+ __dn; \
+ __dn = sys_dlist_peek_next(__dl, __dn))
+
+/**
+ * @brief Provide the primitive to safely iterate on a list
+ * Note: __dn can be removed, it will not break the loop.
+ *
+ * User _MUST_ add the loop statement curly braces enclosing its own code:
+ *
+ * SYS_DLIST_FOR_EACH_NODE_SAFE(l, n, s) {
+ * <user code>
+ * }
+ *
+ * This and other SYS_DLIST_*() macros are not thread safe.
+ *
+ * @param __dl A pointer on a sys_dlist_t to iterate on
+ * @param __dn A sys_dnode_t pointer to peek each node of the list
+ * @param __dns A sys_dnode_t pointer for the loop to run safely
+ */
+#define SYS_DLIST_FOR_EACH_NODE_SAFE(__dl, __dn, __dns) \
+ for (__dn = sys_dlist_peek_head(__dl), \
+ __dns = sys_dlist_peek_next(__dl, __dn); \
+ __dn; __dn = __dns, \
+ __dns = sys_dlist_peek_next(__dl, __dn))
+
+/*
+ * @brief Provide the primitive to resolve the container of a list node
+ * Note: it is safe to use with NULL pointer nodes
+ *
+ * @param __dn A pointer on a sys_dnode_t to get its container
+ * @param __cn Container struct type pointer
+ * @param __n The field name of sys_dnode_t within the container struct
+ */
+#define SYS_DLIST_CONTAINER(__dn, __cn, __n) \
+ (__dn ? CONTAINER_OF(__dn, __typeof__(*__cn), __n) : NULL)
+/*
+ * @brief Provide the primitive to peek container of the list head
+ *
+ * @param __dl A pointer on a sys_dlist_t to peek
+ * @param __cn Container struct type pointer
+ * @param __n The field name of sys_dnode_t within the container struct
+ */
+#define SYS_DLIST_PEEK_HEAD_CONTAINER(__dl, __cn, __n) \
+ SYS_DLIST_CONTAINER(sys_dlist_peek_head(__dl), __cn, __n)
+
+/*
+ * @brief Provide the primitive to peek the next container
+ *
+ * @param __dl A pointer on a sys_dlist_t to peek
+ * @param __cn Container struct type pointer
+ * @param __n The field name of sys_dnode_t within the container struct
+ */
+#define SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n) \
+ ((__cn) ? SYS_DLIST_CONTAINER(sys_dlist_peek_next(__dl, &(__cn->__n)), \
+ __cn, __n) : NULL)
+
+/**
+ * @brief Provide the primitive to iterate on a list under a container
+ * Note: the loop is unsafe and thus __cn should not be detached
+ *
+ * User _MUST_ add the loop statement curly braces enclosing its own code:
+ *
+ * SYS_DLIST_FOR_EACH_CONTAINER(l, c, n) {
+ * <user code>
+ * }
+ *
+ * @param __dl A pointer on a sys_dlist_t to iterate on
+ * @param __cn A pointer to peek each entry of the list
+ * @param __n The field name of sys_dnode_t within the container struct
+ */
+#define SYS_DLIST_FOR_EACH_CONTAINER(__dl, __cn, __n) \
+ for (__cn = SYS_DLIST_PEEK_HEAD_CONTAINER(__dl, __cn, __n); __cn; \
+ __cn = SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n))
+
+/**
+ * @brief Provide the primitive to safely iterate on a list under a container
+ * Note: __cn can be detached, it will not break the loop.
+ *
+ * User _MUST_ add the loop statement curly braces enclosing its own code:
+ *
+ * SYS_DLIST_FOR_EACH_CONTAINER_SAFE(l, c, cn, n) {
+ * <user code>
+ * }
+ *
+ * @param __dl A pointer on a sys_dlist_t to iterate on
+ * @param __cn A pointer to peek each entry of the list
+ * @param __cns A pointer for the loop to run safely
+ * @param __n The field name of sys_dnode_t within the container struct
+ */
+#define SYS_DLIST_FOR_EACH_CONTAINER_SAFE(__dl, __cn, __cns, __n) \
+ for (__cn = SYS_DLIST_PEEK_HEAD_CONTAINER(__dl, __cn, __n), \
+ __cns = SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n); __cn; \
+ __cn = __cns, \
+ __cns = SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n))
+
+/**
+ * @brief initialize list
+ *
+ * @param list the doubly-linked list
+ *
+ * @return N/A
+ */
+
+static inline void sys_dlist_init(sys_dlist_t *list)
+{
+ list->head = (sys_dnode_t *)list;
+ list->tail = (sys_dnode_t *)list;
+}
+
+#define SYS_DLIST_STATIC_INIT(ptr_to_list) {{(ptr_to_list)}, {(ptr_to_list)}}
+
+/**
+ * @brief check if a node is the list's head
+ *
+ * @param list the doubly-linked list to operate on
+ * @param node the node to check
+ *
+ * @return 1 if node is the head, 0 otherwise
+ */
+
+static inline int sys_dlist_is_head(sys_dlist_t *list, sys_dnode_t *node)
+{
+ return list->head == node;
+}
+
+/**
+ * @brief check if a node is the list's tail
+ *
+ * @param list the doubly-linked list to operate on
+ * @param node the node to check
+ *
+ * @return 1 if node is the tail, 0 otherwise
+ */
+
+static inline int sys_dlist_is_tail(sys_dlist_t *list, sys_dnode_t *node)
+{
+ return list->tail == node;
+}
+
+/**
+ * @brief check if the list is empty
+ *
+ * @param list the doubly-linked list to operate on
+ *
+ * @return 1 if empty, 0 otherwise
+ */
+
+static inline int sys_dlist_is_empty(sys_dlist_t *list)
+{
+ return list->head == list;
+}
+
+/**
+ * @brief check if more than one node present
+ *
+ * This and other sys_dlist_*() functions are not thread safe.
+ *
+ * @param list the doubly-linked list to operate on
+ *
+ * @return 1 if multiple nodes, 0 otherwise
+ */
+
+static inline int sys_dlist_has_multiple_nodes(sys_dlist_t *list)
+{
+ return list->head != list->tail;
+}
+
+/**
+ * @brief get a reference to the head item in the list
+ *
+ * @param list the doubly-linked list to operate on
+ *
+ * @return a pointer to the head element, NULL if list is empty
+ */
+
+static inline sys_dnode_t *sys_dlist_peek_head(sys_dlist_t *list)
+{
+ return sys_dlist_is_empty(list) ? NULL : list->head;
+}
+
+/**
+ * @brief get a reference to the head item in the list
+ *
+ * The list must be known to be non-empty.
+ *
+ * @param list the doubly-linked list to operate on
+ *
+ * @return a pointer to the head element
+ */
+
+static inline sys_dnode_t *sys_dlist_peek_head_not_empty(sys_dlist_t *list)
+{
+ return list->head;
+}
+
+/**
+ * @brief get a reference to the next item in the list, node is not NULL
+ *
+ * Faster than sys_dlist_peek_next() if node is known not to be NULL.
+ *
+ * @param list the doubly-linked list to operate on
+ * @param node the node from which to get the next element in the list
+ *
+ * @return a pointer to the next element from a node, NULL if node is the tail
+ */
+
+static inline sys_dnode_t *sys_dlist_peek_next_no_check(sys_dlist_t *list,
+ sys_dnode_t *node)
+{
+ return (node == list->tail) ? NULL : node->next;
+}
+
+/**
+ * @brief get a reference to the next item in the list
+ *
+ * @param list the doubly-linked list to operate on
+ * @param node the node from which to get the next element in the list
+ *
+ * @return a pointer to the next element from a node, NULL if node is the tail
+ * or NULL (when node comes from reading the head of an empty list).
+ */
+
+static inline sys_dnode_t *sys_dlist_peek_next(sys_dlist_t *list,
+ sys_dnode_t *node)
+{
+ return node ? sys_dlist_peek_next_no_check(list, node) : NULL;
+}
+
+/**
+ * @brief get a reference to the tail item in the list
+ *
+ * @param list the doubly-linked list to operate on
+ *
+ * @return a pointer to the tail element, NULL if list is empty
+ */
+
+static inline sys_dnode_t *sys_dlist_peek_tail(sys_dlist_t *list)
+{
+ return sys_dlist_is_empty(list) ? NULL : list->tail;
+}
+
+/**
+ * @brief add node to tail of list
+ *
+ * This and other sys_dlist_*() functions are not thread safe.
+ *
+ * @param list the doubly-linked list to operate on
+ * @param node the element to append
+ *
+ * @return N/A
+ */
+
+static inline void sys_dlist_append(sys_dlist_t *list, sys_dnode_t *node)
+{
+ node->next = list;
+ node->prev = list->tail;
+
+ list->tail->next = node;
+ list->tail = node;
+}
+
+/**
+ * @brief add node to head of list
+ *
+ * This and other sys_dlist_*() functions are not thread safe.
+ *
+ * @param list the doubly-linked list to operate on
+ * @param node the element to append
+ *
+ * @return N/A
+ */
+
+static inline void sys_dlist_prepend(sys_dlist_t *list, sys_dnode_t *node)
+{
+ node->next = list->head;
+ node->prev = list;
+
+ list->head->prev = node;
+ list->head = node;
+}
+
+/**
+ * @brief insert node after a node
+ *
+ * Insert a node after a specified node in a list.
+ * This and other sys_dlist_*() functions are not thread safe.
+ *
+ * @param list the doubly-linked list to operate on
+ * @param insert_point the insert point in the list: if NULL, insert at head
+ * @param node the element to append
+ *
+ * @return N/A
+ */
+
+static inline void sys_dlist_insert_after(sys_dlist_t *list,
+ sys_dnode_t *insert_point,
+ sys_dnode_t *node)
+{
+ if (!insert_point) {
+ sys_dlist_prepend(list, node);
+ } else {
+ node->next = insert_point->next;
+ node->prev = insert_point;
+ insert_point->next->prev = node;
+ insert_point->next = node;
+ }
+}
+
+/**
+ * @brief insert node before a node
+ *
+ * Insert a node before a specified node in a list.
+ * This and other sys_dlist_*() functions are not thread safe.
+ *
+ * @param list the doubly-linked list to operate on
+ * @param insert_point the insert point in the list: if NULL, insert at tail
+ * @param node the element to insert
+ *
+ * @return N/A
+ */
+
+static inline void sys_dlist_insert_before(sys_dlist_t *list,
+ sys_dnode_t *insert_point,
+ sys_dnode_t *node)
+{
+ if (!insert_point) {
+ sys_dlist_append(list, node);
+ } else {
+ node->prev = insert_point->prev;
+ node->next = insert_point;
+ insert_point->prev->next = node;
+ insert_point->prev = node;
+ }
+}
+
+/**
+ * @brief insert node at position
+ *
+ * Insert a node in a location depending on a external condition. The cond()
+ * function checks if the node is to be inserted _before_ the current node
+ * against which it is checked.
+ * This and other sys_dlist_*() functions are not thread safe.
+ *
+ * @param list the doubly-linked list to operate on
+ * @param node the element to insert
+ * @param cond a function that determines if the current node is the correct
+ * insert point
+ * @param data parameter to cond()
+ *
+ * @return N/A
+ */
+
+static inline void sys_dlist_insert_at(sys_dlist_t *list, sys_dnode_t *node,
+ int (*cond)(sys_dnode_t *, void *), void *data)
+{
+ if (sys_dlist_is_empty(list)) {
+ sys_dlist_append(list, node);
+ } else {
+ sys_dnode_t *pos = sys_dlist_peek_head(list);
+
+ while (pos && !cond(pos, data)) {
+ pos = sys_dlist_peek_next(list, pos);
+ }
+ sys_dlist_insert_before(list, pos, node);
+ }
+}
+
+/**
+ * @brief remove a specific node from a list
+ *
+ * The list is implicit from the node. The node must be part of a list.
+ * This and other sys_dlist_*() functions are not thread safe.
+ *
+ * @param node the node to remove
+ *
+ * @return N/A
+ */
+
+static inline void sys_dlist_remove(sys_dnode_t *node)
+{
+ node->prev->next = node->next;
+ node->next->prev = node->prev;
+}
+
+/**
+ * @brief get the first node in a list
+ *
+ * This and other sys_dlist_*() functions are not thread safe.
+ *
+ * @param list the doubly-linked list to operate on
+ *
+ * @return the first node in the list, NULL if list is empty
+ */
+
+static inline sys_dnode_t *sys_dlist_get(sys_dlist_t *list)
+{
+ sys_dnode_t *node;
+
+ if (sys_dlist_is_empty(list)) {
+ return NULL;
+ }
+
+ node = list->head;
+ sys_dlist_remove(node);
+ return node;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_DLIST_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/ffs.h b/lib/bt/esp_ble_mesh/common/include/mesh/ffs.h
new file mode 100644
index 00000000..7f512548
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/ffs.h
@@ -0,0 +1,60 @@
+/*
+ * SPDX-FileCopyrightText: 2015 Wind River Systems, Inc.
+ * SPDX-FileCopyrightText: 2017 Oticon A/S
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _BLE_MESH_FFS_H_
+#define _BLE_MESH_FFS_H_
+
+#include "mesh/types.h"
+#include "mesh/compiler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ *
+ * @brief find most significant bit set in a 32-bit word
+ *
+ * This routine finds the first bit set starting from the most significant bit
+ * in the argument passed in and returns the index of that bit. Bits are
+ * numbered starting at 1 from the least significant bit. A return value of
+ * zero indicates that the value passed is zero.
+ *
+ * @return most significant bit set, 0 if @a op is 0
+ */
+
+static ALWAYS_INLINE unsigned int find_msb_set(uint32_t op)
+{
+ if (op == 0) {
+ return 0;
+ }
+
+ return 32 - __builtin_clz(op);
+}
+
+/**
+ *
+ * @brief find least significant bit set in a 32-bit word
+ *
+ * This routine finds the first bit set starting from the least significant bit
+ * in the argument passed in and returns the index of that bit. Bits are
+ * numbered starting at 1 from the least significant bit. A return value of
+ * zero indicates that the value passed is zero.
+ *
+ * @return least significant bit set, 0 if @a op is 0
+ */
+
+static ALWAYS_INLINE unsigned int find_lsb_set(uint32_t op)
+{
+ return __builtin_ffs(op);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_FFS_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/kernel.h b/lib/bt/esp_ble_mesh/common/include/mesh/kernel.h
new file mode 100644
index 00000000..025b269a
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/kernel.h
@@ -0,0 +1,59 @@
+/*
+ * SPDX-FileCopyrightText: 2016 Wind River Systems, Inc.
+ * SPDX-FileContributor: 2020-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _BLE_MESH_KERNEL_H_
+#define _BLE_MESH_KERNEL_H_
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+#include "freertos/semphr.h"
+
+#include "mesh/config.h"
+#include "mesh/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef CONFIG_BT_BLUEDROID_ENABLED
+#ifdef CONFIG_BT_BLUEDROID_PINNED_TO_CORE
+#define BLE_MESH_ADV_TASK_CORE (CONFIG_BT_BLUEDROID_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BT_BLUEDROID_PINNED_TO_CORE : tskNO_AFFINITY)
+#else
+#define BLE_MESH_ADV_TASK_CORE (0)
+#endif
+#endif
+
+#ifdef CONFIG_BT_NIMBLE_ENABLED
+#ifdef CONFIG_BT_NIMBLE_PINNED_TO_CORE
+#define BLE_MESH_ADV_TASK_CORE (CONFIG_BT_NIMBLE_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BT_NIMBLE_PINNED_TO_CORE : tskNO_AFFINITY)
+#else
+#define BLE_MESH_ADV_TASK_CORE (0)
+#endif
+#endif
+
+#define BLE_MESH_ADV_TASK_STACK_SIZE 3072
+#define BLE_MESH_ADV_TASK_NAME "mesh_adv_task"
+#define BLE_MESH_ADV_TASK_PRIO (configMAX_PRIORITIES - 5)
+
+/**
+ * @brief Put the current thread to sleep.
+ *
+ * This routine puts the current thread to sleep for @a duration
+ * milliseconds.
+ *
+ * @param duration Number of milliseconds to sleep.
+ *
+ * @return N/A
+ */
+void k_sleep(int32_t duration);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_KERNEL_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/mutex.h b/lib/bt/esp_ble_mesh/common/include/mesh/mutex.h
new file mode 100644
index 00000000..ee897500
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/mutex.h
@@ -0,0 +1,54 @@
+/*
+ * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _BLE_MESH_MUTEX_H_
+#define _BLE_MESH_MUTEX_H_
+
+#include "mesh/kernel.h"
+#include "mesh/slist.h"
+#include "mesh/atomic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ SemaphoreHandle_t mutex;
+#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
+ StaticQueue_t *buffer;
+#endif
+} bt_mesh_mutex_t;
+
+void bt_mesh_mutex_create(bt_mesh_mutex_t *mutex);
+void bt_mesh_mutex_free(bt_mesh_mutex_t *mutex);
+void bt_mesh_mutex_lock(bt_mesh_mutex_t *mutex);
+void bt_mesh_mutex_unlock(bt_mesh_mutex_t *mutex);
+
+void bt_mesh_r_mutex_create(bt_mesh_mutex_t *mutex);
+void bt_mesh_r_mutex_free(bt_mesh_mutex_t *mutex);
+void bt_mesh_r_mutex_lock(bt_mesh_mutex_t *mutex);
+void bt_mesh_r_mutex_unlock(bt_mesh_mutex_t *mutex);
+
+void bt_mesh_alarm_lock(void);
+void bt_mesh_alarm_unlock(void);
+
+void bt_mesh_list_lock(void);
+void bt_mesh_list_unlock(void);
+
+void bt_mesh_buf_lock(void);
+void bt_mesh_buf_unlock(void);
+
+void bt_mesh_atomic_lock(void);
+void bt_mesh_atomic_unlock(void);
+
+void bt_mesh_mutex_init(void);
+void bt_mesh_mutex_deinit(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_MUTEX_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/slist.h b/lib/bt/esp_ble_mesh/common/include/mesh/slist.h
new file mode 100644
index 00000000..6050522d
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/slist.h
@@ -0,0 +1,467 @@
+/*
+ * SPDX-FileCopyrightText: 2016 Intel Corporation
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/**
+ * @file
+ *
+ * @brief Single-linked list implementation
+ *
+ * Single-linked list implementation using inline macros/functions.
+ * This API is not thread safe, and thus if a list is used across threads,
+ * calls to functions must be protected with synchronization primitives.
+ */
+
+#ifndef _BLE_MESH_SLIST_H_
+#define _BLE_MESH_SLIST_H_
+
+#include <stddef.h>
+#include <stdbool.h>
+#include "mesh/utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _snode {
+ struct _snode *next;
+};
+
+typedef struct _snode sys_snode_t;
+
+struct _slist {
+ sys_snode_t *head;
+ sys_snode_t *tail;
+};
+
+typedef struct _slist sys_slist_t;
+
+/**
+ * @brief Provide the primitive to iterate on a list
+ * Note: the loop is unsafe and thus __sn should not be removed
+ *
+ * User _MUST_ add the loop statement curly braces enclosing its own code:
+ *
+ * SYS_SLIST_FOR_EACH_NODE(l, n) {
+ * <user code>
+ * }
+ *
+ * This and other SYS_SLIST_*() macros are not thread safe.
+ *
+ * @param __sl A pointer on a sys_slist_t to iterate on
+ * @param __sn A sys_snode_t pointer to peek each node of the list
+ */
+#define SYS_SLIST_FOR_EACH_NODE(__sl, __sn) \
+ for (__sn = sys_slist_peek_head(__sl); __sn; \
+ __sn = sys_slist_peek_next(__sn))
+
+/**
+ * @brief Provide the primitive to iterate on a list, from a node in the list
+ * Note: the loop is unsafe and thus __sn should not be removed
+ *
+ * User _MUST_ add the loop statement curly braces enclosing its own code:
+ *
+ * SYS_SLIST_ITERATE_FROM_NODE(l, n) {
+ * <user code>
+ * }
+ *
+ * Like SYS_SLIST_FOR_EACH_NODE(), but __dn already contains a node in the list
+ * where to start searching for the next entry from. If NULL, it starts from
+ * the head.
+ *
+ * This and other SYS_SLIST_*() macros are not thread safe.
+ *
+ * @param __sl A pointer on a sys_slist_t to iterate on
+ * @param __sn A sys_snode_t pointer to peek each node of the list
+ * it contains the starting node, or NULL to start from the head
+ */
+#define SYS_SLIST_ITERATE_FROM_NODE(__sl, __sn) \
+ for (__sn = __sn ? sys_slist_peek_next_no_check(__sn) \
+ : sys_slist_peek_head(__sl); \
+ __sn; \
+ __sn = sys_slist_peek_next(__sn))
+
+/**
+ * @brief Provide the primitive to safely iterate on a list
+ * Note: __sn can be removed, it will not break the loop.
+ *
+ * User _MUST_ add the loop statement curly braces enclosing its own code:
+ *
+ * SYS_SLIST_FOR_EACH_NODE_SAFE(l, n, s) {
+ * <user code>
+ * }
+ *
+ * This and other SYS_SLIST_*() macros are not thread safe.
+ *
+ * @param __sl A pointer on a sys_slist_t to iterate on
+ * @param __sn A sys_snode_t pointer to peek each node of the list
+ * @param __sns A sys_snode_t pointer for the loop to run safely
+ */
+#define SYS_SLIST_FOR_EACH_NODE_SAFE(__sl, __sn, __sns) \
+ for (__sn = sys_slist_peek_head(__sl), \
+ __sns = sys_slist_peek_next(__sn); \
+ __sn; __sn = __sns, \
+ __sns = sys_slist_peek_next(__sn))
+
+/*
+ * @brief Provide the primitive to resolve the container of a list node
+ * Note: it is safe to use with NULL pointer nodes
+ *
+ * @param __ln A pointer on a sys_node_t to get its container
+ * @param __cn Container struct type pointer
+ * @param __n The field name of sys_node_t within the container struct
+ */
+#define SYS_SLIST_CONTAINER(__ln, __cn, __n) \
+ ((__ln) ? CONTAINER_OF((__ln), __typeof__(*(__cn)), __n) : NULL)
+/*
+ * @brief Provide the primitive to peek container of the list head
+ *
+ * @param __sl A pointer on a sys_slist_t to peek
+ * @param __cn Container struct type pointer
+ * @param __n The field name of sys_node_t within the container struct
+ */
+#define SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n) \
+ SYS_SLIST_CONTAINER(sys_slist_peek_head(__sl), __cn, __n)
+
+/*
+ * @brief Provide the primitive to peek container of the list tail
+ *
+ * @param __sl A pointer on a sys_slist_t to peek
+ * @param __cn Container struct type pointer
+ * @param __n The field name of sys_node_t within the container struct
+ */
+#define SYS_SLIST_PEEK_TAIL_CONTAINER(__sl, __cn, __n) \
+ SYS_SLIST_CONTAINER(sys_slist_peek_tail(__sl), __cn, __n)
+
+/*
+ * @brief Provide the primitive to peek the next container
+ *
+ * @param __cn Container struct type pointer
+ * @param __n The field name of sys_node_t within the container struct
+ */
+
+#define SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n) \
+ ((__cn) ? SYS_SLIST_CONTAINER(sys_slist_peek_next(&((__cn)->__n)), \
+ __cn, __n) : NULL)
+
+/**
+ * @brief Provide the primitive to iterate on a list under a container
+ * Note: the loop is unsafe and thus __cn should not be detached
+ *
+ * User _MUST_ add the loop statement curly braces enclosing its own code:
+ *
+ * SYS_SLIST_FOR_EACH_CONTAINER(l, c, n) {
+ * <user code>
+ * }
+ *
+ * @param __sl A pointer on a sys_slist_t to iterate on
+ * @param __cn A pointer to peek each entry of the list
+ * @param __n The field name of sys_node_t within the container struct
+ */
+#define SYS_SLIST_FOR_EACH_CONTAINER(__sl, __cn, __n) \
+ for (__cn = SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n); __cn; \
+ __cn = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n))
+
+/**
+ * @brief Provide the primitive to safely iterate on a list under a container
+ * Note: __cn can be detached, it will not break the loop.
+ *
+ * User _MUST_ add the loop statement curly braces enclosing its own code:
+ *
+ * SYS_SLIST_FOR_EACH_NODE_SAFE(l, c, cn, n) {
+ * <user code>
+ * }
+ *
+ * @param __sl A pointer on a sys_slist_t to iterate on
+ * @param __cn A pointer to peek each entry of the list
+ * @param __cns A pointer for the loop to run safely
+ * @param __n The field name of sys_node_t within the container struct
+ */
+#define SYS_SLIST_FOR_EACH_CONTAINER_SAFE(__sl, __cn, __cns, __n) \
+ for (__cn = SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n), \
+ __cns = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n); __cn; \
+ __cn = __cns, __cns = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n))
+
+/**
+ * @brief Initialize a list
+ *
+ * @param list A pointer on the list to initialize
+ */
+static inline void sys_slist_init(sys_slist_t *list)
+{
+ list->head = NULL;
+ list->tail = NULL;
+}
+
+#define SYS_SLIST_STATIC_INIT(ptr_to_list) {NULL, NULL}
+
+/**
+ * @brief Test if the given list is empty
+ *
+ * @param list A pointer on the list to test
+ *
+ * @return a boolean, true if it's empty, false otherwise
+ */
+static inline bool sys_slist_is_empty(sys_slist_t *list)
+{
+ return (!list->head);
+}
+
+/**
+ * @brief Peek the first node from the list
+ *
+ * @param list A point on the list to peek the first node from
+ *
+ * @return A pointer on the first node of the list (or NULL if none)
+ */
+static inline sys_snode_t *sys_slist_peek_head(sys_slist_t *list)
+{
+ return list->head;
+}
+
+/**
+ * @brief Peek the last node from the list
+ *
+ * @param list A point on the list to peek the last node from
+ *
+ * @return A pointer on the last node of the list (or NULL if none)
+ */
+static inline sys_snode_t *sys_slist_peek_tail(sys_slist_t *list)
+{
+ return list->tail;
+}
+
+/**
+ * @brief Peek the next node from current node, node is not NULL
+ *
+ * Faster then sys_slist_peek_next() if node is known not to be NULL.
+ *
+ * @param node A pointer on the node where to peek the next node
+ *
+ * @return a pointer on the next node (or NULL if none)
+ */
+static inline sys_snode_t *sys_slist_peek_next_no_check(sys_snode_t *node)
+{
+ return node->next;
+}
+
+/**
+ * @brief Peek the next node from current node
+ *
+ * @param node A pointer on the node where to peek the next node
+ *
+ * @return a pointer on the next node (or NULL if none)
+ */
+static inline sys_snode_t *sys_slist_peek_next(sys_snode_t *node)
+{
+ return node ? sys_slist_peek_next_no_check(node) : NULL;
+}
+
+/**
+ * @brief Prepend a node to the given list
+ *
+ * This and other sys_slist_*() functions are not thread safe.
+ *
+ * @param list A pointer on the list to affect
+ * @param node A pointer on the node to prepend
+ */
+static inline void sys_slist_prepend(sys_slist_t *list,
+ sys_snode_t *node)
+{
+ node->next = list->head;
+ list->head = node;
+
+ if (!list->tail) {
+ list->tail = list->head;
+ }
+}
+
+/**
+ * @brief Append a node to the given list
+ *
+ * This and other sys_slist_*() functions are not thread safe.
+ *
+ * @param list A pointer on the list to affect
+ * @param node A pointer on the node to append
+ */
+static inline void sys_slist_append(sys_slist_t *list,
+ sys_snode_t *node)
+{
+ node->next = NULL;
+
+ if (!list->tail) {
+ list->tail = node;
+ list->head = node;
+ } else {
+ list->tail->next = node;
+ list->tail = node;
+ }
+}
+
+/**
+ * @brief Append a list to the given list
+ *
+ * Append a singly-linked, NULL-terminated list consisting of nodes containing
+ * the pointer to the next node as the first element of a node, to @a list.
+ * This and other sys_slist_*() functions are not thread safe.
+ *
+ * @param list A pointer on the list to affect
+ * @param head A pointer to the first element of the list to append
+ * @param tail A pointer to the last element of the list to append
+ */
+static inline void sys_slist_append_list(sys_slist_t *list,
+ void *head, void *tail)
+{
+ if (!list->tail) {
+ list->head = (sys_snode_t *)head;
+ list->tail = (sys_snode_t *)tail;
+ } else {
+ list->tail->next = (sys_snode_t *)head;
+ list->tail = (sys_snode_t *)tail;
+ }
+}
+
+/**
+ * @brief merge two slists, appending the second one to the first
+ *
+ * When the operation is completed, the appending list is empty.
+ * This and other sys_slist_*() functions are not thread safe.
+ *
+ * @param list A pointer on the list to affect
+ * @param list_to_append A pointer to the list to append.
+ */
+static inline void sys_slist_merge_slist(sys_slist_t *list,
+ sys_slist_t *list_to_append)
+{
+ sys_slist_append_list(list, list_to_append->head,
+ list_to_append->tail);
+ sys_slist_init(list_to_append);
+}
+
+/**
+ * @brief Insert a node to the given list
+ *
+ * This and other sys_slist_*() functions are not thread safe.
+ *
+ * @param list A pointer on the list to affect
+ * @param prev A pointer on the previous node
+ * @param node A pointer on the node to insert
+ */
+static inline void sys_slist_insert(sys_slist_t *list,
+ sys_snode_t *prev,
+ sys_snode_t *node)
+{
+ if (!prev) {
+ sys_slist_prepend(list, node);
+ } else if (!prev->next) {
+ sys_slist_append(list, node);
+ } else {
+ node->next = prev->next;
+ prev->next = node;
+ }
+}
+
+/**
+ * @brief Fetch and remove the first node of the given list
+ *
+ * List must be known to be non-empty.
+ * This and other sys_slist_*() functions are not thread safe.
+ *
+ * @param list A pointer on the list to affect
+ *
+ * @return A pointer to the first node of the list
+ */
+static inline sys_snode_t *sys_slist_get_not_empty(sys_slist_t *list)
+{
+ sys_snode_t *node = list->head;
+
+ list->head = node->next;
+ if (list->tail == node) {
+ list->tail = list->head;
+ }
+
+ return node;
+}
+
+/**
+ * @brief Fetch and remove the first node of the given list
+ *
+ * This and other sys_slist_*() functions are not thread safe.
+ *
+ * @param list A pointer on the list to affect
+ *
+ * @return A pointer to the first node of the list (or NULL if empty)
+ */
+static inline sys_snode_t *sys_slist_get(sys_slist_t *list)
+{
+ return sys_slist_is_empty(list) ? NULL : sys_slist_get_not_empty(list);
+}
+
+/**
+ * @brief Remove a node
+ *
+ * This and other sys_slist_*() functions are not thread safe.
+ *
+ * @param list A pointer on the list to affect
+ * @param prev_node A pointer on the previous node
+ * (can be NULL, which means the node is the list's head)
+ * @param node A pointer on the node to remove
+ */
+static inline void sys_slist_remove(sys_slist_t *list,
+ sys_snode_t *prev_node,
+ sys_snode_t *node)
+{
+ if (!prev_node) {
+ list->head = node->next;
+
+ /* Was node also the tail? */
+ if (list->tail == node) {
+ list->tail = list->head;
+ }
+ } else {
+ prev_node->next = node->next;
+
+ /* Was node the tail? */
+ if (list->tail == node) {
+ list->tail = prev_node;
+ }
+ }
+
+ node->next = NULL;
+}
+
+/**
+ * @brief Find and remove a node from a list
+ *
+ * This and other sys_slist_*() functions are not thread safe.
+ *
+ * @param list A pointer on the list to affect
+ * @param node A pointer on the node to remove from the list
+ *
+ * @return true if node was removed
+ */
+static inline bool sys_slist_find_and_remove(sys_slist_t *list,
+ sys_snode_t *node)
+{
+ sys_snode_t *prev = NULL;
+ sys_snode_t *test;
+
+ SYS_SLIST_FOR_EACH_NODE(list, test) {
+ if (test == node) {
+ sys_slist_remove(list, prev, node);
+ return true;
+ }
+
+ prev = test;
+ }
+
+ return false;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_SLIST_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/timer.h b/lib/bt/esp_ble_mesh/common/include/mesh/timer.h
new file mode 100644
index 00000000..e1296aa8
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/timer.h
@@ -0,0 +1,278 @@
+/*
+ * SPDX-FileCopyrightText: 2016 Wind River Systems, Inc.
+ * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _BLE_MESH_TIMER_H_
+#define _BLE_MESH_TIMER_H_
+
+#include "mesh/types.h"
+#include "mesh/slist.h"
+#include "mesh/atomic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* number of nsec per usec */
+#define NSEC_PER_USEC 1000
+
+/* number of microseconds per millisecond */
+#define USEC_PER_MSEC 1000
+
+/* number of milliseconds per second */
+#define MSEC_PER_SEC 1000
+
+/* number of microseconds per second */
+#define USEC_PER_SEC ((USEC_PER_MSEC) * (MSEC_PER_SEC))
+
+/* number of nanoseconds per second */
+#define NSEC_PER_SEC ((NSEC_PER_USEC) * (USEC_PER_MSEC) * (MSEC_PER_SEC))
+
+/* timeout is not in use */
+#define _INACTIVE (-1)
+
+struct k_work;
+
+/**
+ * @typedef k_work_handler_t
+ * @brief Work item handler function type.
+ *
+ * A work item's handler function is executed by a workqueue's thread
+ * when the work item is processed by the workqueue.
+ *
+ * @param work Address of the work item.
+ *
+ * @return N/A
+ */
+typedef void (*k_work_handler_t)(struct k_work *work);
+
+struct k_work {
+ k_work_handler_t handler;
+ int index;
+ void *user_data;
+};
+
+#define _K_WORK_INITIALIZER(work_handler) \
+{ \
+ .handler = work_handler, \
+ .user_data = NULL, \
+}
+
+/**
+ * @brief Generate null timeout delay.
+ *
+ * This macro generates a timeout delay that that instructs a kernel API
+ * not to wait if the requested operation cannot be performed immediately.
+ *
+ * @return Timeout delay value.
+ */
+#define K_NO_WAIT 0
+
+/**
+ * @brief Generate timeout delay from milliseconds.
+ *
+ * This macro generates a timeout delay that that instructs a kernel API
+ * to wait up to @a ms milliseconds to perform the requested operation.
+ *
+ * @param ms Duration in milliseconds.
+ *
+ * @return Timeout delay value.
+ */
+#define K_MSEC(ms) (ms)
+
+/**
+ * @brief Generate timeout delay from seconds.
+ *
+ * This macro generates a timeout delay that that instructs a kernel API
+ * to wait up to @a s seconds to perform the requested operation.
+ *
+ * @param s Duration in seconds.
+ *
+ * @return Timeout delay value.
+ */
+#define K_SECONDS(s) K_MSEC((s) * MSEC_PER_SEC)
+
+/**
+ * @brief Generate timeout delay from minutes.
+ *
+ * This macro generates a timeout delay that that instructs a kernel API
+ * to wait up to @a m minutes to perform the requested operation.
+ *
+ * @param m Duration in minutes.
+ *
+ * @return Timeout delay value.
+ */
+#define K_MINUTES(m) K_SECONDS((m) * 60)
+
+/**
+ * @brief Generate timeout delay from hours.
+ *
+ * This macro generates a timeout delay that that instructs a kernel API
+ * to wait up to @a h hours to perform the requested operation.
+ *
+ * @param h Duration in hours.
+ *
+ * @return Timeout delay value.
+ */
+#define K_HOURS(h) K_MINUTES((h) * 60)
+
+/**
+ * @brief Generate timeout delay from days.
+ *
+ * This macro generates a timeout delay that that instructs a kernel API
+ * to wait up to @a d days to perform the requested operation.
+ *
+ * @param d Duration in days.
+ *
+ * @return Timeout delay value.
+ */
+#define K_DAYS(d) K_HOURS((d) * 24)
+
+/**
+ * @brief Generate infinite timeout delay.
+ *
+ * This macro generates a timeout delay that that instructs a kernel API
+ * to wait as long as necessary to perform the requested operation.
+ *
+ * @return Timeout delay value.
+ */
+#define K_FOREVER (-1)
+
+/**
+ * @brief Get system uptime (32-bit version).
+ *
+ * This routine returns the lower 32-bits of the elapsed time since the system
+ * booted, in milliseconds.
+ *
+ * This routine can be more efficient than k_uptime_get(), as it reduces the
+ * need for interrupt locking and 64-bit math. However, the 32-bit result
+ * cannot hold a system uptime time larger than approximately 50 days, so the
+ * caller must handle possible rollovers.
+ *
+ * @return Current uptime.
+ */
+uint32_t k_uptime_get_32(void);
+
+struct k_delayed_work {
+ struct k_work work;
+};
+
+/**
+ * @brief Submit a delayed work item to the system workqueue.
+ *
+ * This routine schedules work item @a work to be processed by the system
+ * workqueue after a delay of @a delay milliseconds. The routine initiates
+ * an asynchronous countdown for the work item and then returns to the caller.
+ * Only when the countdown completes is the work item actually submitted to
+ * the workqueue and becomes pending.
+ *
+ * Submitting a previously submitted delayed work item that is still
+ * counting down cancels the existing submission and restarts the countdown
+ * using the new delay. If the work item is currently pending on the
+ * workqueue's queue because the countdown has completed it is too late to
+ * resubmit the item, and resubmission fails without impacting the work item.
+ * If the work item has already been processed, or is currently being processed,
+ * its work is considered complete and the work item can be resubmitted.
+ *
+ * @warning
+ * Work items submitted to the system workqueue should avoid using handlers
+ * that block or yield since this may prevent the system workqueue from
+ * processing other work items in a timely manner.
+ *
+ * @note Can be called by ISRs.
+ *
+ * @param work Address of delayed work item.
+ * @param delay Delay before submitting the work item (in milliseconds).
+ *
+ * @retval 0 Work item countdown started.
+ * @retval -EINPROGRESS Work item is already pending.
+ * @retval -EINVAL Work item is being processed or has completed its work.
+ * @retval -EADDRINUSE Work item is pending on a different workqueue.
+ */
+int k_delayed_work_submit(struct k_delayed_work *work, int32_t delay);
+
+int k_delayed_work_submit_periodic(struct k_delayed_work *work, int32_t period);
+
+/**
+ * @brief Get time remaining before a delayed work gets scheduled.
+ *
+ * This routine computes the (approximate) time remaining before a
+ * delayed work gets executed. If the delayed work is not waiting to be
+ * scheduled, it returns zero.
+ *
+ * @param work Delayed work item.
+ *
+ * @return Remaining time (in milliseconds).
+ */
+int32_t k_delayed_work_remaining_get(struct k_delayed_work *work);
+
+/**
+ * @brief Submit a work item to the system workqueue.
+ *
+ * This routine submits work item @a work to be processed by the system
+ * workqueue. If the work item is already pending in the workqueue's queue
+ * as a result of an earlier submission, this routine has no effect on the
+ * work item. If the work item has already been processed, or is currently
+ * being processed, its work is considered complete and the work item can be
+ * resubmitted.
+ *
+ * @warning
+ * Work items submitted to the system workqueue should avoid using handlers
+ * that block or yield since this may prevent the system workqueue from
+ * processing other work items in a timely manner.
+ *
+ * @note Can be called by ISRs.
+ *
+ * @param work Address of work item.
+ *
+ * @return N/A
+ */
+static inline void k_work_submit(struct k_work *work)
+{
+ if (work && work->handler) {
+ work->handler(work);
+ }
+}
+
+/**
+ * @brief Initialize a work item.
+ *
+ * This routine initializes a workqueue work item, prior to its first use.
+ *
+ * @param work Address of work item.
+ * @param handler Function to invoke each time work item is processed.
+ *
+ * @return N/A
+ */
+static inline void k_work_init(struct k_work *work, k_work_handler_t handler)
+{
+ work->handler = handler;
+}
+
+int k_delayed_work_cancel(struct k_delayed_work *work);
+
+int k_delayed_work_free(struct k_delayed_work *work);
+
+int k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler);
+
+/**
+ * @brief Get system uptime.
+ *
+ * This routine returns the elapsed time since the system booted,
+ * in milliseconds.
+ *
+ * @return Current uptime.
+ */
+int64_t k_uptime_get(void);
+
+void bt_mesh_timer_init(void);
+void bt_mesh_timer_deinit(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_TIMER_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/trace.h b/lib/bt/esp_ble_mesh/common/include/mesh/trace.h
new file mode 100644
index 00000000..48f604f1
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/trace.h
@@ -0,0 +1,173 @@
+/*
+ * SPDX-FileCopyrightText: 2017 Nordic Semiconductor ASA
+ * SPDX-FileCopyrightText: 2015-2016 Intel Corporation
+ * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _BLE_MESH_TRACE_H_
+#define _BLE_MESH_TRACE_H_
+
+#include <assert.h>
+#include "esp_log.h"
+#include "mesh/utils.h"
+#include "esp_rom_sys.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Define common tracing for all */
+#ifndef BLE_MESH_LOG_LEVEL_ERROR
+#define BLE_MESH_LOG_LEVEL_ERROR 1
+#endif /* BLE_MESH_LOG_LEVEL_ERROR */
+
+#ifndef BLE_MESH_LOG_LEVEL_WARN
+#define BLE_MESH_LOG_LEVEL_WARN 2
+#endif /* BLE_MESH_LOG_LEVEL_WARN */
+
+#ifndef BLE_MESH_LOG_LEVEL_INFO
+#define BLE_MESH_LOG_LEVEL_INFO 3
+#endif /* BLE_MESH_LOG_LEVEL_INFO */
+
+#ifndef BLE_MESH_LOG_LEVEL_DEBUG
+#define BLE_MESH_LOG_LEVEL_DEBUG 4
+#endif /* BLE_MESH_LOG_LEVEL_DEBUG */
+
+#ifndef BLE_MESH_LOG_LEVEL_VERBOSE
+#define BLE_MESH_LOG_LEVEL_VERBOSE 5
+#endif /*BLE_MESH_LOG_LEVEL_VERBOSE */
+
+#ifdef CONFIG_BLE_MESH_STACK_TRACE_LEVEL
+#define BLE_MESH_LOG_LEVEL CONFIG_BLE_MESH_STACK_TRACE_LEVEL
+#else
+#define BLE_MESH_LOG_LEVEL BLE_MESH_LOG_LEVEL_WARN
+#endif
+
+#ifdef CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL
+#define BLE_MESH_NET_BUF_LOG_LEVEL CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL
+#else
+#define BLE_MESH_NET_BUF_LOG_LEVEL BLE_MESH_LOG_LEVEL_WARN
+#endif
+
+#define BLE_MESH_TRACE_TAG "BLE_MESH"
+
+#if (LOG_LOCAL_LEVEL >= 4)
+#define BLE_MESH_LOG_LOCAL_LEVEL_MAPPING (LOG_LOCAL_LEVEL + 1)
+#else
+#define BLE_MESH_LOG_LOCAL_LEVEL_MAPPING LOG_LOCAL_LEVEL
+#endif
+
+#define BLE_MESH_LOG_LEVEL_CHECK(LAYER, LEVEL) (MAX(LAYER##_LOG_LEVEL, BLE_MESH_LOG_LOCAL_LEVEL_MAPPING) >= BLE_MESH_LOG_LEVEL_##LEVEL)
+
+#define BLE_MESH_PRINT_E(tag, format, ...) {esp_log_write(ESP_LOG_ERROR, tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
+#define BLE_MESH_PRINT_W(tag, format, ...) {esp_log_write(ESP_LOG_WARN, tag, LOG_FORMAT(W, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
+#define BLE_MESH_PRINT_I(tag, format, ...) {esp_log_write(ESP_LOG_INFO, tag, LOG_FORMAT(I, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
+#define BLE_MESH_PRINT_D(tag, format, ...) {esp_log_write(ESP_LOG_DEBUG, tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
+#define BLE_MESH_PRINT_V(tag, format, ...) {esp_log_write(ESP_LOG_VERBOSE, tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
+
+#define printk esp_rom_printf
+
+#define _STRINGIFY(x) #x
+#define STRINGIFY(s) _STRINGIFY(s)
+
+#ifndef __ASSERT
+#define __ASSERT(test, str) assert(test)
+#endif
+
+#ifndef __ASSERT_NO_MSG
+#define __ASSERT_NO_MSG(x) assert(x)
+#endif
+
+#if !CONFIG_BLE_MESH_NO_LOG
+#define BT_ERR(fmt, args...) do {if ((BLE_MESH_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_ERROR) && BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH, ERROR)) BLE_MESH_PRINT_E(BLE_MESH_TRACE_TAG, fmt, ## args);} while(0)
+#define BT_WARN(fmt, args...) do {if ((BLE_MESH_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_WARN) && BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH, WARN)) BLE_MESH_PRINT_W(BLE_MESH_TRACE_TAG, fmt, ## args);} while(0)
+#define BT_INFO(fmt, args...) do {if ((BLE_MESH_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_INFO) && BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH, INFO)) BLE_MESH_PRINT_I(BLE_MESH_TRACE_TAG, fmt, ## args);} while(0)
+#define BT_DBG(fmt, args...) do {if ((BLE_MESH_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_DEBUG) && BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH, DEBUG)) BLE_MESH_PRINT_D(BLE_MESH_TRACE_TAG, fmt, ## args);} while(0)
+#else
+#define BT_ERR(fmt, args...)
+#define BT_WARN(fmt, args...)
+#define BT_INFO(fmt, args...)
+#define BT_DBG(fmt, args...)
+#endif
+
+#if (CONFIG_BLE_MESH_NET_BUF_LOG && !CONFIG_BLE_MESH_NO_LOG)
+#define NET_BUF_ERR(fmt, args...) do {if ((BLE_MESH_NET_BUF_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_ERROR) && BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH_NET_BUF, ERROR)) BLE_MESH_PRINT_E(BLE_MESH_TRACE_TAG, fmt, ## args);} while(0)
+#define NET_BUF_WARN(fmt, args...) do {if ((BLE_MESH_NET_BUF_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_WARN) && BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH_NET_BUF, WARN)) BLE_MESH_PRINT_W(BLE_MESH_TRACE_TAG, fmt, ## args);} while(0)
+#define NET_BUF_INFO(fmt, args...) do {if ((BLE_MESH_NET_BUF_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_INFO) && BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH_NET_BUF, INFO)) BLE_MESH_PRINT_I(BLE_MESH_TRACE_TAG, fmt, ## args);} while(0)
+#define NET_BUF_DBG(fmt, args...) do {if ((BLE_MESH_NET_BUF_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_DEBUG) && BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH_NET_BUF, DEBUG)) BLE_MESH_PRINT_D(BLE_MESH_TRACE_TAG, fmt, ## args);} while(0)
+#define NET_BUF_ASSERT(cond) __ASSERT_NO_MSG(cond)
+#else
+#define NET_BUF_ERR(fmt, args...)
+#define NET_BUF_WARN(fmt, args...)
+#define NET_BUF_INFO(fmt, args...)
+#define NET_BUF_DBG(fmt, args...)
+#define NET_BUF_ASSERT(cond)
+#endif
+
+#if (CONFIG_BLE_MESH_NET_BUF_SIMPLE_LOG && !CONFIG_BLE_MESH_NO_LOG)
+#define NET_BUF_SIMPLE_ERR(fmt, args...) do {if ((BLE_MESH_NET_BUF_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_ERROR) && BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH_NET_BUF, ERROR)) BLE_MESH_PRINT_E(BLE_MESH_TRACE_TAG, fmt, ## args);} while(0)
+#define NET_BUF_SIMPLE_WARN(fmt, args...) do {if ((BLE_MESH_NET_BUF_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_WARN) && BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH_NET_BUF, WARN)) BLE_MESH_PRINT_W(BLE_MESH_TRACE_TAG, fmt, ## args);} while(0)
+#define NET_BUF_SIMPLE_INFO(fmt, args...) do {if ((BLE_MESH_NET_BUF_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_INFO) && BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH_NET_BUF, INFO)) BLE_MESH_PRINT_I(BLE_MESH_TRACE_TAG, fmt, ## args);} while(0)
+#define NET_BUF_SIMPLE_DBG(fmt, args...) do {if ((BLE_MESH_NET_BUF_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_DEBUG) && BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH_NET_BUF, DEBUG)) BLE_MESH_PRINT_D(BLE_MESH_TRACE_TAG, fmt, ## args);} while(0)
+#define NET_BUF_SIMPLE_ASSERT(cond) __ASSERT_NO_MSG(cond)
+#else
+#define NET_BUF_SIMPLE_ERR(fmt, args...)
+#define NET_BUF_SIMPLE_WARN(fmt, args...)
+#define NET_BUF_SIMPLE_INFO(fmt, args...)
+#define NET_BUF_SIMPLE_DBG(fmt, args...)
+#define NET_BUF_SIMPLE_ASSERT(cond)
+#endif
+
+#if CONFIG_BLE_MESH_BQB_TEST_LOG
+/**
+ * For example, the test case "MESH/NODE/TNPT/BV-01-C"
+ * could use BT_BQB(BLE_MESH_BQB_TEST_LOG_LEVEL_PRIMARY_ID_NODE | BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_TNPT, "msg %s", msg)
+ * to print some message.
+ */
+enum BLE_MESH_BQB_TEST_LOG_LEVEL {
+ BLE_MESH_BQB_TEST_LOG_LEVEL_OUTPUT_ALL = 0, /* Output all BQB related test log */
+ BLE_MESH_BQB_TEST_LOG_LEVEL_PRIMARY_ID_NODE = BIT(0),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_PRIMARY_ID_PVNR = BIT(1),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_PRIMARY_ID_CFGCL = BIT(2),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_PRIMARY_ID_SR = BIT(3),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_PRIMARY_ID_CL = BIT(4),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_PBADV = BIT(5),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_MPS = BIT(6),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_PROV = BIT(7),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_BCN = BIT(8),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_NET = BIT(9),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_RLY = BIT(10),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_TNPT = BIT(11),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_IVU = BIT(12),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_KR = BIT(13),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_FRND_FN = BIT(14),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_FRND_LPN = BIT(15),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_PROX = BIT(16),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_MPXS = BIT(17),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_CFG = BIT(18),
+ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_HM = BIT(19),
+};
+
+#define BLE_MESH_BQB_TEST_LOG_LEVEL_OUTPUT_NONE 0x000FFFFF
+
+#endif /* CONFIG_BLE_MESH_BQB_TEST_LOG */
+
+#if (CONFIG_BLE_MESH_BQB_TEST_LOG && !CONFIG_BLE_MESH_NO_LOG)
+extern bool bt_mesh_bqb_test_flag_check(uint32_t flag_mask);
+extern int bt_mesh_bqb_test_flag_set(uint32_t value);
+#define BT_BQB(flag_mask, fmt, args...) \
+ do { \
+ if (bt_mesh_bqb_test_flag_check(flag_mask)) \
+ BLE_MESH_PRINT_I("BLE_MESH_BQB", fmt, ## args); \
+ } while (0)
+#else
+#define BT_BQB(flag_mask, fmt, args...)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_TRACE_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/types.h b/lib/bt/esp_ble_mesh/common/include/mesh/types.h
new file mode 100644
index 00000000..eba8c1a2
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/types.h
@@ -0,0 +1,33 @@
+/*
+ * SPDX-FileCopyrightText: 2017 Linaro Limited
+ * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _BLE_MESH_TYPES_H_
+#define _BLE_MESH_TYPES_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int bt_mesh_atomic_t;
+
+#ifndef PRIu64
+#define PRIu64 "llu"
+#endif
+
+#ifndef PRIx64
+#define PRIx64 "llx"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_TYPES_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/utils.h b/lib/bt/esp_ble_mesh/common/include/mesh/utils.h
new file mode 100644
index 00000000..98243483
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/utils.h
@@ -0,0 +1,226 @@
+/*
+ * SPDX-FileCopyrightText: 2011-2014 Wind River Systems, Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/**
+ * @file
+ * @brief Misc utilities
+ *
+ * Misc utilities usable by the kernel and application code.
+ */
+
+#ifndef _BLE_MESH_UTILS_H_
+#define _BLE_MESH_UTILS_H_
+
+#include <stddef.h>
+#include "esp_bit_defs.h"
+#include "mesh/types.h"
+#include "utils_loops.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Helper to pass a int as a pointer or vice-versa.
+ * Those are available for 32 bits architectures:
+ */
+#ifndef POINTER_TO_UINT
+#define POINTER_TO_UINT(x) ((uint32_t) (x))
+#endif
+#ifndef UINT_TO_POINTER
+#define UINT_TO_POINTER(x) ((void *) (x))
+#endif
+#ifndef POINTER_TO_INT
+#define POINTER_TO_INT(x) ((int32_t) (x))
+#endif
+#ifndef INT_TO_POINTER
+#define INT_TO_POINTER(x) ((void *) (x))
+#endif
+
+/* Evaluates to 0 if cond is true-ish; compile error otherwise */
+#ifndef ZERO_OR_COMPILE_ERROR
+#define ZERO_OR_COMPILE_ERROR(cond) ((int) sizeof(char[1 - 2 * !(cond)]) - 1)
+#endif
+
+/* Evaluates to 0 if array is an array; compile error if not array (e.g.
+ * pointer)
+ */
+#ifndef IS_ARRAY
+#define IS_ARRAY(array) \
+ ZERO_OR_COMPILE_ERROR( \
+ !__builtin_types_compatible_p(__typeof__(array), \
+ __typeof__(&(array)[0])))
+#endif
+
+/* Evaluates to number of elements in an array; compile error if not
+ * an array (e.g. pointer)
+ */
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
+#endif
+
+/* Evaluates to 1 if ptr is part of array, 0 otherwise; compile error if
+ * "array" argument is not an array (e.g. "ptr" and "array" mixed up)
+ */
+#ifndef PART_OF_ARRAY
+#define PART_OF_ARRAY(array, ptr) \
+ ((ptr) && ((ptr) >= &array[0] && (ptr) < &array[ARRAY_SIZE(array)]))
+#endif
+
+#ifndef CONTAINER_OF
+#define CONTAINER_OF(ptr, type, field) \
+ ((type *)(((char *)(ptr)) - offsetof(type, field)))
+#endif
+
+/* round "x" up/down to next multiple of "align" (which must be a power of 2) */
+#ifndef ROUND_UP
+#define ROUND_UP(x, align) \
+ (((unsigned long)(x) + ((unsigned long)align - 1)) & \
+ ~((unsigned long)align - 1))
+#endif
+
+#ifndef ROUND_DOWN
+#define ROUND_DOWN(x, align) ((unsigned long)(x) & ~((unsigned long)align - 1))
+#endif
+
+/* round up/down to the next word boundary */
+#ifndef WB_UP
+#define WB_UP(x) ROUND_UP(x, sizeof(void *))
+#endif
+
+#ifndef WB_DN
+#define WB_DN(x) ROUND_DOWN(x, sizeof(void *))
+#endif
+
+#ifndef ceiling_fraction
+#define ceiling_fraction(numerator, divider) \
+ (((numerator) + ((divider) - 1)) / (divider))
+#endif
+
+#ifndef CHECKIF
+#define CHECKIF(expr) if (expr)
+#endif
+
+/** @brief Return larger value of two provided expressions.
+ *
+ * @note Arguments are evaluated twice. See Z_MAX for GCC only, single
+ * evaluation version.
+ */
+#ifndef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+/** @brief Return smaller value of two provided expressions.
+ *
+ * @note Arguments are evaluated twice. See Z_MIN for GCC only, single
+ * evaluation version.
+ */
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef BIT
+#define BIT(n) (1UL << (n))
+#endif
+
+#ifndef BIT_MASK
+#define BIT_MASK(n) (BIT(n) - 1)
+#endif
+
+/**
+ * @brief Check for macro definition in compiler-visible expressions
+ *
+ * This trick was pioneered in Linux as the config_enabled() macro.
+ * The madness has the effect of taking a macro value that may be
+ * defined to "1" (e.g. CONFIG_MYFEATURE), or may not be defined at
+ * all and turning it into a literal expression that can be used at
+ * "runtime". That is, it works similarly to
+ * "defined(CONFIG_MYFEATURE)" does except that it is an expansion
+ * that can exist in a standard expression and be seen by the compiler
+ * and optimizer. Thus much ifdef usage can be replaced with cleaner
+ * expressions like:
+ *
+ * if (IS_ENABLED(CONFIG_MYFEATURE))
+ * myfeature_enable();
+ *
+ * INTERNAL
+ * First pass just to expand any existing macros, we need the macro
+ * value to be e.g. a literal "1" at expansion time in the next macro,
+ * not "(1)", etc... Standard recursive expansion does not work.
+ */
+#define IS_ENABLED(config_macro) Z_IS_ENABLED1(config_macro)
+
+/* Now stick on a "_XXXX" prefix, it will now be "_XXXX1" if config_macro
+ * is "1", or just "_XXXX" if it's undefined.
+ * ENABLED: Z_IS_ENABLED2(_XXXX1)
+ * DISABLED Z_IS_ENABLED2(_XXXX)
+ */
+#define Z_IS_ENABLED1(config_macro) Z_IS_ENABLED2(_XXXX##config_macro)
+
+/* Here's the core trick, we map "_XXXX1" to "_YYYY," (i.e. a string
+ * with a trailing comma), so it has the effect of making this a
+ * two-argument tuple to the preprocessor only in the case where the
+ * value is defined to "1"
+ * ENABLED: _YYYY, <--- note comma!
+ * DISABLED: _XXXX
+ */
+#define _XXXX1 _YYYY,
+
+/* Then we append an extra argument to fool the gcc preprocessor into
+ * accepting it as a varargs macro.
+ * arg1 arg2 arg3
+ * ENABLED: Z_IS_ENABLED3(_YYYY, 1, 0)
+ * DISABLED Z_IS_ENABLED3(_XXXX 1, 0)
+ */
+#define Z_IS_ENABLED2(one_or_two_args) Z_IS_ENABLED3(one_or_two_args true, false)
+
+/* And our second argument is thus now cooked to be 1 in the case
+ * where the value is defined to 1, and 0 if not:
+ */
+#define Z_IS_ENABLED3(ignore_this, val, ...) val
+
+/* Used to remove brackets from around a single argument. */
+#define __DEBRACKET(...) __VA_ARGS__
+
+#define UTIL_CAT(a, ...) UTIL_PRIMITIVE_CAT(a, __VA_ARGS__)
+#define UTIL_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__
+
+/**
+ * @brief Generates a sequence of code with configurable separator.
+ *
+ * Example:
+ *
+ * #define FOO(i, _) MY_PWM ## i
+ * { LISTIFY(PWM_COUNT, FOO, (,)) }
+ *
+ * The above two lines expand to:
+ *
+ * { MY_PWM0 , MY_PWM1 }
+ *
+ * @param LEN The length of the sequence. Must be an integer literal less
+ * than 255.
+ * @param F A macro function that accepts at least two arguments:
+ * <tt>F(i, ...)</tt>. @p F is called repeatedly in the expansion.
+ * Its first argument @p i is the index in the sequence, and
+ * the variable list of arguments passed to LISTIFY are passed
+ * through to @p F.
+ *
+ * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
+ * this is required to enable providing a comma as separator.
+ *
+ * @note Calling LISTIFY with undefined arguments has undefined
+ * behavior.
+ */
+#define LISTIFY(LEN, F, sep, ...) UTIL_CAT(Z_UTIL_LISTIFY_, LEN)(F, sep, __VA_ARGS__)
+
+const char *bt_hex(const void *buf, size_t len);
+
+void mem_rcopy(uint8_t *dst, uint8_t const *src, uint16_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_UTILS_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/utils_loops.h b/lib/bt/esp_ble_mesh/common/include/mesh/utils_loops.h
new file mode 100644
index 00000000..e454f1e0
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/utils_loops.h
@@ -0,0 +1,1051 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/**
+ * @file
+ * @brief Internals for looping macros
+ *
+ * Repetitive or obscure helper macros needed by mesh_util.h.
+ */
+
+#ifndef _BLE_MESH_UTIL_LOOPS_H_
+#define _BLE_MESH_UTIL_LOOPS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Set of UTIL_LISTIFY particles */
+#define Z_UTIL_LISTIFY_0(F, sep, ...)
+
+#define Z_UTIL_LISTIFY_1(F, sep, ...) \
+ F(0, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_2(F, sep, ...) \
+ Z_UTIL_LISTIFY_1(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(1, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_3(F, sep, ...) \
+ Z_UTIL_LISTIFY_2(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(2, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_4(F, sep, ...) \
+ Z_UTIL_LISTIFY_3(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(3, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_5(F, sep, ...) \
+ Z_UTIL_LISTIFY_4(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(4, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_6(F, sep, ...) \
+ Z_UTIL_LISTIFY_5(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(5, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_7(F, sep, ...) \
+ Z_UTIL_LISTIFY_6(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(6, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_8(F, sep, ...) \
+ Z_UTIL_LISTIFY_7(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(7, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_9(F, sep, ...) \
+ Z_UTIL_LISTIFY_8(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(8, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_10(F, sep, ...) \
+ Z_UTIL_LISTIFY_9(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(9, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_11(F, sep, ...) \
+ Z_UTIL_LISTIFY_10(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(10, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_12(F, sep, ...) \
+ Z_UTIL_LISTIFY_11(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(11, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_13(F, sep, ...) \
+ Z_UTIL_LISTIFY_12(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(12, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_14(F, sep, ...) \
+ Z_UTIL_LISTIFY_13(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(13, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_15(F, sep, ...) \
+ Z_UTIL_LISTIFY_14(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(14, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_16(F, sep, ...) \
+ Z_UTIL_LISTIFY_15(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(15, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_17(F, sep, ...) \
+ Z_UTIL_LISTIFY_16(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(16, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_18(F, sep, ...) \
+ Z_UTIL_LISTIFY_17(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(17, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_19(F, sep, ...) \
+ Z_UTIL_LISTIFY_18(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(18, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_20(F, sep, ...) \
+ Z_UTIL_LISTIFY_19(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(19, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_21(F, sep, ...) \
+ Z_UTIL_LISTIFY_20(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(20, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_22(F, sep, ...) \
+ Z_UTIL_LISTIFY_21(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(21, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_23(F, sep, ...) \
+ Z_UTIL_LISTIFY_22(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(22, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_24(F, sep, ...) \
+ Z_UTIL_LISTIFY_23(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(23, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_25(F, sep, ...) \
+ Z_UTIL_LISTIFY_24(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(24, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_26(F, sep, ...) \
+ Z_UTIL_LISTIFY_25(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(25, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_27(F, sep, ...) \
+ Z_UTIL_LISTIFY_26(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(26, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_28(F, sep, ...) \
+ Z_UTIL_LISTIFY_27(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(27, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_29(F, sep, ...) \
+ Z_UTIL_LISTIFY_28(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(28, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_30(F, sep, ...) \
+ Z_UTIL_LISTIFY_29(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(29, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_31(F, sep, ...) \
+ Z_UTIL_LISTIFY_30(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(30, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_32(F, sep, ...) \
+ Z_UTIL_LISTIFY_31(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(31, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_33(F, sep, ...) \
+ Z_UTIL_LISTIFY_32(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(32, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_34(F, sep, ...) \
+ Z_UTIL_LISTIFY_33(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(33, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_35(F, sep, ...) \
+ Z_UTIL_LISTIFY_34(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(34, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_36(F, sep, ...) \
+ Z_UTIL_LISTIFY_35(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(35, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_37(F, sep, ...) \
+ Z_UTIL_LISTIFY_36(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(36, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_38(F, sep, ...) \
+ Z_UTIL_LISTIFY_37(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(37, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_39(F, sep, ...) \
+ Z_UTIL_LISTIFY_38(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(38, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_40(F, sep, ...) \
+ Z_UTIL_LISTIFY_39(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(39, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_41(F, sep, ...) \
+ Z_UTIL_LISTIFY_40(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(40, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_42(F, sep, ...) \
+ Z_UTIL_LISTIFY_41(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(41, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_43(F, sep, ...) \
+ Z_UTIL_LISTIFY_42(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(42, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_44(F, sep, ...) \
+ Z_UTIL_LISTIFY_43(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(43, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_45(F, sep, ...) \
+ Z_UTIL_LISTIFY_44(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(44, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_46(F, sep, ...) \
+ Z_UTIL_LISTIFY_45(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(45, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_47(F, sep, ...) \
+ Z_UTIL_LISTIFY_46(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(46, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_48(F, sep, ...) \
+ Z_UTIL_LISTIFY_47(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(47, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_49(F, sep, ...) \
+ Z_UTIL_LISTIFY_48(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(48, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_50(F, sep, ...) \
+ Z_UTIL_LISTIFY_49(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(49, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_51(F, sep, ...) \
+ Z_UTIL_LISTIFY_50(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(50, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_52(F, sep, ...) \
+ Z_UTIL_LISTIFY_51(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(51, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_53(F, sep, ...) \
+ Z_UTIL_LISTIFY_52(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(52, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_54(F, sep, ...) \
+ Z_UTIL_LISTIFY_53(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(53, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_55(F, sep, ...) \
+ Z_UTIL_LISTIFY_54(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(54, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_56(F, sep, ...) \
+ Z_UTIL_LISTIFY_55(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(55, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_57(F, sep, ...) \
+ Z_UTIL_LISTIFY_56(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(56, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_58(F, sep, ...) \
+ Z_UTIL_LISTIFY_57(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(57, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_59(F, sep, ...) \
+ Z_UTIL_LISTIFY_58(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(58, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_60(F, sep, ...) \
+ Z_UTIL_LISTIFY_59(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(59, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_61(F, sep, ...) \
+ Z_UTIL_LISTIFY_60(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(60, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_62(F, sep, ...) \
+ Z_UTIL_LISTIFY_61(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(61, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_63(F, sep, ...) \
+ Z_UTIL_LISTIFY_62(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(62, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_64(F, sep, ...) \
+ Z_UTIL_LISTIFY_63(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(63, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_65(F, sep, ...) \
+ Z_UTIL_LISTIFY_64(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(64, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_66(F, sep, ...) \
+ Z_UTIL_LISTIFY_65(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(65, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_67(F, sep, ...) \
+ Z_UTIL_LISTIFY_66(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(66, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_68(F, sep, ...) \
+ Z_UTIL_LISTIFY_67(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(67, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_69(F, sep, ...) \
+ Z_UTIL_LISTIFY_68(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(68, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_70(F, sep, ...) \
+ Z_UTIL_LISTIFY_69(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(69, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_71(F, sep, ...) \
+ Z_UTIL_LISTIFY_70(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(70, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_72(F, sep, ...) \
+ Z_UTIL_LISTIFY_71(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(71, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_73(F, sep, ...) \
+ Z_UTIL_LISTIFY_72(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(72, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_74(F, sep, ...) \
+ Z_UTIL_LISTIFY_73(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(73, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_75(F, sep, ...) \
+ Z_UTIL_LISTIFY_74(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(74, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_76(F, sep, ...) \
+ Z_UTIL_LISTIFY_75(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(75, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_77(F, sep, ...) \
+ Z_UTIL_LISTIFY_76(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(76, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_78(F, sep, ...) \
+ Z_UTIL_LISTIFY_77(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(77, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_79(F, sep, ...) \
+ Z_UTIL_LISTIFY_78(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(78, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_80(F, sep, ...) \
+ Z_UTIL_LISTIFY_79(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(79, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_81(F, sep, ...) \
+ Z_UTIL_LISTIFY_80(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(80, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_82(F, sep, ...) \
+ Z_UTIL_LISTIFY_81(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(81, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_83(F, sep, ...) \
+ Z_UTIL_LISTIFY_82(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(82, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_84(F, sep, ...) \
+ Z_UTIL_LISTIFY_83(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(83, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_85(F, sep, ...) \
+ Z_UTIL_LISTIFY_84(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(84, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_86(F, sep, ...) \
+ Z_UTIL_LISTIFY_85(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(85, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_87(F, sep, ...) \
+ Z_UTIL_LISTIFY_86(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(86, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_88(F, sep, ...) \
+ Z_UTIL_LISTIFY_87(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(87, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_89(F, sep, ...) \
+ Z_UTIL_LISTIFY_88(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(88, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_90(F, sep, ...) \
+ Z_UTIL_LISTIFY_89(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(89, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_91(F, sep, ...) \
+ Z_UTIL_LISTIFY_90(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(90, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_92(F, sep, ...) \
+ Z_UTIL_LISTIFY_91(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(91, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_93(F, sep, ...) \
+ Z_UTIL_LISTIFY_92(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(92, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_94(F, sep, ...) \
+ Z_UTIL_LISTIFY_93(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(93, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_95(F, sep, ...) \
+ Z_UTIL_LISTIFY_94(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(94, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_96(F, sep, ...) \
+ Z_UTIL_LISTIFY_95(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(95, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_97(F, sep, ...) \
+ Z_UTIL_LISTIFY_96(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(96, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_98(F, sep, ...) \
+ Z_UTIL_LISTIFY_97(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(97, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_99(F, sep, ...) \
+ Z_UTIL_LISTIFY_98(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(98, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_100(F, sep, ...) \
+ Z_UTIL_LISTIFY_99(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(99, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_101(F, sep, ...) \
+ Z_UTIL_LISTIFY_100(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(100, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_102(F, sep, ...) \
+ Z_UTIL_LISTIFY_101(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(101, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_103(F, sep, ...) \
+ Z_UTIL_LISTIFY_102(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(102, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_104(F, sep, ...) \
+ Z_UTIL_LISTIFY_103(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(103, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_105(F, sep, ...) \
+ Z_UTIL_LISTIFY_104(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(104, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_106(F, sep, ...) \
+ Z_UTIL_LISTIFY_105(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(105, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_107(F, sep, ...) \
+ Z_UTIL_LISTIFY_106(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(106, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_108(F, sep, ...) \
+ Z_UTIL_LISTIFY_107(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(107, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_109(F, sep, ...) \
+ Z_UTIL_LISTIFY_108(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(108, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_110(F, sep, ...) \
+ Z_UTIL_LISTIFY_109(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(109, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_111(F, sep, ...) \
+ Z_UTIL_LISTIFY_110(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(110, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_112(F, sep, ...) \
+ Z_UTIL_LISTIFY_111(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(111, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_113(F, sep, ...) \
+ Z_UTIL_LISTIFY_112(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(112, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_114(F, sep, ...) \
+ Z_UTIL_LISTIFY_113(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(113, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_115(F, sep, ...) \
+ Z_UTIL_LISTIFY_114(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(114, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_116(F, sep, ...) \
+ Z_UTIL_LISTIFY_115(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(115, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_117(F, sep, ...) \
+ Z_UTIL_LISTIFY_116(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(116, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_118(F, sep, ...) \
+ Z_UTIL_LISTIFY_117(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(117, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_119(F, sep, ...) \
+ Z_UTIL_LISTIFY_118(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(118, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_120(F, sep, ...) \
+ Z_UTIL_LISTIFY_119(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(119, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_121(F, sep, ...) \
+ Z_UTIL_LISTIFY_120(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(120, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_122(F, sep, ...) \
+ Z_UTIL_LISTIFY_121(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(121, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_123(F, sep, ...) \
+ Z_UTIL_LISTIFY_122(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(122, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_124(F, sep, ...) \
+ Z_UTIL_LISTIFY_123(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(123, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_125(F, sep, ...) \
+ Z_UTIL_LISTIFY_124(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(124, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_126(F, sep, ...) \
+ Z_UTIL_LISTIFY_125(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(125, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_127(F, sep, ...) \
+ Z_UTIL_LISTIFY_126(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(126, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_128(F, sep, ...) \
+ Z_UTIL_LISTIFY_127(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(127, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_129(F, sep, ...) \
+ Z_UTIL_LISTIFY_128(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(128, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_130(F, sep, ...) \
+ Z_UTIL_LISTIFY_129(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(129, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_131(F, sep, ...) \
+ Z_UTIL_LISTIFY_130(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(130, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_132(F, sep, ...) \
+ Z_UTIL_LISTIFY_131(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(131, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_133(F, sep, ...) \
+ Z_UTIL_LISTIFY_132(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(132, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_134(F, sep, ...) \
+ Z_UTIL_LISTIFY_133(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(133, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_135(F, sep, ...) \
+ Z_UTIL_LISTIFY_134(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(134, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_136(F, sep, ...) \
+ Z_UTIL_LISTIFY_135(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(135, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_137(F, sep, ...) \
+ Z_UTIL_LISTIFY_136(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(136, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_138(F, sep, ...) \
+ Z_UTIL_LISTIFY_137(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(137, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_139(F, sep, ...) \
+ Z_UTIL_LISTIFY_138(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(138, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_140(F, sep, ...) \
+ Z_UTIL_LISTIFY_139(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(139, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_141(F, sep, ...) \
+ Z_UTIL_LISTIFY_140(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(140, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_142(F, sep, ...) \
+ Z_UTIL_LISTIFY_141(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(141, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_143(F, sep, ...) \
+ Z_UTIL_LISTIFY_142(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(142, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_144(F, sep, ...) \
+ Z_UTIL_LISTIFY_143(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(143, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_145(F, sep, ...) \
+ Z_UTIL_LISTIFY_144(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(144, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_146(F, sep, ...) \
+ Z_UTIL_LISTIFY_145(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(145, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_147(F, sep, ...) \
+ Z_UTIL_LISTIFY_146(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(146, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_148(F, sep, ...) \
+ Z_UTIL_LISTIFY_147(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(147, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_149(F, sep, ...) \
+ Z_UTIL_LISTIFY_148(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(148, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_150(F, sep, ...) \
+ Z_UTIL_LISTIFY_149(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(149, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_151(F, sep, ...) \
+ Z_UTIL_LISTIFY_150(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(150, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_152(F, sep, ...) \
+ Z_UTIL_LISTIFY_151(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(151, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_153(F, sep, ...) \
+ Z_UTIL_LISTIFY_152(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(152, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_154(F, sep, ...) \
+ Z_UTIL_LISTIFY_153(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(153, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_155(F, sep, ...) \
+ Z_UTIL_LISTIFY_154(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(154, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_156(F, sep, ...) \
+ Z_UTIL_LISTIFY_155(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(155, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_157(F, sep, ...) \
+ Z_UTIL_LISTIFY_156(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(156, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_158(F, sep, ...) \
+ Z_UTIL_LISTIFY_157(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(157, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_159(F, sep, ...) \
+ Z_UTIL_LISTIFY_158(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(158, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_160(F, sep, ...) \
+ Z_UTIL_LISTIFY_159(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(159, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_161(F, sep, ...) \
+ Z_UTIL_LISTIFY_160(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(160, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_162(F, sep, ...) \
+ Z_UTIL_LISTIFY_161(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(161, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_163(F, sep, ...) \
+ Z_UTIL_LISTIFY_162(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(162, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_164(F, sep, ...) \
+ Z_UTIL_LISTIFY_163(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(163, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_165(F, sep, ...) \
+ Z_UTIL_LISTIFY_164(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(164, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_166(F, sep, ...) \
+ Z_UTIL_LISTIFY_165(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(165, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_167(F, sep, ...) \
+ Z_UTIL_LISTIFY_166(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(166, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_168(F, sep, ...) \
+ Z_UTIL_LISTIFY_167(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(167, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_169(F, sep, ...) \
+ Z_UTIL_LISTIFY_168(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(168, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_170(F, sep, ...) \
+ Z_UTIL_LISTIFY_169(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(169, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_171(F, sep, ...) \
+ Z_UTIL_LISTIFY_170(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(170, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_172(F, sep, ...) \
+ Z_UTIL_LISTIFY_171(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(171, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_173(F, sep, ...) \
+ Z_UTIL_LISTIFY_172(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(172, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_174(F, sep, ...) \
+ Z_UTIL_LISTIFY_173(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(173, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_175(F, sep, ...) \
+ Z_UTIL_LISTIFY_174(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(174, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_176(F, sep, ...) \
+ Z_UTIL_LISTIFY_175(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(175, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_177(F, sep, ...) \
+ Z_UTIL_LISTIFY_176(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(176, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_178(F, sep, ...) \
+ Z_UTIL_LISTIFY_177(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(177, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_179(F, sep, ...) \
+ Z_UTIL_LISTIFY_178(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(178, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_180(F, sep, ...) \
+ Z_UTIL_LISTIFY_179(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(179, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_181(F, sep, ...) \
+ Z_UTIL_LISTIFY_180(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(180, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_182(F, sep, ...) \
+ Z_UTIL_LISTIFY_181(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(181, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_183(F, sep, ...) \
+ Z_UTIL_LISTIFY_182(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(182, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_184(F, sep, ...) \
+ Z_UTIL_LISTIFY_183(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(183, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_185(F, sep, ...) \
+ Z_UTIL_LISTIFY_184(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(184, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_186(F, sep, ...) \
+ Z_UTIL_LISTIFY_185(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(185, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_187(F, sep, ...) \
+ Z_UTIL_LISTIFY_186(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(186, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_188(F, sep, ...) \
+ Z_UTIL_LISTIFY_187(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(187, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_189(F, sep, ...) \
+ Z_UTIL_LISTIFY_188(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(188, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_190(F, sep, ...) \
+ Z_UTIL_LISTIFY_189(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(189, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_191(F, sep, ...) \
+ Z_UTIL_LISTIFY_190(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(190, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_192(F, sep, ...) \
+ Z_UTIL_LISTIFY_191(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(191, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_193(F, sep, ...) \
+ Z_UTIL_LISTIFY_192(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(192, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_194(F, sep, ...) \
+ Z_UTIL_LISTIFY_193(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(193, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_195(F, sep, ...) \
+ Z_UTIL_LISTIFY_194(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(194, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_196(F, sep, ...) \
+ Z_UTIL_LISTIFY_195(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(195, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_197(F, sep, ...) \
+ Z_UTIL_LISTIFY_196(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(196, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_198(F, sep, ...) \
+ Z_UTIL_LISTIFY_197(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(197, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_199(F, sep, ...) \
+ Z_UTIL_LISTIFY_198(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(198, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_200(F, sep, ...) \
+ Z_UTIL_LISTIFY_199(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(199, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_201(F, sep, ...) \
+ Z_UTIL_LISTIFY_200(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(200, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_202(F, sep, ...) \
+ Z_UTIL_LISTIFY_201(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(201, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_203(F, sep, ...) \
+ Z_UTIL_LISTIFY_202(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(202, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_204(F, sep, ...) \
+ Z_UTIL_LISTIFY_203(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(203, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_205(F, sep, ...) \
+ Z_UTIL_LISTIFY_204(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(204, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_206(F, sep, ...) \
+ Z_UTIL_LISTIFY_205(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(205, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_207(F, sep, ...) \
+ Z_UTIL_LISTIFY_206(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(206, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_208(F, sep, ...) \
+ Z_UTIL_LISTIFY_207(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(207, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_209(F, sep, ...) \
+ Z_UTIL_LISTIFY_208(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(208, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_210(F, sep, ...) \
+ Z_UTIL_LISTIFY_209(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(209, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_211(F, sep, ...) \
+ Z_UTIL_LISTIFY_210(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(210, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_212(F, sep, ...) \
+ Z_UTIL_LISTIFY_211(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(211, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_213(F, sep, ...) \
+ Z_UTIL_LISTIFY_212(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(212, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_214(F, sep, ...) \
+ Z_UTIL_LISTIFY_213(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(213, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_215(F, sep, ...) \
+ Z_UTIL_LISTIFY_214(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(214, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_216(F, sep, ...) \
+ Z_UTIL_LISTIFY_215(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(215, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_217(F, sep, ...) \
+ Z_UTIL_LISTIFY_216(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(216, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_218(F, sep, ...) \
+ Z_UTIL_LISTIFY_217(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(217, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_219(F, sep, ...) \
+ Z_UTIL_LISTIFY_218(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(218, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_220(F, sep, ...) \
+ Z_UTIL_LISTIFY_219(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(219, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_221(F, sep, ...) \
+ Z_UTIL_LISTIFY_220(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(220, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_222(F, sep, ...) \
+ Z_UTIL_LISTIFY_221(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(221, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_223(F, sep, ...) \
+ Z_UTIL_LISTIFY_222(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(222, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_224(F, sep, ...) \
+ Z_UTIL_LISTIFY_223(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(223, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_225(F, sep, ...) \
+ Z_UTIL_LISTIFY_224(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(224, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_226(F, sep, ...) \
+ Z_UTIL_LISTIFY_225(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(225, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_227(F, sep, ...) \
+ Z_UTIL_LISTIFY_226(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(226, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_228(F, sep, ...) \
+ Z_UTIL_LISTIFY_227(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(227, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_229(F, sep, ...) \
+ Z_UTIL_LISTIFY_228(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(228, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_230(F, sep, ...) \
+ Z_UTIL_LISTIFY_229(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(229, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_231(F, sep, ...) \
+ Z_UTIL_LISTIFY_230(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(230, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_232(F, sep, ...) \
+ Z_UTIL_LISTIFY_231(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(231, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_233(F, sep, ...) \
+ Z_UTIL_LISTIFY_232(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(232, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_234(F, sep, ...) \
+ Z_UTIL_LISTIFY_233(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(233, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_235(F, sep, ...) \
+ Z_UTIL_LISTIFY_234(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(234, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_236(F, sep, ...) \
+ Z_UTIL_LISTIFY_235(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(235, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_237(F, sep, ...) \
+ Z_UTIL_LISTIFY_236(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(236, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_238(F, sep, ...) \
+ Z_UTIL_LISTIFY_237(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(237, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_239(F, sep, ...) \
+ Z_UTIL_LISTIFY_238(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(238, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_240(F, sep, ...) \
+ Z_UTIL_LISTIFY_239(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(239, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_241(F, sep, ...) \
+ Z_UTIL_LISTIFY_240(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(240, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_242(F, sep, ...) \
+ Z_UTIL_LISTIFY_241(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(241, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_243(F, sep, ...) \
+ Z_UTIL_LISTIFY_242(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(242, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_244(F, sep, ...) \
+ Z_UTIL_LISTIFY_243(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(243, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_245(F, sep, ...) \
+ Z_UTIL_LISTIFY_244(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(244, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_246(F, sep, ...) \
+ Z_UTIL_LISTIFY_245(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(245, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_247(F, sep, ...) \
+ Z_UTIL_LISTIFY_246(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(246, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_248(F, sep, ...) \
+ Z_UTIL_LISTIFY_247(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(247, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_249(F, sep, ...) \
+ Z_UTIL_LISTIFY_248(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(248, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_250(F, sep, ...) \
+ Z_UTIL_LISTIFY_249(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(249, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_251(F, sep, ...) \
+ Z_UTIL_LISTIFY_250(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(250, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_252(F, sep, ...) \
+ Z_UTIL_LISTIFY_251(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(251, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_253(F, sep, ...) \
+ Z_UTIL_LISTIFY_252(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(252, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_254(F, sep, ...) \
+ Z_UTIL_LISTIFY_253(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(253, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_255(F, sep, ...) \
+ Z_UTIL_LISTIFY_254(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(254, __VA_ARGS__)
+
+#define Z_UTIL_LISTIFY_256(F, sep, ...) \
+ Z_UTIL_LISTIFY_255(F, sep, __VA_ARGS__) __DEBRACKET sep \
+ F(255, __VA_ARGS__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_UTIL_LOOPS_H_ */