Просмотр исходного кода

update nimble porting with freertos

sakumisu 2 лет назад
Родитель
Сommit
c7cf09f6c3
31 измененных файлов с 7467 добавлено и 16 удалено
  1. 0 0
      third_party/nimble-1.6.0/README.md
  2. 32 16
      third_party/nimble-1.6.0/ble_hci_usbh.c
  3. 70 0
      third_party/nimble-1.6.0/porting/nimble/include/mem/mem.h
  4. 43 0
      third_party/nimble-1.6.0/porting/nimble/include/nimble/nimble_port.h
  5. 229 0
      third_party/nimble-1.6.0/porting/nimble/include/os/endian.h
  6. 55 0
      third_party/nimble-1.6.0/porting/nimble/include/os/os.h
  7. 239 0
      third_party/nimble-1.6.0/porting/nimble/include/os/os_cputime.h
  8. 62 0
      third_party/nimble-1.6.0/porting/nimble/include/os/os_error.h
  9. 677 0
      third_party/nimble-1.6.0/porting/nimble/include/os/os_mbuf.h
  10. 287 0
      third_party/nimble-1.6.0/porting/nimble/include/os/os_mempool.h
  11. 277 0
      third_party/nimble-1.6.0/porting/nimble/include/os/os_trace_api.h
  12. 522 0
      third_party/nimble-1.6.0/porting/nimble/include/os/queue.h
  13. 38 0
      third_party/nimble-1.6.0/porting/nimble/include/os/util.h
  14. 80 0
      third_party/nimble-1.6.0/porting/nimble/include/stats/stats.h
  15. 51 0
      third_party/nimble-1.6.0/porting/nimble/include/sysflash/sysflash.h
  16. 38 0
      third_party/nimble-1.6.0/porting/nimble/include/sysinit/sysinit.h
  17. 268 0
      third_party/nimble-1.6.0/porting/nimble/src/endian.c
  18. 324 0
      third_party/nimble-1.6.0/porting/nimble/src/mem.c
  19. 84 0
      third_party/nimble-1.6.0/porting/nimble/src/nimble_port.c
  20. 1253 0
      third_party/nimble-1.6.0/porting/nimble/src/os_mbuf.c
  21. 476 0
      third_party/nimble-1.6.0/porting/nimble/src/os_mempool.c
  22. 156 0
      third_party/nimble-1.6.0/porting/nimble/src/os_msys_init.c
  23. 14 0
      third_party/nimble-1.6.0/porting/npl/freertos/include/console/console.h
  24. 300 0
      third_party/nimble-1.6.0/porting/npl/freertos/include/nimble/nimble_npl_os.h
  25. 35 0
      third_party/nimble-1.6.0/porting/npl/freertos/include/nimble/nimble_npl_os_log.h
  26. 35 0
      third_party/nimble-1.6.0/porting/npl/freertos/include/nimble/nimble_port_freertos.h
  27. 76 0
      third_party/nimble-1.6.0/porting/npl/freertos/include/nimble/npl_freertos.h
  28. 1344 0
      third_party/nimble-1.6.0/porting/npl/freertos/include/syscfg/syscfg.h
  29. 51 0
      third_party/nimble-1.6.0/porting/npl/freertos/src/nimble_port_freertos.c
  30. 351 0
      third_party/nimble-1.6.0/porting/npl/freertos/src/npl_os_freertos.c
  31. 0 0
      third_party/zephyr_bluetooth-2.x.x/ble_hci_usbh.c

+ 0 - 0
third_party/nimble-latest/README.md → third_party/nimble-1.6.0/README.md


+ 32 - 16
third_party/nimble-latest/ble_hci_usbh.c → third_party/nimble-1.6.0/ble_hci_usbh.c

@@ -7,20 +7,22 @@
 #include "usbh_core.h"
 #include "usbh_bluetooth.h"
 
-#include <sysinit/sysinit.h>
-#include <syscfg/syscfg.h>
-#include "os/os_mbuf.h"
 #include <nimble/ble.h>
 #include "nimble/transport.h"
 #include "nimble/transport/hci_h4.h"
 
 struct hci_h4_sm g_hci_h4sm;
 
+void ble_transport_ll_init(void)
+{
+    /* nothing here */
+}
+
 static void hci_dump(uint8_t hci_type, uint8_t *data, uint32_t len)
 {
     uint32_t i = 0;
 
-    USB_LOG_DBG("hci type:%u\r\n", hci_type);
+    USB_LOG_DBG("\r\nhci type:%u", hci_type);
 
     for (i = 0; i < len; i++) {
         if (i % 16 == 0) {
@@ -80,18 +82,6 @@ void usbh_bluetooth_hci_rx_callback(uint8_t hci_type, uint8_t *data, uint32_t le
     hci_h4_sm_rx(&g_hci_h4sm, data, len);
 }
 
-void usbh_bluetooth_run(struct usbh_bluetooth *bluetooth_class)
-{
-    ble_usb_transport_init();
-
-    usb_osal_thread_create("ble_event", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_bluetooth_hci_event_rx_thread, NULL);
-    usb_osal_thread_create("ble_acl", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_bluetooth_hci_acl_rx_thread, NULL);
-}
-
-void usbh_bluetooth_stop(struct usbh_bluetooth *bluetooth_class)
-{
-}
-
 int ble_transport_to_ll_cmd_impl(void *buf)
 {
     int ret = 0;
@@ -133,3 +123,29 @@ int ble_transport_to_ll_acl_impl(struct os_mbuf *om)
 
     return ret;
 }
+
+
+__WEAK void usbh_bluetooth_run_callback(void)
+{
+    /* bt_enable() */
+}
+
+__WEAK void usbh_bluetooth_stop_callback(void)
+{
+    /* bt_disable() */
+}
+
+void usbh_bluetooth_run(struct usbh_bluetooth *bluetooth_class)
+{
+    ble_usb_transport_init();
+
+    usb_osal_thread_create("ble_event", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_bluetooth_hci_event_rx_thread, NULL);
+    usb_osal_thread_create("ble_acl", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_bluetooth_hci_acl_rx_thread, NULL);
+
+    usbh_bluetooth_run_callback();
+}
+
+void usbh_bluetooth_stop(struct usbh_bluetooth *bluetooth_class)
+{
+    usbh_bluetooth_stop_callback();
+}

+ 70 - 0
third_party/nimble-1.6.0/porting/nimble/include/mem/mem.h

@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_UTIL_MEM_
+#define H_UTIL_MEM_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct os_mempool;
+struct os_mbuf_pool;
+
+int mem_malloc_mempool(struct os_mempool *mempool, uint16_t num_blocks,
+                       uint32_t block_size, char *name, void **out_buf);
+int mem_malloc_mempool_ext(struct os_mempool_ext *mempool, uint16_t num_blocks,
+                           uint32_t block_size, char *name, void **out_buf);
+
+int mem_malloc_mbuf_pool(struct os_mempool *mempool,
+                         struct os_mbuf_pool *mbuf_pool, uint16_t num_blocks,
+                         uint32_t block_size, char *name,
+                         void **out_buf);
+int mem_malloc_mbufpkt_pool(struct os_mempool *mempool,
+                            struct os_mbuf_pool *mbuf_pool, int num_blocks,
+                            int block_size, char *name,
+                            void **out_buf);
+int mem_init_mbuf_pool(void *mem, struct os_mempool *mempool,
+                       struct os_mbuf_pool *mbuf_pool, int num_blocks,
+                       int block_size, char *name);
+
+/**
+ * Specifies a function used as a callback.  Functions of this type allocate an
+ * mbuf chain meant to hold a packet fragment.  The resulting mbuf must contain
+ * a pkthdr.
+ *
+ * @param frag_size             The number of data bytes that the mbuf will
+ *                                  eventually contain.
+ * @param arg                   A generic parameter.
+ *
+ * @return                      An allocated mbuf chain on success;
+ *                              NULL on failure.
+ */
+typedef struct os_mbuf *mem_frag_alloc_fn(uint16_t frag_size, void *arg);
+
+struct os_mbuf *mem_split_frag(struct os_mbuf **om, uint16_t max_frag_sz,
+                               mem_frag_alloc_fn *alloc_cb, void *cb_arg);
+
+void *mem_pullup_obj(struct os_mbuf **om, uint16_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 43 - 0
third_party/nimble-1.6.0/porting/nimble/include/nimble/nimble_port.h

@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _NIMBLE_PORT_H
+#define _NIMBLE_PORT_H
+
+#include "nimble/nimble_npl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void nimble_port_init(void);
+
+void nimble_port_run(void);
+
+struct ble_npl_eventq *nimble_port_get_dflt_eventq(void);
+
+#if NIMBLE_CFG_CONTROLLER
+void nimble_port_ll_task_func(void *arg);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NIMBLE_PORT_H */

+ 229 - 0
third_party/nimble-1.6.0/porting/nimble/include/os/endian.h

@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_ENDIAN_
+#define H_ENDIAN_
+
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Internal helpers */
+#ifndef os_bswap_64
+#define os_bswap_64(x)   ((uint64_t)                \
+     ((((x) & 0xff00000000000000ull) >> 56) |       \
+      (((x) & 0x00ff000000000000ull) >> 40) |       \
+      (((x) & 0x0000ff0000000000ull) >> 24) |       \
+      (((x) & 0x000000ff00000000ull) >>  8) |       \
+      (((x) & 0x00000000ff000000ull) <<  8) |       \
+      (((x) & 0x0000000000ff0000ull) << 24) |       \
+      (((x) & 0x000000000000ff00ull) << 40) |       \
+      (((x) & 0x00000000000000ffull) << 56)))
+#endif
+
+#ifndef os_bswap_32
+#define os_bswap_32(x)    ((uint32_t)               \
+    ((((x) & 0xff000000) >> 24) |                   \
+     (((x) & 0x00ff0000) >>  8) |                   \
+     (((x) & 0x0000ff00) <<  8) |                   \
+     (((x) & 0x000000ff) << 24)))
+#endif
+
+#ifndef os_bswap_16
+#define os_bswap_16(x)   ((uint16_t)                \
+    ((((x) & 0xff00) >> 8) |                        \
+     (((x) & 0x00ff) << 8)))
+#endif
+
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+
+#ifndef ntohll
+#define ntohll(x)  ((uint64_t)(x))
+#endif
+
+#ifndef htonll
+#define htonll(x)  ((uint64_t)(x))
+#endif
+
+#ifndef ntohl
+#define ntohl(x)   ((uint32_t)(x))
+#endif
+
+#ifndef htonl
+#define htonl(x)   ((uint32_t)(x))
+#endif
+
+#ifndef ntohs
+#define ntohs(x)   ((uint16_t)(x))
+#endif
+
+#ifndef htons
+#define htons(x)   ((uint16_t)(x))
+#endif
+
+#ifndef htobe16
+#define htobe16(x) ((uint16_t)(x))
+#endif
+
+#ifndef htole16
+#define htole16(x) os_bswap_16 (x)
+#endif
+
+#ifndef be16toh
+#define be16toh(x) ((uint16_t)(x))
+#endif
+
+#ifndef le16toh
+#define le16toh(x) os_bswap_16 (x)
+#endif
+
+#ifndef htobe32
+#define htobe32(x) ((uint32_t)(x))
+#endif
+
+#ifndef htole32
+#define htole32(x) os_bswap_32 (x)
+#endif
+
+#ifndef be32toh
+#define be32toh(x) ((uint32_t)(x))
+#endif
+
+#ifndef le32toh
+#define le32toh(x) os_bswap_32 (x)
+#endif
+
+#ifndef htobe64
+#define htobe64(x) ((uint64_t)(x))
+#endif
+
+#ifndef htole64
+#define htole64(x) os_bswap_64 (x)
+#endif
+
+#ifndef be64toh
+#define be64toh(x) ((uint64_t)(x))
+#endif
+
+#ifndef le64toh
+#define le64toh(x) os_bswap_64 (x)
+#endif
+
+#else
+
+#ifndef ntohll
+#define ntohll(x)   os_bswap_64(x)
+#endif
+
+#ifndef htonll
+#define htonll      ntohll
+#endif
+
+#ifndef ntohl
+#define ntohl(x)    os_bswap_32(x)
+#endif
+
+#ifndef htonl
+#define htonl       ntohl
+#endif
+
+#ifndef htons
+#define htons(x)    os_bswap_16(x)
+#endif
+
+#ifndef ntohs
+#define ntohs       htons
+#endif
+
+#ifndef htobe16
+#define htobe16(x) os_bswap_16(x)
+#endif
+
+#ifndef htole16
+#define htole16(x) ((uint16_t)(x))
+#endif
+
+#ifndef be16toh
+#define be16toh(x) os_bswap_16(x)
+#endif
+
+#ifndef le16toh
+#define le16toh(x) ((uint16_t)(x))
+#endif
+
+#ifndef htobe32
+#define htobe32(x) os_bswap_32(x)
+#endif
+
+#ifndef htole32
+#define htole32(x) ((uint32_t)(x))
+#endif
+
+#ifndef be32toh
+#define be32toh(x) os_bswap_32(x)
+#endif
+
+#ifndef le32toh
+#define le32toh(x) ((uint32_t)(x))
+#endif
+
+#ifndef htobe64
+#define htobe64(x) os_bswap_64(x)
+#endif
+
+#ifndef htole64
+#define htole64(x) ((uint64_t)(x))
+#endif
+
+#ifndef be64toh
+#define be64toh(x) os_bswap_64(x)
+#endif
+
+#ifndef le64toh
+#define le64toh(x) ((uint64_t)(x))
+#endif
+
+#endif
+
+void put_le16(void *buf, uint16_t x);
+void put_le24(void *buf, uint32_t x);
+void put_le32(void *buf, uint32_t x);
+void put_le64(void *buf, uint64_t x);
+uint16_t get_le16(const void *buf);
+uint32_t get_le24(const void *buf);
+uint32_t get_le32(const void *buf);
+uint64_t get_le64(const void *buf);
+void put_be16(void *buf, uint16_t x);
+void put_be24(void *buf, uint32_t x);
+void put_be32(void *buf, uint32_t x);
+void put_be64(void *buf, uint64_t x);
+uint16_t get_be16(const void *buf);
+uint32_t get_be24(const void *buf);
+uint32_t get_be32(const void *buf);
+uint64_t get_be64(const void *buf);
+void swap_in_place(void *buf, int len);
+void swap_buf(uint8_t *dst, const uint8_t *src, int len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 55 - 0
third_party/nimble-1.6.0/porting/nimble/include/os/os.h

@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _OS_H
+#define _OS_H
+
+#include <assert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "syscfg/syscfg.h"
+#include "nimble/nimble_npl.h"
+
+#define OS_ALIGN(__n, __a) (                             \
+        (((__n) & ((__a) - 1)) == 0)                   ? \
+            (__n)                                      : \
+            ((__n) + ((__a) - ((__n) & ((__a) - 1))))    \
+        )
+#define OS_ALIGNMENT    (BLE_NPL_OS_ALIGNMENT)
+
+typedef uint32_t os_sr_t;
+#define OS_ENTER_CRITICAL(_sr) (_sr = ble_npl_hw_enter_critical())
+#define OS_EXIT_CRITICAL(_sr) (ble_npl_hw_exit_critical(_sr))
+#define OS_ASSERT_CRITICAL() assert(ble_npl_hw_is_in_critical())
+
+/* Mynewt components (not abstracted in NPL) */
+#include "os/endian.h"
+#include "os/queue.h"
+#include "os/os_error.h"
+#include "os/os_mbuf.h"
+#include "os/os_mempool.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OS_H */

+ 239 - 0
third_party/nimble-1.6.0/porting/nimble/include/os/os_cputime.h

@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @addtogroup OSKernel
+ * @{
+ *   @defgroup OSCPUTime High Resolution Timers
+ *   @{
+ */
+
+#ifndef H_OS_CPUTIME_
+#define H_OS_CPUTIME_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "syscfg/syscfg.h"
+#include "hal/hal_timer.h"
+
+/*
+ * NOTE: these definitions allow one to override the cputime frequency used.
+ * The reason these definitions exist is to make the code more
+ * efficient/smaller when CPUTIME counts at 1 MHz.
+ *
+ * For those who want a different cputime frequency, you can set the config
+ * definition for OS_CPUTIME_FREQ to the desired frequency in your project,
+ * target or bsp.
+ */
+#if (MYNEWT_VAL(OS_CPUTIME_FREQ) == 1000000)
+
+#define OS_CPUTIME_FREQ_1MHZ
+
+#elif MYNEWT_VAL(OS_CPUTIME_FREQ) == 256        ||  \
+      MYNEWT_VAL(OS_CPUTIME_FREQ) == 512        ||  \
+      MYNEWT_VAL(OS_CPUTIME_FREQ) == 1024       ||  \
+      MYNEWT_VAL(OS_CPUTIME_FREQ) == 2048       ||  \
+      MYNEWT_VAL(OS_CPUTIME_FREQ) == 4096       ||  \
+      MYNEWT_VAL(OS_CPUTIME_FREQ) == 8192       ||  \
+      MYNEWT_VAL(OS_CPUTIME_FREQ) == 16384      ||  \
+      MYNEWT_VAL(OS_CPUTIME_FREQ) == 32768      ||  \
+      MYNEWT_VAL(OS_CPUTIME_FREQ) == 65536      ||  \
+      MYNEWT_VAL(OS_CPUTIME_FREQ) == 131072     ||  \
+      MYNEWT_VAL(OS_CPUTIME_FREQ) == 262144     ||  \
+      MYNEWT_VAL(OS_CPUTIME_FREQ) == 524288
+
+#define OS_CPUTIME_FREQ_PWR2
+
+#elif MYNEWT_VAL(OS_CPUTIME_FREQ) > 1000000
+
+#define OS_CPUTIME_FREQ_HIGH
+
+#else
+
+#error "Invalid OS_CPUTIME_FREQ value.  Value must be one of a) a power of 2" \
+       ">= 256Hz, or b) any value >= 1MHz"
+
+#endif
+
+#if defined(OS_CPUTIME_FREQ_HIGH)
+/* CPUTIME data. */
+struct os_cputime_data
+{
+    uint32_t ticks_per_usec;    /* number of ticks per usec */
+};
+extern struct os_cputime_data g_os_cputime;
+#endif
+
+/* Helpful macros to compare cputimes */
+/** evaluates to true if t1 is before t2 in time */
+#define CPUTIME_LT(__t1, __t2) ((int32_t)   ((__t1) - (__t2)) < 0)
+/** evaluates to true if t1 is after t2 in time */
+#define CPUTIME_GT(__t1, __t2) ((int32_t)   ((__t1) - (__t2)) > 0)
+/** evaluates to true if t1 is on or after t2 in time */
+#define CPUTIME_GEQ(__t1, __t2) ((int32_t)  ((__t1) - (__t2)) >= 0)
+/** evaluates to true if t1 is on or before t2 in time */
+#define CPUTIME_LEQ(__t1, __t2) ((int32_t)  ((__t1) - (__t2)) <= 0)
+
+/**
+ * Initialize the cputime module. This must be called after os_init is called
+ * and before any other timer API are used. This should be called only once
+ * and should be called before the hardware timer is used.
+ *
+ * @param clock_freq The desired cputime frequency, in hertz (Hz).
+ *
+ * @return int 0 on success; -1 on error.
+ */
+int os_cputime_init(uint32_t clock_freq);
+
+/**
+ * Returns the low 32 bits of cputime.
+ *
+ * @return uint32_t The lower 32 bits of cputime
+ */
+uint32_t os_cputime_get32(void);
+
+#if !defined(OS_CPUTIME_FREQ_PWR2)
+/**
+ * Converts the given number of nanoseconds into cputime ticks.
+ * Not defined if OS_CPUTIME_FREQ_PWR2 is defined.
+ *
+ * @param usecs The number of nanoseconds to convert to ticks
+ *
+ * @return uint32_t The number of ticks corresponding to 'nsecs'
+ */
+uint32_t os_cputime_nsecs_to_ticks(uint32_t nsecs);
+
+/**
+ * Convert the given number of ticks into nanoseconds.
+ * Not defined if OS_CPUTIME_FREQ_PWR2 is defined.
+ *
+ * @param ticks The number of ticks to convert to nanoseconds.
+ *
+ * @return uint32_t The number of nanoseconds corresponding to 'ticks'
+ */
+uint32_t os_cputime_ticks_to_nsecs(uint32_t ticks);
+
+/**
+ * Wait until 'nsecs' nanoseconds has elapsed. This is a blocking delay.
+ * Not defined if OS_CPUTIME_FREQ_PWR2 is defined.
+ *
+ *
+ * @param nsecs The number of nanoseconds to wait.
+ */
+void os_cputime_delay_nsecs(uint32_t nsecs);
+#endif
+
+#if defined(OS_CPUTIME_FREQ_1MHZ)
+#define os_cputime_usecs_to_ticks(x)    (x)
+#define os_cputime_ticks_to_usecs(x)    (x)
+#else
+
+/**
+ * Converts the given number of microseconds into cputime ticks.
+ *
+ * @param usecs The number of microseconds to convert to ticks
+ *
+ * @return uint32_t The number of ticks corresponding to 'usecs'
+ */
+uint32_t os_cputime_usecs_to_ticks(uint32_t usecs);
+
+/**
+ * Convert the given number of ticks into microseconds.
+ *
+ * @param ticks The number of ticks to convert to microseconds.
+ *
+ * @return uint32_t The number of microseconds corresponding to 'ticks'
+ */
+uint32_t os_cputime_ticks_to_usecs(uint32_t ticks);
+#endif
+
+/**
+ * Wait until the number of ticks has elapsed. This is a blocking delay.
+ *
+ * @param ticks The number of ticks to wait.
+ */
+void os_cputime_delay_ticks(uint32_t ticks);
+
+/**
+ * Wait until 'usecs' microseconds has elapsed. This is a blocking delay.
+ *
+ * @param usecs The number of usecs to wait.
+ */
+void os_cputime_delay_usecs(uint32_t usecs);
+
+/**
+ * Initialize a CPU timer, using the given HAL timer.
+ *
+ * @param timer The timer to initialize. Cannot be NULL.
+ * @param fp    The timer callback function. Cannot be NULL.
+ * @param arg   Pointer to data object to pass to timer.
+ */
+void os_cputime_timer_init(struct hal_timer *timer, hal_timer_cb fp,
+                           void *arg);
+
+/**
+ * Start a cputimer that will expire at 'cputime'. If cputime has already
+ * passed, the timer callback will still be called (at interrupt context).
+ *
+ * NOTE: This must be called when the timer is stopped.
+ *
+ * @param timer     Pointer to timer to start. Cannot be NULL.
+ * @param cputime   The cputime at which the timer should expire.
+ *
+ * @return int 0 on success; EINVAL if timer already started or timer struct
+ *         invalid
+ *
+ */
+int os_cputime_timer_start(struct hal_timer *timer, uint32_t cputime);
+
+/**
+ * Sets a cpu timer that will expire 'usecs' microseconds from the current
+ * cputime.
+ *
+ * NOTE: This must be called when the timer is stopped.
+ *
+ * @param timer Pointer to timer. Cannot be NULL.
+ * @param usecs The number of usecs from now at which the timer will expire.
+ *
+ * @return int 0 on success; EINVAL if timer already started or timer struct
+ *         invalid
+ */
+int os_cputime_timer_relative(struct hal_timer *timer, uint32_t usecs);
+
+/**
+ * Stops a cputimer from running. The timer is removed from the timer queue
+ * and interrupts are disabled if no timers are left on the queue. Can be
+ * called even if timer is not running.
+ *
+ * @param timer Pointer to cputimer to stop. Cannot be NULL.
+ */
+void os_cputime_timer_stop(struct hal_timer *timer);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_OS_CPUTIME_ */
+
+/**
+ *   @} OSCPUTime
+ * @} OSKernel
+ */

+ 62 - 0
third_party/nimble-1.6.0/porting/nimble/include/os/os_error.h

@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_OS_ERROR_
+#define H_OS_ERROR_
+
+#include "os/os.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* OS error enumerations */
+enum os_error {
+    OS_OK = 0,
+    OS_ENOMEM = 1,
+    OS_EINVAL = 2,
+    OS_INVALID_PARM = 3,
+    OS_MEM_NOT_ALIGNED = 4,
+    OS_BAD_MUTEX = 5,
+    OS_TIMEOUT = 6,
+    OS_ERR_IN_ISR = 7,      /* Function cannot be called from ISR */
+    OS_ERR_PRIV = 8,        /* Privileged access error */
+    OS_NOT_STARTED = 9,     /* OS must be started to call this function, but isn't */
+    OS_ENOENT = 10,         /* No such thing */
+    OS_EBUSY = 11,          /* Resource busy */
+    OS_ERROR = 12,          /* Generic Error */
+};
+
+typedef enum os_error os_error_t;
+
+/**
+ * @brief Converts an OS error code (`OS_[...]`) to an equivalent system error
+ * code (`SYS_E[...]`).
+ *
+ * @param os_error              The OS error code to convert.
+ *
+ * @return                      The equivalent system error code.
+ */
+int os_error_to_sys(os_error_t os_error);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 677 - 0
third_party/nimble-1.6.0/porting/nimble/include/os/os_mbuf.h

@@ -0,0 +1,677 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+/**
+ * @addtogroup OSKernel
+ * @{
+ *   @defgroup OSMbuf Chained Memory Buffers
+ *   @{
+ */
+
+
+#ifndef _OS_MBUF_H
+#define _OS_MBUF_H
+
+#include "os/os.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A mbuf pool from which to allocate mbufs. This contains a pointer to the os
+ * mempool to allocate mbufs out of, the total number of elements in the pool,
+ * and the amount of "user" data in a non-packet header mbuf. The total pool
+ * size, in bytes, should be:
+ *  os_mbuf_count * (omp_databuf_len + sizeof(struct os_mbuf))
+ */
+struct os_mbuf_pool {
+    /**
+     * Total length of the databuf in each mbuf.  This is the size of the
+     * mempool block, minus the mbuf header
+     */
+    uint16_t omp_databuf_len;
+    /**
+     * The memory pool which to allocate mbufs out of
+     */
+    struct os_mempool *omp_pool;
+
+    STAILQ_ENTRY(os_mbuf_pool) omp_next;
+};
+
+
+/**
+ * A packet header structure that preceeds the mbuf packet headers.
+ */
+struct os_mbuf_pkthdr {
+    /**
+     * Overall length of the packet.
+     */
+    uint16_t omp_len;
+    /**
+     * Flags
+     */
+    uint16_t omp_flags;
+
+    STAILQ_ENTRY(os_mbuf_pkthdr) omp_next;
+};
+
+/**
+ * Chained memory buffer.
+ */
+struct os_mbuf {
+    /**
+     * Current pointer to data in the structure
+     */
+    uint8_t *om_data;
+    /**
+     * Flags associated with this buffer, see OS_MBUF_F_* defintions
+     */
+    uint8_t om_flags;
+    /**
+     * Length of packet header
+     */
+    uint8_t om_pkthdr_len;
+    /**
+     * Length of data in this buffer
+     */
+    uint16_t om_len;
+
+    /**
+     * The mbuf pool this mbuf was allocated out of
+     */
+    struct os_mbuf_pool *om_omp;
+
+    SLIST_ENTRY(os_mbuf) om_next;
+
+    /**
+     * Pointer to the beginning of the data, after this buffer
+     */
+    uint8_t om_databuf[0];
+};
+
+/**
+ * Structure representing a queue of mbufs.
+ */
+struct os_mqueue {
+    STAILQ_HEAD(, os_mbuf_pkthdr) mq_head;
+    /** Event to post when new buffers are available on the queue. */
+    struct ble_npl_event mq_ev;
+};
+
+/*
+ * Given a flag number, provide the mask for it
+ *
+ * @param __n The number of the flag in the mask
+ */
+#define OS_MBUF_F_MASK(__n) (1 << (__n))
+
+/*
+ * Checks whether a given mbuf is a packet header mbuf
+ *
+ * @param __om The mbuf to check
+ */
+#define OS_MBUF_IS_PKTHDR(__om) \
+    ((__om)->om_pkthdr_len >= sizeof (struct os_mbuf_pkthdr))
+
+/** Get a packet header pointer given an mbuf pointer */
+#define OS_MBUF_PKTHDR(__om) ((struct os_mbuf_pkthdr *)(uintptr_t)  \
+                              (void *)((uint8_t *)&(__om)->om_data  \
+                              + sizeof(struct os_mbuf)))
+
+/** Given a mbuf packet header pointer, return a pointer to the mbuf */
+#define OS_MBUF_PKTHDR_TO_MBUF(__hdr)   \
+    (struct os_mbuf *)(uintptr_t)((uint8_t *)(__hdr) - sizeof(struct os_mbuf))
+
+/**
+ * Gets the length of an entire mbuf chain.  The specified mbuf must have a
+ * packet header.
+ */
+#define OS_MBUF_PKTLEN(__om) (OS_MBUF_PKTHDR(__om)->omp_len)
+
+/**
+ * Access the data of a mbuf, and cast it to type
+ *
+ * @param __om The mbuf to access, and cast
+ * @param __type The type to cast it to
+ */
+#define OS_MBUF_DATA(__om, __type) \
+     (__type) ((__om)->om_data)
+
+/**
+ * Access the "user header" in the head of an mbuf chain.
+ *
+ * @param om                    Pointer to the head of an mbuf chain.
+ */
+#define OS_MBUF_USRHDR(om)                              \
+    (void *)((uint8_t *)om + sizeof (struct os_mbuf) +  \
+             sizeof (struct os_mbuf_pkthdr))
+
+/**
+ * Retrieves the length of the user header in an mbuf.
+ *
+ * @param om                    Pointer to the mbuf to query.
+ */
+#define OS_MBUF_USRHDR_LEN(om) \
+    ((om)->om_pkthdr_len - sizeof (struct os_mbuf_pkthdr))
+
+
+/** @cond INTERNAL_HIDDEN */
+
+/*
+ * Called by OS_MBUF_LEADINGSPACE() macro
+ */
+static inline uint16_t
+_os_mbuf_leadingspace(struct os_mbuf *om)
+{
+    uint16_t startoff;
+    uint16_t leadingspace;
+
+    startoff = 0;
+    if (OS_MBUF_IS_PKTHDR(om)) {
+        startoff = om->om_pkthdr_len;
+    }
+
+    leadingspace = (uint16_t) (OS_MBUF_DATA(om, uint8_t *) -
+                               ((uint8_t *) &om->om_databuf[0] + startoff));
+
+    return (leadingspace);
+}
+
+/** @endcond */
+
+/**
+ * Returns the leading space (space at the beginning) of the mbuf.
+ * Works on both packet header, and regular mbufs, as it accounts
+ * for the additional space allocated to the packet header.
+ *
+ * @param __omp Is the mbuf pool (which contains packet header length.)
+ * @param __om  Is the mbuf in that pool to get the leadingspace for
+ *
+ * @return Amount of leading space available in the mbuf
+ */
+#define OS_MBUF_LEADINGSPACE(__om) _os_mbuf_leadingspace(__om)
+
+
+/** @cond INTERNAL_HIDDEN */
+
+/* Called by OS_MBUF_TRAILINGSPACE() macro. */
+static inline uint16_t
+_os_mbuf_trailingspace(struct os_mbuf *om)
+{
+    struct os_mbuf_pool *omp;
+
+    omp = om->om_omp;
+
+    return (&om->om_databuf[0] + omp->omp_databuf_len) -
+           (om->om_data + om->om_len);
+}
+
+/** @endcond */
+
+/**
+ * Returns the trailing space (space at the end) of the mbuf.
+ * Works on both packet header and regular mbufs.
+ *
+ * @param __omp The mbuf pool for this mbuf
+ * @param __om  Is the mbuf in that pool to get trailing space for
+ *
+ * @return The amount of trailing space available in the mbuf
+ */
+#define OS_MBUF_TRAILINGSPACE(__om) _os_mbuf_trailingspace(__om)
+
+
+/**
+ * Initializes an mqueue.  An mqueue is a queue of mbufs that ties to a
+ * particular task's event queue.  Mqueues form a helper API around a common
+ * paradigm: wait on an event queue until at least one packet is available,
+ * then process a queue of packets.
+ *
+ * When mbufs are available on the queue, an event OS_EVENT_T_MQUEUE_DATA
+ * will be posted to the task's mbuf queue.
+ *
+ * @param mq                    The mqueue to initialize
+ * @param ev_cb                 The callback to associate with the mqeueue
+ *                                  event.  Typically, this callback pulls each
+ *                                  packet off the mqueue and processes them.
+ * @param arg                   The argument to associate with the mqueue event.
+ *
+ * @return                      0 on success, non-zero on failure.
+ */
+int os_mqueue_init(struct os_mqueue *mq, ble_npl_event_fn *ev_cb, void *arg);
+
+/**
+ * Remove and return a single mbuf from the mbuf queue.  Does not block.
+ *
+ * @param mq The mbuf queue to pull an element off of.
+ *
+ * @return The next mbuf in the queue, or NULL if queue has no mbufs.
+ */
+struct os_mbuf *os_mqueue_get(struct os_mqueue *);
+
+/**
+ * Adds a packet (i.e. packet header mbuf) to an mqueue. The event associated
+ * with the mqueue gets posted to the specified eventq.
+ *
+ * @param mq                    The mbuf queue to append the mbuf to.
+ * @param evq                   The event queue to post an event to.
+ * @param m                     The mbuf to append to the mbuf queue.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
+int os_mqueue_put(struct os_mqueue *, struct ble_npl_eventq *, struct os_mbuf *);
+
+/**
+ * MSYS is a system level mbuf registry.  Allows the system to share
+ * packet buffers amongst the various networking stacks that can be running
+ * simultaeneously.
+ *
+ * Mbuf pools are created in the system initialization code, and then when
+ * a mbuf is allocated out of msys, it will try and find the best fit based
+ * upon estimated mbuf size.
+ *
+ * os_msys_register() registers a mbuf pool with MSYS, and allows MSYS to
+ * allocate mbufs out of it.
+ *
+ * @param new_pool The pool to register with MSYS
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int os_msys_register(struct os_mbuf_pool *);
+
+/**
+ * Allocate a mbuf from msys.  Based upon the data size requested,
+ * os_msys_get() will choose the mbuf pool that has the best fit.
+ *
+ * @param dsize The estimated size of the data being stored in the mbuf
+ * @param leadingspace The amount of leadingspace to allocate in the mbuf
+ *
+ * @return A freshly allocated mbuf on success, NULL on failure.
+ */
+struct os_mbuf *os_msys_get(uint16_t dsize, uint16_t leadingspace);
+
+/**
+ * De-registers all mbuf pools from msys.
+ */
+void os_msys_reset(void);
+
+/**
+ * Allocate a packet header structure from the MSYS pool.  See
+ * os_msys_register() for a description of MSYS.
+ *
+ * @param dsize The estimated size of the data being stored in the mbuf
+ * @param user_hdr_len The length to allocate for the packet header structure
+ *
+ * @return A freshly allocated mbuf on success, NULL on failure.
+ */
+struct os_mbuf *os_msys_get_pkthdr(uint16_t dsize, uint16_t user_hdr_len);
+
+/**
+ * Count the number of blocks in all the mbuf pools that are allocated.
+ *
+ * @return total number of blocks allocated in Msys
+ */
+int os_msys_count(void);
+
+/**
+ * Return the number of free blocks in Msys
+ *
+ * @return Number of free blocks available in Msys
+ */
+int os_msys_num_free(void);
+
+/**
+ * Initialize a pool of mbufs.
+ *
+ * @param omp     The mbuf pool to initialize
+ * @param mp      The memory pool that will hold this mbuf pool
+ * @param buf_len The length of the buffer itself.
+ * @param nbufs   The number of buffers in the pool
+ *
+ * @return 0 on success, error code on failure.
+ */
+int os_mbuf_pool_init(struct os_mbuf_pool *, struct os_mempool *mp,
+                      uint16_t, uint16_t);
+
+/**
+ * Get an mbuf from the mbuf pool.  The mbuf is allocated, and initialized
+ * prior to being returned.
+ *
+ * @param omp The mbuf pool to return the packet from
+ * @param leadingspace The amount of leadingspace to put before the data
+ *     section by default.
+ *
+ * @return An initialized mbuf on success, and NULL on failure.
+ */
+struct os_mbuf *os_mbuf_get(struct os_mbuf_pool *omp, uint16_t);
+
+/**
+ * Allocate a new packet header mbuf out of the os_mbuf_pool.
+ *
+ * @param omp The mbuf pool to allocate out of
+ * @param user_pkthdr_len The packet header length to reserve for the caller.
+ *
+ * @return A freshly allocated mbuf on success, NULL on failure.
+ */
+struct os_mbuf *os_mbuf_get_pkthdr(struct os_mbuf_pool *omp,
+                                   uint8_t pkthdr_len);
+
+/**
+ * Duplicate a chain of mbufs.  Return the start of the duplicated chain.
+ *
+ * @param omp The mbuf pool to duplicate out of
+ * @param om  The mbuf chain to duplicate
+ *
+ * @return A pointer to the new chain of mbufs
+ */
+struct os_mbuf *os_mbuf_dup(struct os_mbuf *m);
+
+/**
+ * Locates the specified absolute offset within an mbuf chain.  The offset
+ * can be one past than the total length of the chain, but no greater.
+ *
+ * @param om                    The start of the mbuf chain to seek within.
+ * @param off                   The absolute address to find.
+ * @param out_off               On success, this points to the relative offset
+ *                                  within the returned mbuf.
+ *
+ * @return                      The mbuf containing the specified offset on
+ *                                  success.
+ *                              NULL if the specified offset is out of bounds.
+ */
+struct os_mbuf *os_mbuf_off(const struct os_mbuf *om, int off,
+                            uint16_t *out_off);
+
+
+/*
+ * Copy data from an mbuf chain starting "off" bytes from the beginning,
+ * continuing for "len" bytes, into the indicated buffer.
+ *
+ * @param m The mbuf chain to copy from
+ * @param off The offset into the mbuf chain to begin copying from
+ * @param len The length of the data to copy
+ * @param dst The destination buffer to copy into
+ *
+ * @return                      0 on success;
+ *                              -1 if the mbuf does not contain enough data.
+ */
+int os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst);
+
+/**
+ * @brief Calculates the length of an mbuf chain.
+ *
+ * Calculates the length of an mbuf chain.  If the mbuf contains a packet
+ * header, you should use `OS_MBUF_PKTLEN()` as a more efficient alternative to
+ * this function.
+ *
+ * @param om                    The mbuf to measure.
+ *
+ * @return                      The length, in bytes, of the provided mbuf
+ *                                  chain.
+ */
+uint16_t os_mbuf_len(const struct os_mbuf *om);
+
+/**
+ * Append data onto a mbuf
+ *
+ * @param om   The mbuf to append the data onto
+ * @param data The data to append onto the mbuf
+ * @param len  The length of the data to append
+ *
+ * @return 0 on success, and an error code on failure
+ */
+int os_mbuf_append(struct os_mbuf *m, const void *, uint16_t);
+
+/**
+ * Reads data from one mbuf and appends it to another.  On error, the specified
+ * data range may be partially appended.  Neither mbuf is required to contain
+ * an mbuf packet header.
+ *
+ * @param dst                   The mbuf to append to.
+ * @param src                   The mbuf to copy data from.
+ * @param src_off               The absolute offset within the source mbuf
+ *                                  chain to read from.
+ * @param len                   The number of bytes to append.
+ *
+ * @return                      0 on success;
+ *                              OS_EINVAL if the specified range extends beyond
+ *                                  the end of the source mbuf chain.
+ */
+int os_mbuf_appendfrom(struct os_mbuf *dst, const struct os_mbuf *src,
+                       uint16_t src_off, uint16_t len);
+
+/**
+ * Release a mbuf back to the pool
+ *
+ * @param omp The Mbuf pool to release back to
+ * @param om  The Mbuf to release back to the pool
+ *
+ * @return 0 on success, -1 on failure
+ */
+int os_mbuf_free(struct os_mbuf *mb);
+
+/**
+ * Free a chain of mbufs
+ *
+ * @param omp The mbuf pool to free the chain of mbufs into
+ * @param om  The starting mbuf of the chain to free back into the pool
+ *
+ * @return 0 on success, -1 on failure
+ */
+int os_mbuf_free_chain(struct os_mbuf *om);
+
+/**
+ * Adjust the length of a mbuf, trimming either from the head or the tail
+ * of the mbuf.
+ *
+ * @param mp The mbuf chain to adjust
+ * @param req_len The length to trim from the mbuf.  If positive, trims
+ *                from the head of the mbuf, if negative, trims from the
+ *                tail of the mbuf.
+ */
+void os_mbuf_adj(struct os_mbuf *mp, int req_len);
+
+
+/**
+ * Performs a memory compare of the specified region of an mbuf chain against a
+ * flat buffer.
+ *
+ * @param om                    The start of the mbuf chain to compare.
+ * @param off                   The offset within the mbuf chain to start the
+ *                                  comparison.
+ * @param data                  The flat buffer to compare.
+ * @param len                   The length of the flat buffer.
+ *
+ * @return                      0 if both memory regions are identical;
+ *                              A memcmp return code if there is a mismatch;
+ *                              INT_MAX if the mbuf is too short.
+ */
+int os_mbuf_cmpf(const struct os_mbuf *om, int off, const void *data, int len);
+
+/**
+ * Compares the contents of two mbuf chains.  The ranges of the two chains to
+ * be compared are specified via the two offset parameters and the len
+ * parameter.  Neither mbuf chain is required to contain a packet header.
+ *
+ * @param om1                   The first mbuf chain to compare.
+ * @param offset1               The absolute offset within om1 at which to
+ *                                  start the comparison.
+ * @param om2                   The second mbuf chain to compare.
+ * @param offset2               The absolute offset within om2 at which to
+ *                                  start the comparison.
+ * @param len                   The number of bytes to compare.
+ *
+ * @return                      0 if both mbuf segments are identical;
+ *                              A memcmp() return code if the segment contents
+ *                                  differ;
+ *                              INT_MAX if a specified range extends beyond the
+ *                                  end of its corresponding mbuf chain.
+ */
+int os_mbuf_cmpm(const struct os_mbuf *om1, uint16_t offset1,
+                 const struct os_mbuf *om2, uint16_t offset2,
+                 uint16_t len);
+
+/**
+ * Increases the length of an mbuf chain by adding data to the front.  If there
+ * is insufficient room in the leading mbuf, additional mbufs are allocated and
+ * prepended as necessary.  If this function fails to allocate an mbuf, the
+ * entire chain is freed.
+ *
+ * The specified mbuf chain does not need to contain a packet header.
+ *
+ * @param omp                   The mbuf pool to allocate from.
+ * @param om                    The head of the mbuf chain.
+ * @param len                   The number of bytes to prepend.
+ *
+ * @return                      The new head of the chain on success;
+ *                              NULL on failure.
+ */
+struct os_mbuf *os_mbuf_prepend(struct os_mbuf *om, int len);
+
+/**
+ * Prepends a chunk of empty data to the specified mbuf chain and ensures the
+ * chunk is contiguous.  If either operation fails, the specified mbuf chain is
+ * freed and NULL is returned.
+ *
+ * @param om                    The mbuf chain to prepend to.
+ * @param len                   The number of bytes to prepend and pullup.
+ *
+ * @return                      The modified mbuf on success;
+ *                              NULL on failure (and the mbuf chain is freed).
+ */
+struct os_mbuf *os_mbuf_prepend_pullup(struct os_mbuf *om, uint16_t len);
+
+/**
+ * Copies the contents of a flat buffer into an mbuf chain, starting at the
+ * specified destination offset.  If the mbuf is too small for the source data,
+ * it is extended as necessary.  If the destination mbuf contains a packet
+ * header, the header length is updated.
+ *
+ * @param omp                   The mbuf pool to allocate from.
+ * @param om                    The mbuf chain to copy into.
+ * @param off                   The offset within the chain to copy to.
+ * @param src                   The source buffer to copy from.
+ * @param len                   The number of bytes to copy.
+ *
+ * @return                      0 on success; nonzero on failure.
+ */
+int os_mbuf_copyinto(struct os_mbuf *om, int off, const void *src, int len);
+
+/**
+ * Attaches a second mbuf chain onto the end of the first.  If the first chain
+ * contains a packet header, the header's length is updated.  If the second
+ * chain has a packet header, its header is cleared.
+ *
+ * @param first                 The mbuf chain being attached to.
+ * @param second                The mbuf chain that gets attached.
+ */
+void os_mbuf_concat(struct os_mbuf *first, struct os_mbuf *second);
+
+
+/**
+ * Increases the length of an mbuf chain by the specified amount.  If there is
+ * not sufficient room in the last buffer, a new buffer is allocated and
+ * appended to the chain.  It is an error to request more data than can fit in
+ * a single buffer.
+ *
+ * @param omp
+ * @param om                    The head of the chain to extend.
+ * @param len                   The number of bytes to extend by.
+ *
+ * @return                      A pointer to the new data on success;
+ *                              NULL on failure.
+ */
+void *os_mbuf_extend(struct os_mbuf *om, uint16_t len);
+
+/**
+ * Rearrange a mbuf chain so that len bytes are contiguous,
+ * and in the data area of an mbuf (so that OS_MBUF_DATA() will
+ * work on a structure of size len.)  Returns the resulting
+ * mbuf chain on success, free's it and returns NULL on failure.
+ *
+ * If there is room, it will add up to "max_protohdr - len"
+ * extra bytes to the contiguous region, in an attempt to avoid being
+ * called next time.
+ *
+ * @param omp The mbuf pool to take the mbufs out of
+ * @param om The mbuf chain to make contiguous
+ * @param len The number of bytes in the chain to make contiguous
+ *
+ * @return The contiguous mbuf chain on success, NULL on failure.
+ */
+struct os_mbuf *os_mbuf_pullup(struct os_mbuf *om, uint16_t len);
+
+
+/**
+ * Removes and frees empty mbufs from the front of a chain.  If the chain
+ * contains a packet header, it is preserved.
+ *
+ * @param om                    The mbuf chain to trim.
+ *
+ * @return                      The head of the trimmed mbuf chain.
+ */
+struct os_mbuf *os_mbuf_trim_front(struct os_mbuf *om);
+
+/**
+ * Increases the length of an mbuf chain by inserting a gap at the specified
+ * offset.  The contents of the gap are indeterminate.  If the mbuf chain
+ * contains a packet header, its total length is increased accordingly.
+ *
+ * This function never frees the provided mbuf chain.
+ *
+ * @param om                    The mbuf chain to widen.
+ * @param off                   The offset at which to insert the gap.
+ * @param len                   The size of the gap to insert.
+ *
+ * @return                      0 on success; SYS_[...] error code on failure.
+ */
+int os_mbuf_widen(struct os_mbuf *om, uint16_t off, uint16_t len);
+
+
+/**
+ * Creates a single chained mbuf from m1 and m2 utilizing all
+ * the available buffer space in all mbufs in the resulting
+ * chain. In other words, ensures there is no leading space in
+ * any mbuf in the resulting chain and trailing space only in
+ * the last mbuf in the chain. Mbufs from either chain may be
+ * freed if not needed. No mbufs are allocated. Note that mbufs
+ * from m2 are added to the end of m1. If m1 has a packet
+ * header, it is retained and length updated. If m2 has a packet
+ * header it is discarded. If m1 is NULL, NULL is returned and
+ * m2 is left untouched.
+ *
+ * @param m1 Pointer to first mbuf chain to pack
+ * @param m2 Pointer to second mbuf chain to pack
+ *
+ * @return struct os_mbuf* Pointer to resulting mbuf chain
+ */
+struct os_mbuf *os_mbuf_pack_chains(struct os_mbuf *m1, struct os_mbuf *m2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OS_MBUF_H */
+
+
+/**
+ *   @} OSMbuf
+ * @} OSKernel
+ */

+ 287 - 0
third_party/nimble-1.6.0/porting/nimble/include/os/os_mempool.h

@@ -0,0 +1,287 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @addtogroup OSKernel
+ * @{
+ *   @defgroup OSMempool Memory Pools
+ *   @{
+ */
+
+
+#ifndef _OS_MEMPOOL_H_
+#define _OS_MEMPOOL_H_
+
+#include <stdbool.h>
+#include "os/os.h"
+#include "os/queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A memory block structure. This simply contains a pointer to the free list
+ * chain and is only used when the block is on the free list. When the block
+ * has been removed from the free list the entire memory block is usable by the
+ * caller.
+ */
+struct os_memblock {
+    SLIST_ENTRY(os_memblock) mb_next;
+};
+
+/* XXX: Change this structure so that we keep the first address in the pool? */
+/* XXX: add memory debug structure and associated code */
+/* XXX: Change how I coded the SLIST_HEAD here. It should be named:
+   SLIST_HEAD(,os_memblock) mp_head; */
+
+/**
+ * Memory pool
+ */
+struct os_mempool {
+    /** Size of the memory blocks, in bytes. */
+    uint32_t mp_block_size;
+    /** The number of memory blocks. */
+    uint16_t mp_num_blocks;
+    /** The number of free blocks left */
+    uint16_t mp_num_free;
+    /** The lowest number of free blocks seen */
+    uint16_t mp_min_free;
+    /** Bitmap of OS_MEMPOOL_F_[...] values. */
+    uint8_t mp_flags;
+    /** Address of memory buffer used by pool */
+    uint32_t mp_membuf_addr;
+    STAILQ_ENTRY(os_mempool) mp_list;
+    SLIST_HEAD(,os_memblock);
+    /** Name for memory block */
+    char *name;
+};
+
+/**
+ * Indicates an extended mempool.  Address can be safely cast to
+ * (struct os_mempool_ext *).
+ */
+#define OS_MEMPOOL_F_EXT        0x01
+
+struct os_mempool_ext;
+
+/**
+ * Block put callback function.  If configured, this callback gets executed
+ * whenever a block is freed to the corresponding extended mempool.  Note: The
+ * os_memblock_put() function calls this callback instead of freeing the block
+ * itself.  Therefore, it is the callback's responsibility to free the block
+ * via a call to os_memblock_put_from_cb().
+ *
+ * @param ome                   The extended mempool that a block is being
+ *                                  freed back to.
+ * @param data                  The block being freed.
+ * @param arg                   Optional argument configured along with the
+ *                                  callback.
+ *
+ * @return                      Indicates whether the block was successfully
+ *                                  freed.  A non-zero value should only be
+ *                                  returned if the block was not successfully
+ *                                  released back to its pool.
+ */
+typedef os_error_t os_mempool_put_fn(struct os_mempool_ext *ome, void *data,
+                                     void *arg);
+
+struct os_mempool_ext {
+    struct os_mempool mpe_mp;
+
+    /* Callback that is executed immediately when a block is freed. */
+    os_mempool_put_fn *mpe_put_cb;
+    void *mpe_put_arg;
+};
+
+#define OS_MEMPOOL_INFO_NAME_LEN (32)
+
+/**
+ * Information describing a memory pool, used to return OS information
+ * to the management layer.
+ */
+struct os_mempool_info {
+    /** Size of the memory blocks in the pool */
+    int omi_block_size;
+    /** Number of memory blocks in the pool */
+    int omi_num_blocks;
+    /** Number of free memory blocks */
+    int omi_num_free;
+    /** Minimum number of free memory blocks ever */
+    int omi_min_free;
+    /** Name of the memory pool */
+    char omi_name[OS_MEMPOOL_INFO_NAME_LEN];
+};
+
+/**
+ * Get information about the next system memory pool.
+ *
+ * @param mempool The current memory pool, or NULL if starting iteration.
+ * @param info    A pointer to the structure to return memory pool information
+ *                into.
+ *
+ * @return The next memory pool in the list to get information about, or NULL
+ *         when at the last memory pool.
+ */
+struct os_mempool *os_mempool_info_get_next(struct os_mempool *,
+                                            struct os_mempool_info *);
+
+/*
+ * To calculate size of the memory buffer needed for the pool. NOTE: This size
+ * is NOT in bytes! The size is the number of os_membuf_t elements required for
+ * the memory pool.
+ */
+#if MYNEWT_VAL(OS_MEMPOOL_GUARD)
+/*
+ * Leave extra 4 bytes of guard area at the end.
+ */
+#define OS_MEMPOOL_BLOCK_SZ(sz) ((sz) + sizeof(os_membuf_t))
+#else
+#define OS_MEMPOOL_BLOCK_SZ(sz) (sz)
+#endif
+#if (OS_ALIGNMENT == 4)
+typedef uint32_t os_membuf_t;
+#elif (OS_ALIGNMENT == 8)
+typedef uint64_t os_membuf_t;
+#elif (OS_ALIGNMENT == 16)
+typedef __uint128_t os_membuf_t;
+#else
+#error "Unhandled `OS_ALIGNMENT` for `os_membuf_t`"
+#endif /* OS_ALIGNMENT == * */
+#define OS_MEMPOOL_SIZE(n,blksize)      ((((blksize) + ((OS_ALIGNMENT)-1)) / (OS_ALIGNMENT)) * (n))
+
+/** Calculates the number of bytes required to initialize a memory pool. */
+#define OS_MEMPOOL_BYTES(n,blksize)     \
+    (sizeof (os_membuf_t) * OS_MEMPOOL_SIZE((n), (blksize)))
+
+/**
+ * Initialize a memory pool.
+ *
+ * @param mp            Pointer to a pointer to a mempool
+ * @param blocks        The number of blocks in the pool
+ * @param blocks_size   The size of the block, in bytes.
+ * @param membuf        Pointer to memory to contain blocks.
+ * @param name          Name of the pool.
+ *
+ * @return os_error_t
+ */
+os_error_t os_mempool_init(struct os_mempool *mp, uint16_t blocks,
+                           uint32_t block_size, void *membuf, char *name);
+
+/**
+ * Initializes an extended memory pool.  Extended attributes (e.g., callbacks)
+ * are not specified when this function is called; they are assigned manually
+ * after initialization.
+ *
+ * @param mpe           The extended memory pool to initialize.
+ * @param blocks        The number of blocks in the pool.
+ * @param block_size    The size of each block, in bytes.
+ * @param membuf        Pointer to memory to contain blocks.
+ * @param name          Name of the pool.
+ *
+ * @return os_error_t
+ */
+os_error_t os_mempool_ext_init(struct os_mempool_ext *mpe, uint16_t blocks,
+                               uint32_t block_size, void *membuf, char *name);
+
+/**
+ * Removes the specified mempool from the list of initialized mempools.
+ *
+ * @param mp                    The mempool to unregister.
+ *
+ * @return                      0 on success;
+ *                              OS_INVALID_PARM if the mempool is not
+ *                                  registered.
+ */
+os_error_t os_mempool_unregister(struct os_mempool *mp);
+
+/**
+ * Clears a memory pool.
+ *
+ * @param mp            The mempool to clear.
+ *
+ * @return os_error_t
+ */
+os_error_t os_mempool_clear(struct os_mempool *mp);
+
+/**
+ * Performs an integrity check of the specified mempool.  This function
+ * attempts to detect memory corruption in the specified memory pool.
+ *
+ * @param mp                    The mempool to check.
+ *
+ * @return                      true if the memory pool passes the integrity
+ *                                  check;
+ *                              false if the memory pool is corrupt.
+ */
+bool os_mempool_is_sane(const struct os_mempool *mp);
+
+/**
+ * Checks if a memory block was allocated from the specified mempool.
+ *
+ * @param mp                    The mempool to check as parent.
+ * @param block_addr            The memory block to check as child.
+ *
+ * @return                      0 if the block does not belong to the mempool;
+ *                              1 if the block does belong to the mempool.
+ */
+int os_memblock_from(const struct os_mempool *mp, const void *block_addr);
+
+/**
+ * Get a memory block from a memory pool
+ *
+ * @param mp Pointer to the memory pool
+ *
+ * @return void* Pointer to block if available; NULL otherwise
+ */
+void *os_memblock_get(struct os_mempool *mp);
+
+/**
+ * Puts the memory block back into the pool, ignoring the put callback, if any.
+ * This function should only be called from a put callback to free a block
+ * without causing infinite recursion.
+ *
+ * @param mp Pointer to memory pool
+ * @param block_addr Pointer to memory block
+ *
+ * @return os_error_t
+ */
+os_error_t os_memblock_put_from_cb(struct os_mempool *mp, void *block_addr);
+
+/**
+ * Puts the memory block back into the pool
+ *
+ * @param mp Pointer to memory pool
+ * @param block_addr Pointer to memory block
+ *
+ * @return os_error_t
+ */
+os_error_t os_memblock_put(struct os_mempool *mp, void *block_addr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _OS_MEMPOOL_H_ */
+
+
+/**
+ *   @} OSMempool
+ * @} OSKernel
+ */

+ 277 - 0
third_party/nimble-1.6.0/porting/nimble/include/os/os_trace_api.h

@@ -0,0 +1,277 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef OS_TRACE_API_H
+#define OS_TRACE_API_H
+
+#ifdef __ASSEMBLER__
+
+#define os_trace_isr_enter              SEGGER_SYSVIEW_RecordEnterISR
+#define os_trace_isr_exit               SEGGER_SYSVIEW_RecordExitISR
+#define os_trace_task_start_exec        SEGGER_SYSVIEW_OnTaskStartExec
+
+#else
+
+#include <stdio.h>
+#include <string.h>
+#include "syscfg/syscfg.h"
+#if MYNEWT_VAL(OS_SYSVIEW)
+#include "sysview/vendor/SEGGER_SYSVIEW.h"
+#endif
+#include "os/os.h"
+
+#define OS_TRACE_ID_EVENTQ_PUT                  (40)
+#define OS_TRACE_ID_EVENTQ_GET_NO_WAIT          (41)
+#define OS_TRACE_ID_EVENTQ_GET                  (42)
+#define OS_TRACE_ID_EVENTQ_REMOVE               (43)
+#define OS_TRACE_ID_EVENTQ_POLL_0TIMO           (44)
+#define OS_TRACE_ID_EVENTQ_POLL                 (45)
+#define OS_TRACE_ID_MUTEX_INIT                  (50)
+#define OS_TRACE_ID_MUTEX_RELEASE               (51)
+#define OS_TRACE_ID_MUTEX_PEND                  (52)
+#define OS_TRACE_ID_SEM_INIT                    (60)
+#define OS_TRACE_ID_SEM_RELEASE                 (61)
+#define OS_TRACE_ID_SEM_PEND                    (62)
+#define OS_TRACE_ID_CALLOUT_INIT                (70)
+#define OS_TRACE_ID_CALLOUT_STOP                (71)
+#define OS_TRACE_ID_CALLOUT_RESET               (72)
+#define OS_TRACE_ID_CALLOUT_TICK                (73)
+#define OS_TRACE_ID_MEMBLOCK_GET                (80)
+#define OS_TRACE_ID_MEMBLOCK_PUT_FROM_CB        (81)
+#define OS_TRACE_ID_MEMBLOCK_PUT                (82)
+#define OS_TRACE_ID_MBUF_GET                    (90)
+#define OS_TRACE_ID_MBUF_GET_PKTHDR             (91)
+#define OS_TRACE_ID_MBUF_FREE                   (92)
+#define OS_TRACE_ID_MBUF_FREE_CHAIN             (93)
+
+#if MYNEWT_VAL(OS_SYSVIEW)
+
+typedef struct SEGGER_SYSVIEW_MODULE_STRUCT os_trace_module_t;
+
+static inline uint32_t
+os_trace_module_register(os_trace_module_t *m, const char *name,
+                         uint32_t num_events, void (* send_desc_func)(void))
+{
+    char *desc = "M=???";
+
+    asprintf(&desc, "M=%s", name);
+
+    memset(m, 0, sizeof(*m));
+    m->sModule = desc;
+    m->NumEvents = num_events;
+    m->pfSendModuleDesc = send_desc_func;
+
+    SEGGER_SYSVIEW_RegisterModule(m);
+
+    return m->EventOffset;
+}
+
+static inline void
+os_trace_module_desc(const os_trace_module_t *m, const char *desc)
+{
+    SEGGER_SYSVIEW_RecordModuleDescription(m, desc);
+}
+
+static inline void
+os_trace_isr_enter(void)
+{
+    SEGGER_SYSVIEW_RecordEnterISR();
+}
+
+static inline void
+os_trace_isr_exit(void)
+{
+    SEGGER_SYSVIEW_RecordExitISR();
+}
+
+static inline void
+os_trace_task_info(const struct ble_npl_task *t)
+{
+    SEGGER_SYSVIEW_TASKINFO ti;
+
+    ti.TaskID = (uint32_t)t;
+    ti.sName = t->t_name;
+    ti.Prio = t->t_prio;
+    ti.StackSize = t->t_stacksize * sizeof(os_stack_t);
+    ti.StackBase = (uint32_t)&t->t_stackbottom + ti.StackSize;
+
+    SEGGER_SYSVIEW_SendTaskInfo(&ti);
+}
+
+static inline void
+os_trace_task_create(const struct ble_npl_task *t)
+{
+    SEGGER_SYSVIEW_OnTaskCreate((uint32_t)t);
+}
+
+static inline void
+os_trace_task_start_exec(const struct ble_npl_task *t)
+{
+    SEGGER_SYSVIEW_OnTaskStartExec((uint32_t)t);
+}
+
+static inline void
+os_trace_task_stop_exec(void)
+{
+    SEGGER_SYSVIEW_OnTaskStopExec();
+}
+
+static inline void
+os_trace_task_start_ready(const struct ble_npl_task *t)
+{
+    SEGGER_SYSVIEW_OnTaskStartReady((uint32_t)t);
+}
+
+static inline void
+os_trace_task_stop_ready(const struct ble_npl_task *t, unsigned reason)
+{
+    SEGGER_SYSVIEW_OnTaskStopReady((uint32_t)t, reason);
+}
+
+static inline void
+os_trace_idle(void)
+{
+    SEGGER_SYSVIEW_OnIdle();
+}
+
+static inline void
+os_trace_user_start(unsigned id)
+{
+    SEGGER_SYSVIEW_OnUserStart(id);
+}
+
+static inline void
+os_trace_user_stop(unsigned id)
+{
+    SEGGER_SYSVIEW_OnUserStop(id);
+}
+
+#endif /* MYNEWT_VAL(OS_SYSVIEW) */
+
+#if MYNEWT_VAL(OS_SYSVIEW) && !defined(OS_TRACE_DISABLE_FILE_API)
+
+static inline void
+os_trace_api_void(unsigned id)
+{
+    SEGGER_SYSVIEW_RecordVoid(id);
+}
+
+static inline void
+os_trace_api_u32(unsigned id, uint32_t p0)
+{
+    SEGGER_SYSVIEW_RecordU32(id, p0);
+}
+
+static inline void
+os_trace_api_u32x2(unsigned id, uint32_t p0, uint32_t p1)
+{
+    SEGGER_SYSVIEW_RecordU32x2(id, p0, p1);
+}
+
+static inline void
+os_trace_api_u32x3(unsigned id, uint32_t p0, uint32_t p1, uint32_t p2)
+{
+    SEGGER_SYSVIEW_RecordU32x3(id, p0, p1, p2);
+}
+
+static inline void
+os_trace_api_ret(unsigned id)
+{
+    SEGGER_SYSVIEW_RecordEndCall(id);
+}
+
+static inline void
+os_trace_api_ret_u32(unsigned id, uint32_t ret)
+{
+    SEGGER_SYSVIEW_RecordEndCallU32(id, ret);
+}
+
+#endif /* MYNEWT_VAL(OS_SYSVIEW) && !defined(OS_TRACE_DISABLE_FILE_API) */
+
+#if !MYNEWT_VAL(OS_SYSVIEW)
+
+static inline void
+os_trace_isr_enter(void)
+{
+}
+
+static inline void
+os_trace_isr_exit(void)
+{
+}
+
+static inline void
+os_trace_task_stop_exec(void)
+{
+}
+
+static inline void
+os_trace_idle(void)
+{
+}
+
+static inline void
+os_trace_user_start(unsigned id)
+{
+}
+
+static inline void
+os_trace_user_stop(unsigned id)
+{
+}
+
+#endif /* !MYNEWT_VAL(OS_SYSVIEW) */
+
+#if !MYNEWT_VAL(OS_SYSVIEW) || defined(OS_TRACE_DISABLE_FILE_API)
+
+static inline void
+os_trace_api_void(unsigned id)
+{
+}
+
+static inline void
+os_trace_api_u32(unsigned id, uint32_t p0)
+{
+}
+
+static inline void
+os_trace_api_u32x2(unsigned id, uint32_t p0, uint32_t p1)
+{
+}
+
+static inline void
+os_trace_api_u32x3(unsigned id, uint32_t p0, uint32_t p1, uint32_t p2)
+{
+}
+
+static inline void
+os_trace_api_ret(unsigned id)
+{
+}
+
+static inline void
+os_trace_api_ret_u32(unsigned id, uint32_t return_value)
+{
+}
+
+#endif /* !MYNEWT_VAL(OS_SYSVIEW) || defined(OS_TRACE_DISABLE_FILE_API) */
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* OS_TRACE_API_H */

+ 522 - 0
third_party/nimble-1.6.0/porting/nimble/include/os/queue.h

@@ -0,0 +1,522 @@
+/*
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)queue.h	8.5 (Berkeley) 8/20/94
+ * $FreeBSD: src/sys/sys/queue.h,v 1.32.2.7 2002/04/17 14:21:02 des Exp $
+ */
+
+#ifndef _QUEUE_H_
+#define	_QUEUE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This file defines five types of data structures: singly-linked lists,
+ * singly-linked tail queues, lists, tail queues, and circular queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction.  Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A singly-linked tail queue is headed by a pair of pointers, one to the
+ * head of the list and the other to the tail of the list. The elements are
+ * singly linked for minimum space and pointer manipulation overhead at the
+ * expense of O(n) removal for arbitrary elements. New elements can be added
+ * to the list after an existing element, at the head of the list, or at the
+ * end of the list. Elements being removed from the head of the tail queue
+ * should use the explicit macro for this purpose for optimum efficiency.
+ * A singly-linked tail queue may only be traversed in the forward direction.
+ * Singly-linked tail queues are ideal for applications with large datasets
+ * and few or no removals or for implementing a FIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * A circle queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the list.
+ * A circle queue may be traversed in either direction, but has a more
+ * complex end of list detection.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ *
+ *
+ *                      SLIST   LIST    STAILQ  TAILQ   CIRCLEQ
+ * _HEAD                +       +       +       +       +
+ * _HEAD_INITIALIZER    +       +       +       +       +
+ * _ENTRY               +       +       +       +       +
+ * _INIT                +       +       +       +       +
+ * _EMPTY               +       +       +       +       +
+ * _FIRST               +       +       +       +       +
+ * _NEXT                +       +       +       +       +
+ * _PREV                -       -       -       +       +
+ * _LAST                -       -       +       +       +
+ * _FOREACH             +       +       +       +       +
+ * _FOREACH_REVERSE     -       -       -       +       +
+ * _INSERT_HEAD         +       +       +       +       +
+ * _INSERT_BEFORE       -       +       -       +       +
+ * _INSERT_AFTER        +       +       +       +       +
+ * _INSERT_TAIL         -       -       +       +       +
+ * _REMOVE_HEAD         +       -       +       -       -
+ * _REMOVE              +       +       +       +       +
+ *
+ */
+
+/*
+ * Singly-linked List declarations.
+ */
+#define	SLIST_HEAD(name, type)                          \
+struct name {                                           \
+    struct type *slh_first;	/* first element */         \
+}
+
+#define	SLIST_HEAD_INITIALIZER(head)                    \
+    { NULL }
+
+#define	SLIST_ENTRY(type)                               \
+struct {                                                \
+    struct type *sle_next;  /* next element */          \
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#define SLIST_EMPTY(head)   ((head)->slh_first == NULL)
+
+#define SLIST_FIRST(head)   ((head)->slh_first)
+
+#define SLIST_FOREACH(var, head, field)                 \
+    for ((var) = SLIST_FIRST((head));                   \
+        (var);                                          \
+        (var) = SLIST_NEXT((var), field))
+
+#define SLIST_INIT(head) do {                           \
+        SLIST_FIRST((head)) = NULL;                     \
+} while (0)
+
+#define SLIST_INSERT_AFTER(slistelm, elm, field) do {           \
+    SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);   \
+    SLIST_NEXT((slistelm), field) = (elm);                      \
+} while (0)
+
+#define SLIST_INSERT_HEAD(head, elm, field) do {            \
+    SLIST_NEXT((elm), field) = SLIST_FIRST((head));         \
+    SLIST_FIRST((head)) = (elm);                            \
+} while (0)
+
+#define SLIST_NEXT(elm, field)	((elm)->field.sle_next)
+
+#define SLIST_REMOVE(head, elm, type, field) do {           \
+    if (SLIST_FIRST((head)) == (elm)) {                     \
+        SLIST_REMOVE_HEAD((head), field);                   \
+    }                                                       \
+    else {                                                  \
+        struct type *curelm = SLIST_FIRST((head));          \
+        while (SLIST_NEXT(curelm, field) != (elm))          \
+            curelm = SLIST_NEXT(curelm, field);             \
+        SLIST_NEXT(curelm, field) =                         \
+            SLIST_NEXT(SLIST_NEXT(curelm, field), field);   \
+    }                                                       \
+} while (0)
+
+#define SLIST_REMOVE_HEAD(head, field) do {                         \
+    SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);   \
+} while (0)
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define	STAILQ_HEAD(name, type)						\
+struct name {								\
+	struct type *stqh_first;/* first element */			\
+	struct type **stqh_last;/* addr of last next element */		\
+}
+
+#define	STAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).stqh_first }
+
+#define	STAILQ_ENTRY(type)						\
+struct {								\
+	struct type *stqe_next;	/* next element */			\
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
+
+#define	STAILQ_FIRST(head)	((head)->stqh_first)
+
+#define	STAILQ_FOREACH(var, head, field)				\
+	for((var) = STAILQ_FIRST((head));				\
+	   (var);							\
+	   (var) = STAILQ_NEXT((var), field))
+
+#define	STAILQ_INIT(head) do {						\
+	STAILQ_FIRST((head)) = NULL;					\
+	(head)->stqh_last = &STAILQ_FIRST((head));			\
+} while (0)
+
+#define	STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
+	if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+	STAILQ_NEXT((tqelm), field) = (elm);				\
+} while (0)
+
+#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
+	if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)	\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+	STAILQ_FIRST((head)) = (elm);					\
+} while (0)
+
+#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
+	STAILQ_NEXT((elm), field) = NULL;				\
+	*(head)->stqh_last = (elm);					\
+	(head)->stqh_last = &STAILQ_NEXT((elm), field);			\
+} while (0)
+
+#define	STAILQ_LAST(head, type, field)					\
+	(STAILQ_EMPTY(head) ?						\
+		NULL :							\
+	        ((struct type *)					\
+		((char *)((head)->stqh_last) - offsetof(struct type, field))))
+
+#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
+
+#define	STAILQ_REMOVE(head, elm, type, field) do {			\
+	if (STAILQ_FIRST((head)) == (elm)) {				\
+		STAILQ_REMOVE_HEAD(head, field);			\
+	}								\
+	else {								\
+		struct type *curelm = STAILQ_FIRST((head));		\
+		while (STAILQ_NEXT(curelm, field) != (elm))		\
+			curelm = STAILQ_NEXT(curelm, field);		\
+		if ((STAILQ_NEXT(curelm, field) =			\
+		     STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
+			(head)->stqh_last = &STAILQ_NEXT((curelm), field);\
+	}								\
+} while (0)
+
+#define	STAILQ_REMOVE_HEAD(head, field) do {				\
+	if ((STAILQ_FIRST((head)) =					\
+	     STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)		\
+		(head)->stqh_last = &STAILQ_FIRST((head));		\
+} while (0)
+
+#define	STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do {			\
+	if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL)	\
+		(head)->stqh_last = &STAILQ_FIRST((head));		\
+} while (0)
+
+#define STAILQ_REMOVE_AFTER(head, elm, field) do {			\
+	if ((STAILQ_NEXT(elm, field) =					\
+	     STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)	\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+} while (0)
+
+/*
+ * List declarations.
+ */
+#define	LIST_HEAD(name, type)						\
+struct name {								\
+	struct type *lh_first;	/* first element */			\
+}
+
+#define	LIST_HEAD_INITIALIZER(head)					\
+	{ NULL }
+
+#define	LIST_ENTRY(type)						\
+struct {								\
+	struct type *le_next;	/* next element */			\
+	struct type **le_prev;	/* address of previous next element */	\
+}
+
+/*
+ * List functions.
+ */
+
+#define	LIST_EMPTY(head)	((head)->lh_first == NULL)
+
+#define	LIST_FIRST(head)	((head)->lh_first)
+
+#define	LIST_FOREACH(var, head, field)					\
+	for ((var) = LIST_FIRST((head));				\
+	    (var);							\
+	    (var) = LIST_NEXT((var), field))
+
+#define	LIST_INIT(head) do {						\
+	LIST_FIRST((head)) = NULL;					\
+} while (0)
+
+#define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
+	if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
+		LIST_NEXT((listelm), field)->field.le_prev =		\
+		    &LIST_NEXT((elm), field);				\
+	LIST_NEXT((listelm), field) = (elm);				\
+	(elm)->field.le_prev = &LIST_NEXT((listelm), field);		\
+} while (0)
+
+#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
+	(elm)->field.le_prev = (listelm)->field.le_prev;		\
+	LIST_NEXT((elm), field) = (listelm);				\
+	*(listelm)->field.le_prev = (elm);				\
+	(listelm)->field.le_prev = &LIST_NEXT((elm), field);		\
+} while (0)
+
+#define	LIST_INSERT_HEAD(head, elm, field) do {				\
+	if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)	\
+		LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
+	LIST_FIRST((head)) = (elm);					\
+	(elm)->field.le_prev = &LIST_FIRST((head));			\
+} while (0)
+
+#define	LIST_NEXT(elm, field)	((elm)->field.le_next)
+
+#define	LIST_REMOVE(elm, field) do {					\
+	if (LIST_NEXT((elm), field) != NULL)				\
+		LIST_NEXT((elm), field)->field.le_prev = 		\
+		    (elm)->field.le_prev;				\
+	*(elm)->field.le_prev = LIST_NEXT((elm), field);		\
+} while (0)
+
+/*
+ * Tail queue declarations.
+ */
+#define	TAILQ_HEAD(name, type)						\
+struct name {								\
+	struct type *tqh_first;	/* first element */			\
+	struct type **tqh_last;	/* addr of last next element */		\
+}
+
+#define	TAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).tqh_first }
+
+#define	TAILQ_ENTRY(type)						\
+struct {								\
+	struct type *tqe_next;	/* next element */			\
+	struct type **tqe_prev;	/* address of previous next element */	\
+}
+
+/*
+ * Tail queue functions.
+ */
+#define	TAILQ_EMPTY(head)	((head)->tqh_first == NULL)
+
+#define	TAILQ_FIRST(head)	((head)->tqh_first)
+
+#define	TAILQ_FOREACH(var, head, field)					\
+	for ((var) = TAILQ_FIRST((head));				\
+	    (var);							\
+	    (var) = TAILQ_NEXT((var), field))
+
+#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
+	for ((var) = TAILQ_LAST((head), headname);			\
+	    (var);							\
+	    (var) = TAILQ_PREV((var), headname, field))
+
+#define	TAILQ_INIT(head) do {						\
+	TAILQ_FIRST((head)) = NULL;					\
+	(head)->tqh_last = &TAILQ_FIRST((head));			\
+} while (0)
+
+#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
+		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
+		    &TAILQ_NEXT((elm), field);				\
+	else								\
+		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
+	TAILQ_NEXT((listelm), field) = (elm);				\
+	(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);		\
+} while (0)
+
+#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
+	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
+	TAILQ_NEXT((elm), field) = (listelm);				\
+	*(listelm)->field.tqe_prev = (elm);				\
+	(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);		\
+} while (0)
+
+#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
+	if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)	\
+		TAILQ_FIRST((head))->field.tqe_prev =			\
+		    &TAILQ_NEXT((elm), field);				\
+	else								\
+		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
+	TAILQ_FIRST((head)) = (elm);					\
+	(elm)->field.tqe_prev = &TAILQ_FIRST((head));			\
+} while (0)
+
+#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
+	TAILQ_NEXT((elm), field) = NULL;				\
+	(elm)->field.tqe_prev = (head)->tqh_last;			\
+	*(head)->tqh_last = (elm);					\
+	(head)->tqh_last = &TAILQ_NEXT((elm), field);			\
+} while (0)
+
+#define	TAILQ_LAST(head, headname)					\
+	(*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+#define	TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define	TAILQ_PREV(elm, headname, field)				\
+	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define	TAILQ_REMOVE(head, elm, field) do {				\
+	if ((TAILQ_NEXT((elm), field)) != NULL)				\
+		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
+		    (elm)->field.tqe_prev;				\
+	else								\
+		(head)->tqh_last = (elm)->field.tqe_prev;		\
+	*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);		\
+} while (0)
+
+/*
+ * Circular queue declarations.
+ */
+#define	CIRCLEQ_HEAD(name, type)					\
+struct name {								\
+	struct type *cqh_first;		/* first element */		\
+	struct type *cqh_last;		/* last element */		\
+}
+
+#define	CIRCLEQ_HEAD_INITIALIZER(head)					\
+	{ (void *)&(head), (void *)&(head) }
+
+#define	CIRCLEQ_ENTRY(type)						\
+struct {								\
+	struct type *cqe_next;		/* next element */		\
+	struct type *cqe_prev;		/* previous element */		\
+}
+
+/*
+ * Circular queue functions.
+ */
+#define	CIRCLEQ_EMPTY(head)	((head)->cqh_first == (void *)(head))
+
+#define	CIRCLEQ_FIRST(head)	((head)->cqh_first)
+
+#define	CIRCLEQ_FOREACH(var, head, field)				\
+	for ((var) = CIRCLEQ_FIRST((head));				\
+	    (var) != (void *)(head) || ((var) = NULL);			\
+	    (var) = CIRCLEQ_NEXT((var), field))
+
+#define	CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
+	for ((var) = CIRCLEQ_LAST((head));				\
+	    (var) != (void *)(head) || ((var) = NULL);			\
+	    (var) = CIRCLEQ_PREV((var), field))
+
+#define	CIRCLEQ_INIT(head) do {						\
+	CIRCLEQ_FIRST((head)) = (void *)(head);				\
+	CIRCLEQ_LAST((head)) = (void *)(head);				\
+} while (0)
+
+#define	CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	CIRCLEQ_NEXT((elm), field) = CIRCLEQ_NEXT((listelm), field);	\
+	CIRCLEQ_PREV((elm), field) = (listelm);				\
+	if (CIRCLEQ_NEXT((listelm), field) == (void *)(head))		\
+		CIRCLEQ_LAST((head)) = (elm);				\
+	else								\
+		CIRCLEQ_PREV(CIRCLEQ_NEXT((listelm), field), field) = (elm);\
+	CIRCLEQ_NEXT((listelm), field) = (elm);				\
+} while (0)
+
+#define	CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
+	CIRCLEQ_NEXT((elm), field) = (listelm);				\
+	CIRCLEQ_PREV((elm), field) = CIRCLEQ_PREV((listelm), field);	\
+	if (CIRCLEQ_PREV((listelm), field) == (void *)(head))		\
+		CIRCLEQ_FIRST((head)) = (elm);				\
+	else								\
+		CIRCLEQ_NEXT(CIRCLEQ_PREV((listelm), field), field) = (elm);\
+	CIRCLEQ_PREV((listelm), field) = (elm);				\
+} while (0)
+
+#define	CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
+	CIRCLEQ_NEXT((elm), field) = CIRCLEQ_FIRST((head));		\
+	CIRCLEQ_PREV((elm), field) = (void *)(head);			\
+	if (CIRCLEQ_LAST((head)) == (void *)(head))			\
+		CIRCLEQ_LAST((head)) = (elm);				\
+	else								\
+		CIRCLEQ_PREV(CIRCLEQ_FIRST((head)), field) = (elm);	\
+	CIRCLEQ_FIRST((head)) = (elm);					\
+} while (0)
+
+#define	CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
+	CIRCLEQ_NEXT((elm), field) = (void *)(head);			\
+	CIRCLEQ_PREV((elm), field) = CIRCLEQ_LAST((head));		\
+	if (CIRCLEQ_FIRST((head)) == (void *)(head))			\
+		CIRCLEQ_FIRST((head)) = (elm);				\
+	else								\
+		CIRCLEQ_NEXT(CIRCLEQ_LAST((head)), field) = (elm);	\
+	CIRCLEQ_LAST((head)) = (elm);					\
+} while (0)
+
+#define	CIRCLEQ_LAST(head)	((head)->cqh_last)
+
+#define	CIRCLEQ_NEXT(elm,field)	((elm)->field.cqe_next)
+
+#define	CIRCLEQ_PREV(elm,field)	((elm)->field.cqe_prev)
+
+#define	CIRCLEQ_REMOVE(head, elm, field) do {				\
+	if (CIRCLEQ_NEXT((elm), field) == (void *)(head))		\
+		CIRCLEQ_LAST((head)) = CIRCLEQ_PREV((elm), field);	\
+	else								\
+		CIRCLEQ_PREV(CIRCLEQ_NEXT((elm), field), field) =	\
+		    CIRCLEQ_PREV((elm), field);				\
+	if (CIRCLEQ_PREV((elm), field) == (void *)(head))		\
+		CIRCLEQ_FIRST((head)) = CIRCLEQ_NEXT((elm), field);	\
+	else								\
+		CIRCLEQ_NEXT(CIRCLEQ_PREV((elm), field), field) =	\
+		    CIRCLEQ_NEXT((elm), field);				\
+} while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_SYS_QUEUE_H_ */

+ 38 - 0
third_party/nimble-1.6.0/porting/nimble/include/os/util.h

@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_OS_UTIL_
+#define H_OS_UTIL_
+
+/* Helpers to pass integers as pointers and vice-versa */
+#define POINTER_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
+#define UINT_TO_POINTER(u) ((void *) ((uintptr_t) (u)))
+#define POINTER_TO_INT(p) ((int) ((intptr_t) (p)))
+#define INT_TO_POINTER(u) ((void *) ((intptr_t) (u)))
+
+/* Helper to retrieve pointer to "parent" object in structure */
+#define CONTAINER_OF(ptr, type, field) \
+        ((type *)(((char *)(ptr)) - offsetof(type, field)))
+
+/* Helper to calculate number of elements in array */
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(array) \
+        (sizeof(array) / sizeof((array)[0]))
+#endif
+#endif

+ 80 - 0
third_party/nimble-1.6.0/porting/nimble/include/stats/stats.h

@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __STATS_H__
+#define __STATS_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define STATS_SECT_DECL(__name)         struct stats_ ## __name
+#define STATS_SECT_END                  };
+
+#define STATS_SECT_START(__name)        STATS_SECT_DECL(__name) {
+#define STATS_SECT_VAR(__var)
+
+#define STATS_HDR(__sectname)           NULL
+
+#define STATS_SECT_ENTRY(__var)
+#define STATS_SECT_ENTRY16(__var)
+#define STATS_SECT_ENTRY32(__var)
+#define STATS_SECT_ENTRY64(__var)
+#define STATS_RESET(__var)
+
+#define STATS_SIZE_INIT_PARMS(__sectvarname, __size) \
+                                        0, 0
+
+#define STATS_INC(__sectvarname, __var)
+#define STATS_INCN(__sectvarname, __var, __n)
+#define STATS_CLEAR(__sectvarname, __var)
+
+#define STATS_NAME_START(__name)
+#define STATS_NAME(__name, __entry)
+#define STATS_NAME_END(__name)
+#define STATS_NAME_INIT_PARMS(__name)   NULL, 0
+
+static inline int
+stats_init(void *a, uint8_t b, uint8_t c, void *d, uint8_t e)
+{
+    /* dummy */
+    return 0;
+}
+
+static inline int
+stats_register(void *a, void *b)
+{
+    /* dummy */
+    return 0;
+}
+
+static inline int
+stats_init_and_reg(void *a, uint8_t b, uint8_t c, void *d, uint8_t e, void *f)
+{
+    /* dummy */
+    return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STATS_H__ */

+ 51 - 0
third_party/nimble-1.6.0/porting/nimble/include/sysflash/sysflash.h

@@ -0,0 +1,51 @@
+/**
+ * This file was generated by Apache newt version: 1.12.0-dev
+ */
+
+#ifndef H_MYNEWT_SYSFLASH_
+#define H_MYNEWT_SYSFLASH_
+
+#include "flash_map/flash_map.h"
+
+#define FLASH_AREA_COUNT 6
+
+/**
+ * This flash map definition is used for two purposes:
+ * 1. To locate the meta area, which contains the true flash map definition.
+ * 2. As a fallback in case the meta area cannot be read from flash.
+ */
+extern const struct flash_area sysflash_map_dflt[FLASH_AREA_COUNT];
+
+/* Flash map was defined in @apache-mynewt-core/hw/bsp/native */
+
+#define FLASH_AREA_BOOTLOADER                    0
+#define FLASH_AREA_BOOTLOADER_DEVICE             0
+#define FLASH_AREA_BOOTLOADER_OFFSET             0x00000000
+#define FLASH_AREA_BOOTLOADER_SIZE               16384
+
+#define FLASH_AREA_IMAGE_0                       1
+#define FLASH_AREA_IMAGE_0_DEVICE                0
+#define FLASH_AREA_IMAGE_0_OFFSET                0x00020000
+#define FLASH_AREA_IMAGE_0_SIZE                  393216
+
+#define FLASH_AREA_IMAGE_1                       2
+#define FLASH_AREA_IMAGE_1_DEVICE                0
+#define FLASH_AREA_IMAGE_1_OFFSET                0x00080000
+#define FLASH_AREA_IMAGE_1_SIZE                  393216
+
+#define FLASH_AREA_IMAGE_SCRATCH                 3
+#define FLASH_AREA_IMAGE_SCRATCH_DEVICE          0
+#define FLASH_AREA_IMAGE_SCRATCH_OFFSET          0x000e0000
+#define FLASH_AREA_IMAGE_SCRATCH_SIZE            131072
+
+#define FLASH_AREA_REBOOT_LOG                    16
+#define FLASH_AREA_REBOOT_LOG_DEVICE             0
+#define FLASH_AREA_REBOOT_LOG_OFFSET             0x00004000
+#define FLASH_AREA_REBOOT_LOG_SIZE               16384
+
+#define FLASH_AREA_NFFS                          17
+#define FLASH_AREA_NFFS_DEVICE                   0
+#define FLASH_AREA_NFFS_OFFSET                   0x00008000
+#define FLASH_AREA_NFFS_SIZE                     32768
+
+#endif

+ 38 - 0
third_party/nimble-1.6.0/porting/nimble/include/sysinit/sysinit.h

@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __SYSINIT_H__
+#define __SYSINIT_H__
+
+#include <assert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SYSINIT_ASSERT_ACTIVE()
+
+#define SYSINIT_PANIC_ASSERT(rc)            assert(rc)
+#define SYSINIT_PANIC_ASSERT_MSG(rc, msg)   assert(rc)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SYSINIT_H__ */

+ 268 - 0
third_party/nimble-1.6.0/porting/nimble/src/endian.c

@@ -0,0 +1,268 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "os/endian.h"
+
+void
+put_le16(void *buf, uint16_t x)
+{
+    uint8_t *u8ptr;
+
+    u8ptr = buf;
+    u8ptr[0] = (uint8_t)x;
+    u8ptr[1] = (uint8_t)(x >> 8);
+}
+
+void
+put_le24(void *buf, uint32_t x)
+{
+    uint8_t *u8ptr;
+
+    u8ptr = buf;
+    u8ptr[0] = (uint8_t)x;
+    u8ptr[1] = (uint8_t)(x >> 8);
+    u8ptr[2] = (uint8_t)(x >> 16);
+}
+
+void
+put_le32(void *buf, uint32_t x)
+{
+    uint8_t *u8ptr;
+
+    u8ptr = buf;
+    u8ptr[0] = (uint8_t)x;
+    u8ptr[1] = (uint8_t)(x >> 8);
+    u8ptr[2] = (uint8_t)(x >> 16);
+    u8ptr[3] = (uint8_t)(x >> 24);
+}
+
+void
+put_le64(void *buf, uint64_t x)
+{
+    uint8_t *u8ptr;
+
+    u8ptr = buf;
+    u8ptr[0] = (uint8_t)x;
+    u8ptr[1] = (uint8_t)(x >> 8);
+    u8ptr[2] = (uint8_t)(x >> 16);
+    u8ptr[3] = (uint8_t)(x >> 24);
+    u8ptr[4] = (uint8_t)(x >> 32);
+    u8ptr[5] = (uint8_t)(x >> 40);
+    u8ptr[6] = (uint8_t)(x >> 48);
+    u8ptr[7] = (uint8_t)(x >> 56);
+}
+
+uint16_t
+get_le16(const void *buf)
+{
+    const uint8_t *u8ptr;
+    uint16_t x;
+
+    u8ptr = buf;
+    x = u8ptr[0];
+    x |= (uint16_t)u8ptr[1] << 8;
+
+    return x;
+}
+
+uint32_t
+get_le24(const void *buf)
+{
+    const uint8_t *u8ptr;
+    uint32_t x;
+
+    u8ptr = buf;
+    x = u8ptr[0];
+    x |= (uint32_t)u8ptr[1] << 8;
+    x |= (uint32_t)u8ptr[2] << 16;
+
+    return x;
+}
+
+uint32_t
+get_le32(const void *buf)
+{
+    const uint8_t *u8ptr;
+    uint32_t x;
+
+    u8ptr = buf;
+    x = u8ptr[0];
+    x |= (uint32_t)u8ptr[1] << 8;
+    x |= (uint32_t)u8ptr[2] << 16;
+    x |= (uint32_t)u8ptr[3] << 24;
+
+    return x;
+}
+
+uint64_t
+get_le64(const void *buf)
+{
+    const uint8_t *u8ptr;
+    uint64_t x;
+
+    u8ptr = buf;
+    x = u8ptr[0];
+    x |= (uint64_t)u8ptr[1] << 8;
+    x |= (uint64_t)u8ptr[2] << 16;
+    x |= (uint64_t)u8ptr[3] << 24;
+    x |= (uint64_t)u8ptr[4] << 32;
+    x |= (uint64_t)u8ptr[5] << 40;
+    x |= (uint64_t)u8ptr[6] << 48;
+    x |= (uint64_t)u8ptr[7] << 56;
+
+    return x;
+}
+
+void
+put_be16(void *buf, uint16_t x)
+{
+    uint8_t *u8ptr;
+
+    u8ptr = buf;
+    u8ptr[0] = (uint8_t)(x >> 8);
+    u8ptr[1] = (uint8_t)x;
+}
+
+void
+put_be24(void *buf, uint32_t x)
+{
+    uint8_t *u8ptr;
+
+    u8ptr = buf;
+    u8ptr[0] = (uint8_t)(x >> 16);
+    u8ptr[1] = (uint8_t)(x >> 8);
+    u8ptr[2] = (uint8_t)x;
+}
+
+void
+put_be32(void *buf, uint32_t x)
+{
+    uint8_t *u8ptr;
+
+    u8ptr = buf;
+    u8ptr[0] = (uint8_t)(x >> 24);
+    u8ptr[1] = (uint8_t)(x >> 16);
+    u8ptr[2] = (uint8_t)(x >> 8);
+    u8ptr[3] = (uint8_t)x;
+}
+
+void
+put_be64(void *buf, uint64_t x)
+{
+    uint8_t *u8ptr;
+
+    u8ptr = buf;
+    u8ptr[0] = (uint8_t)(x >> 56);
+    u8ptr[1] = (uint8_t)(x >> 48);
+    u8ptr[2] = (uint8_t)(x >> 40);
+    u8ptr[3] = (uint8_t)(x >> 32);
+    u8ptr[4] = (uint8_t)(x >> 24);
+    u8ptr[5] = (uint8_t)(x >> 16);
+    u8ptr[6] = (uint8_t)(x >> 8);
+    u8ptr[7] = (uint8_t)x;
+}
+
+uint16_t
+get_be16(const void *buf)
+{
+    const uint8_t *u8ptr;
+    uint16_t x;
+
+    u8ptr = buf;
+    x = (uint16_t)u8ptr[0] << 8;
+    x |= u8ptr[1];
+
+    return x;
+}
+
+uint32_t
+get_be24(const void *buf)
+{
+    const uint8_t *u8ptr;
+    uint32_t x;
+
+    u8ptr = buf;
+    x = (uint32_t)u8ptr[0] << 16;
+    x |= (uint32_t)u8ptr[1] << 8;
+    x |= (uint32_t)u8ptr[2];
+
+    return x;
+}
+
+uint32_t
+get_be32(const void *buf)
+{
+    const uint8_t *u8ptr;
+    uint32_t x;
+
+    u8ptr = buf;
+    x = (uint32_t)u8ptr[0] << 24;
+    x |= (uint32_t)u8ptr[1] << 16;
+    x |= (uint32_t)u8ptr[2] << 8;
+    x |= u8ptr[3];
+
+    return x;
+}
+
+uint64_t
+get_be64(const void *buf)
+{
+    const uint8_t *u8ptr;
+    uint64_t x;
+
+    u8ptr = buf;
+    x = (uint64_t)u8ptr[0] << 56;
+    x |= (uint64_t)u8ptr[1] << 48;
+    x |= (uint64_t)u8ptr[2] << 40;
+    x |= (uint64_t)u8ptr[3] << 32;
+    x |= (uint64_t)u8ptr[4] << 24;
+    x |= (uint64_t)u8ptr[5] << 16;
+    x |= (uint64_t)u8ptr[6] << 8;
+    x |= u8ptr[7];
+
+    return x;
+}
+void
+swap_in_place(void *buf, int len)
+{
+    uint8_t *u8ptr;
+    uint8_t tmp;
+    int i;
+    int j;
+
+    u8ptr = buf;
+
+    for (i = 0, j = len - 1; i < j; i++, j--) {
+        tmp = u8ptr[i];
+
+        u8ptr[i] = u8ptr[j];
+        u8ptr[j] = tmp;
+    }
+}
+
+/* swap octets */
+void
+swap_buf(uint8_t *dst, const uint8_t *src, int len)
+{
+    int i;
+
+    for (i = 0; i < len; i++) {
+        dst[len - 1 - i] = src[i];
+    }
+}

+ 324 - 0
third_party/nimble-1.6.0/porting/nimble/src/mem.c

@@ -0,0 +1,324 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <stdlib.h>
+#include "os/os.h"
+#include "mem/mem.h"
+
+/**
+ * Generic mempool allocation function.  Used with basic and extended mempools.
+ */
+static int
+mem_malloc_mempool_gen(uint16_t num_blocks, uint32_t block_size,
+                       void **out_buf)
+{
+    block_size = OS_ALIGN(block_size, OS_ALIGNMENT);
+
+    if (num_blocks > 0) {
+        *out_buf = malloc(OS_MEMPOOL_BYTES(num_blocks, block_size));
+        if (*out_buf == NULL) {
+            return OS_ENOMEM;
+        }
+    } else {
+        *out_buf = NULL;
+    }
+
+    return 0;
+}
+
+/**
+ * Mallocs a block of memory and initializes a mempool to use it.
+ *
+ * @param mempool               The mempool to initialize.
+ * @param num_blocks            The total number of memory blocks in the
+ *                                  mempool.
+ * @param block_size            The size of each mempool entry.
+ * @param name                  The name to give the mempool.
+ * @param out_buf               On success, this points to the malloced memory.
+ *                                  Pass NULL if you don't need this
+ *                                  information.
+ *
+ * @return                      0 on success;
+ *                              OS_ENOMEM on malloc failure;
+ *                              Other OS code on unexpected error.
+ */
+int
+mem_malloc_mempool(struct os_mempool *mempool, uint16_t num_blocks,
+                   uint32_t block_size, char *name, void **out_buf)
+{
+    void *buf;
+    int rc;
+
+    rc = mem_malloc_mempool_gen(num_blocks, block_size, &buf);
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = os_mempool_init(mempool, num_blocks, block_size, buf, name);
+    if (rc != 0) {
+        free(buf);
+        return rc;
+    }
+
+    if (out_buf != NULL) {
+        *out_buf = buf;
+    }
+
+    return 0;
+}
+
+/**
+ * Mallocs a block of memory and initializes an extended mempool to use it.
+ *
+ * @param mpe                   The extended mempool to initialize.
+ * @param num_blocks            The total number of memory blocks in the
+ *                                  mempool.
+ * @param block_size            The size of each mempool entry.
+ * @param name                  The name to give the mempool.
+ * @param out_buf               On success, this points to the malloced memory.
+ *                                  Pass NULL if you don't need this
+ *                                  information.
+ *
+ * @return                      0 on success;
+ *                              OS_ENOMEM on malloc failure;
+ *                              Other OS code on unexpected error.
+ */
+int
+mem_malloc_mempool_ext(struct os_mempool_ext *mpe, uint16_t num_blocks,
+                       uint32_t block_size, char *name, void **out_buf)
+{
+    void *buf;
+    int rc;
+
+    rc = mem_malloc_mempool_gen(num_blocks, block_size, &buf);
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = os_mempool_ext_init(mpe, num_blocks, block_size, buf, name);
+    if (rc != 0) {
+        free(buf);
+        return rc;
+    }
+
+    if (out_buf != NULL) {
+        *out_buf = buf;
+    }
+
+    return 0;
+}
+
+/**
+ * Mallocs a block of memory and initializes an mbuf pool to use it.  The
+ * specified block_size indicates the size of an mbuf acquired from the pool if
+ * it does not contain a pkthdr.
+ *
+ * @param mempool               The mempool to initialize.
+ * @param mbuf_pool             The mbuf pool to initialize.
+ * @param num_blocks            The total number of mbufs in the pool.
+ * @param block_size            The size of each mbuf.
+ * @param name                  The name to give the mempool.
+ * @param out_buf               On success, this points to the malloced memory.
+ *                                  Pass NULL if you don't need this
+ *                                  information.
+ *
+ * @return                      0 on success;
+ *                              OS_ENOMEM on malloc failure;
+ *                              Other OS code on unexpected error.
+ */
+int
+mem_malloc_mbuf_pool(struct os_mempool *mempool,
+                     struct os_mbuf_pool *mbuf_pool, uint16_t num_blocks,
+                     uint32_t block_size, char *name,
+                     void **out_buf)
+{
+    void *buf;
+    int rc;
+
+    block_size = OS_ALIGN(block_size + sizeof (struct os_mbuf), OS_ALIGNMENT);
+
+    rc = mem_malloc_mempool(mempool, num_blocks, block_size, name, &buf);
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = os_mbuf_pool_init(mbuf_pool, mempool, block_size, num_blocks);
+    if (rc != 0) {
+        free(buf);
+        return rc;
+    }
+
+    if (out_buf != NULL) {
+        *out_buf = buf;
+    }
+
+    return 0;
+}
+
+/**
+ * Mallocs a block of memory and initializes an mbuf pool to use it.  The
+ * specified block_size indicates the size of an mbuf acquired from the pool if
+ * it contains a pkthdr.
+ *
+ * @param mempool               The mempool to initialize.
+ * @param mbuf_pool             The mbuf pool to initialize.
+ * @param num_blocks            The total number of mbufs in the pool.
+ * @param block_size            The size of each mbuf.
+ * @param name                  The name to give the mempool.
+ * @param out_buf               On success, this points to the malloced memory.
+ *                                  Pass NULL if you don't need this
+ *                                  information.
+ *
+ * @return                      0 on success;
+ *                              OS_ENOMEM on malloc failure;
+ *                              Other OS code on unexpected error.
+ */
+int
+mem_malloc_mbufpkt_pool(struct os_mempool *mempool,
+                        struct os_mbuf_pool *mbuf_pool, int num_blocks,
+                        int block_size, char *name,
+                        void **out_buf)
+{
+    int rc;
+
+    rc = mem_malloc_mbuf_pool(mempool, mbuf_pool, num_blocks,
+                              block_size + sizeof (struct os_mbuf_pkthdr),
+                              name, out_buf);
+    return rc;
+}
+
+int
+mem_init_mbuf_pool(void *mem, struct os_mempool *mempool,
+                   struct os_mbuf_pool *mbuf_pool, int num_blocks,
+                   int block_size, char *name)
+{
+    int rc;
+
+    rc = os_mempool_init(mempool, num_blocks, block_size, mem, name);
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = os_mbuf_pool_init(mbuf_pool, mempool, block_size, num_blocks);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
+
+/*
+ * Splits an appropriately-sized fragment from the front of an mbuf chain, as
+ * neeeded.  If the length of the mbuf chain greater than specified maximum
+ * fragment size, a new mbuf is allocated, and data is moved from the source
+ * mbuf to the new mbuf.  If the mbuf chain is small enough to fit in a single
+ * fragment, the source mbuf itself is returned unmodified, and the suplied
+ * pointer is set to NULL.
+ *
+ * This function is expected to be called in a loop until the entire mbuf chain
+ * has been consumed.  For example:
+ *
+ *     struct os_mbuf *frag;
+ *     struct os_mbuf *rsp;
+ *     // [...]
+ *     while (rsp != NULL) {
+ *         frag = mem_split_frag(&rsp, get_mtu(), frag_alloc, NULL);
+ *         if (frag == NULL) {
+ *             os_mbuf_free_chain(rsp);
+ *             return OS_ENOMEM;
+ *         }
+ *         send_packet(frag)
+ *     }
+ *
+ * @param om                    The packet to fragment.  Upon fragmentation,
+ *                                  this mbuf is adjusted such that the
+ *                                  fragment data is removed.  If the packet
+ *                                  constitutes a single fragment, this gets
+ *                                  set to NULL on success.
+ * @param max_frag_sz           The maximum payload size of a fragment.
+ *                                  Typically this is the MTU of the
+ *                                  connection.
+ * @param alloc_cb              Points to a function that allocates an mbuf to
+ *                                  hold a fragment.  This function gets called
+ *                                  before the source mbuf chain is modified,
+ *                                  so it can safely inspect it.
+ * @param cb_arg                Generic parameter that gets passed to the
+ *                                  callback function.
+ *
+ * @return                      The next fragment to send on success;
+ *                              NULL on failure.
+ */
+struct os_mbuf *
+mem_split_frag(struct os_mbuf **om, uint16_t max_frag_sz,
+               mem_frag_alloc_fn *alloc_cb, void *cb_arg)
+{
+    struct os_mbuf *frag;
+    int rc;
+
+    if (OS_MBUF_PKTLEN(*om) <= max_frag_sz) {
+        /* Final fragment. */
+        frag = *om;
+        *om = NULL;
+        return frag;
+    }
+
+    /* Packet needs to be split.  Allocate a new buffer for the fragment. */
+    frag = alloc_cb(max_frag_sz, cb_arg);
+    if (frag == NULL) {
+        goto err;
+    }
+
+    /* Move data from the front of the packet into the fragment mbuf. */
+    rc = os_mbuf_appendfrom(frag, *om, 0, max_frag_sz);
+    if (rc != 0) {
+        goto err;
+    }
+    os_mbuf_adj(*om, max_frag_sz);
+
+    /* Free unused portion of of source mbuf chain, if possible. */
+    *om = os_mbuf_trim_front(*om);
+
+    return frag;
+
+err:
+    os_mbuf_free_chain(frag);
+    return NULL;
+}
+
+/**
+ * Applies a pullup operation to the supplied mbuf and returns a pointer to the
+ * start of the mbuf data.  This is simply a convenience function which allows
+ * the user to access the mbuf data without a cast.  On failure, the provided
+ * mbuf is freed.
+ *
+ * @param om                    The mbuf to pull up.
+ * @param len                   The size of the object to pull up.
+ *
+ * @return                      The start of the pulled-up mbuf data.
+ */
+void *
+mem_pullup_obj(struct os_mbuf **om, uint16_t len)
+{
+    *om = os_mbuf_pullup(*om, len);
+    if (*om == NULL) {
+        return NULL;
+    }
+
+    return (*om)->om_data;
+}

+ 84 - 0
third_party/nimble-1.6.0/porting/nimble/src/nimble_port.c

@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <stddef.h>
+#include "os/os.h"
+#include "sysinit/sysinit.h"
+#include "host/ble_hs.h"
+#include "nimble/nimble_port.h"
+#include "nimble/transport.h"
+#if NIMBLE_CFG_CONTROLLER
+#include "controller/ble_ll.h"
+#endif
+
+static struct ble_npl_eventq g_eventq_dflt;
+
+extern void os_msys_init(void);
+extern void os_mempool_module_init(void);
+
+void
+nimble_port_init(void)
+{
+    /* Initialize default event queue */
+    ble_npl_eventq_init(&g_eventq_dflt);
+    /* Initialize the global memory pool */
+    os_mempool_module_init();
+    os_msys_init();
+    /* Initialize transport */
+    ble_transport_init();
+    /* Initialize the host */
+    ble_transport_hs_init();
+
+#if NIMBLE_CFG_CONTROLLER
+#ifndef RIOT_VERSION
+    hal_timer_init(5, NULL);
+    os_cputime_init(32768);
+#endif
+#endif
+
+    /* Initialize the controller */
+    ble_transport_ll_init();
+}
+
+void
+nimble_port_run(void)
+{
+    struct ble_npl_event *ev;
+
+    while (1) {
+        ev = ble_npl_eventq_get(&g_eventq_dflt, BLE_NPL_TIME_FOREVER);
+        ble_npl_event_run(ev);
+    }
+}
+
+struct ble_npl_eventq *
+nimble_port_get_dflt_eventq(void)
+{
+    return &g_eventq_dflt;
+}
+
+#if NIMBLE_CFG_CONTROLLER
+void
+nimble_port_ll_task_func(void *arg)
+{
+    extern void ble_ll_task(void *);
+
+    ble_ll_task(arg);
+}
+#endif

+ 1253 - 0
third_party/nimble-1.6.0/porting/nimble/src/os_mbuf.c

@@ -0,0 +1,1253 @@
+/*
+ * Software in this file is based heavily on code written in the FreeBSD source
+ * code repostiory.  While the code is written from scratch, it contains
+ * many of the ideas and logic flow in the original source, this is a
+ * derivative work, and the following license applies as well:
+ *
+ * Copyright (c) 1982, 1986, 1988, 1991, 1993
+ *  The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include "os/os.h"
+#include "os/os_trace_api.h"
+
+#include <assert.h>
+#include <stddef.h>
+#include <string.h>
+#include <limits.h>
+
+#ifndef min
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef max
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+/**
+ * @addtogroup OSKernel
+ * @{
+ *   @defgroup OSMqueue Queue of Mbufs
+ *   @{
+ */
+
+STAILQ_HEAD(, os_mbuf_pool) g_msys_pool_list =
+    STAILQ_HEAD_INITIALIZER(g_msys_pool_list);
+
+
+int
+os_mqueue_init(struct os_mqueue *mq, ble_npl_event_fn *ev_cb, void *arg)
+{
+    struct ble_npl_event *ev;
+
+    STAILQ_INIT(&mq->mq_head);
+
+    ev = &mq->mq_ev;
+    ble_npl_event_init(ev, ev_cb, arg);
+
+    return (0);
+}
+
+struct os_mbuf *
+os_mqueue_get(struct os_mqueue *mq)
+{
+    struct os_mbuf_pkthdr *mp;
+    struct os_mbuf *m;
+    os_sr_t sr;
+
+    OS_ENTER_CRITICAL(sr);
+    mp = STAILQ_FIRST(&mq->mq_head);
+    if (mp) {
+        STAILQ_REMOVE_HEAD(&mq->mq_head, omp_next);
+    }
+    OS_EXIT_CRITICAL(sr);
+
+    if (mp) {
+        m = OS_MBUF_PKTHDR_TO_MBUF(mp);
+    } else {
+        m = NULL;
+    }
+
+    return (m);
+}
+
+int
+os_mqueue_put(struct os_mqueue *mq, struct ble_npl_eventq *evq, struct os_mbuf *m)
+{
+    struct os_mbuf_pkthdr *mp;
+    os_sr_t sr;
+    int rc;
+
+    /* Can only place the head of a chained mbuf on the queue. */
+    if (!OS_MBUF_IS_PKTHDR(m)) {
+        rc = OS_EINVAL;
+        goto err;
+    }
+
+    mp = OS_MBUF_PKTHDR(m);
+
+    OS_ENTER_CRITICAL(sr);
+    STAILQ_INSERT_TAIL(&mq->mq_head, mp, omp_next);
+    OS_EXIT_CRITICAL(sr);
+
+    /* Only post an event to the queue if its specified */
+    if (evq) {
+        ble_npl_eventq_put(evq, &mq->mq_ev);
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+int
+os_msys_register(struct os_mbuf_pool *new_pool)
+{
+    struct os_mbuf_pool *pool;
+
+    pool = NULL;
+    STAILQ_FOREACH(pool, &g_msys_pool_list, omp_next) {
+        if (new_pool->omp_databuf_len > pool->omp_databuf_len) {
+            break;
+        }
+    }
+
+    if (pool) {
+        STAILQ_INSERT_AFTER(&g_msys_pool_list, pool, new_pool, omp_next);
+    } else {
+        STAILQ_INSERT_TAIL(&g_msys_pool_list, new_pool, omp_next);
+    }
+
+    return (0);
+}
+
+void
+os_msys_reset(void)
+{
+    STAILQ_INIT(&g_msys_pool_list);
+}
+
+static struct os_mbuf_pool *
+_os_msys_find_pool(uint16_t dsize)
+{
+    struct os_mbuf_pool *pool;
+
+    pool = NULL;
+    STAILQ_FOREACH(pool, &g_msys_pool_list, omp_next) {
+        if (dsize <= pool->omp_databuf_len) {
+            break;
+        }
+    }
+
+    if (!pool) {
+        pool = STAILQ_LAST(&g_msys_pool_list, os_mbuf_pool, omp_next);
+    }
+
+    return (pool);
+}
+
+
+struct os_mbuf *
+os_msys_get(uint16_t dsize, uint16_t leadingspace)
+{
+    struct os_mbuf *m;
+    struct os_mbuf_pool *pool;
+
+    pool = _os_msys_find_pool(dsize);
+    if (!pool) {
+        goto err;
+    }
+
+    m = os_mbuf_get(pool, leadingspace);
+    return (m);
+err:
+    return (NULL);
+}
+
+struct os_mbuf *
+os_msys_get_pkthdr(uint16_t dsize, uint16_t user_hdr_len)
+{
+    uint16_t total_pkthdr_len;
+    struct os_mbuf *m;
+    struct os_mbuf_pool *pool;
+
+    total_pkthdr_len =  user_hdr_len + sizeof(struct os_mbuf_pkthdr);
+    pool = _os_msys_find_pool(dsize + total_pkthdr_len);
+    if (!pool) {
+        goto err;
+    }
+
+    m = os_mbuf_get_pkthdr(pool, user_hdr_len);
+    return (m);
+err:
+    return (NULL);
+}
+
+int
+os_msys_count(void)
+{
+    struct os_mbuf_pool *omp;
+    int total;
+
+    total = 0;
+    STAILQ_FOREACH(omp, &g_msys_pool_list, omp_next) {
+        total += omp->omp_pool->mp_num_blocks;
+    }
+
+    return total;
+}
+
+int
+os_msys_num_free(void)
+{
+    struct os_mbuf_pool *omp;
+    int total;
+
+    total = 0;
+    STAILQ_FOREACH(omp, &g_msys_pool_list, omp_next) {
+        total += omp->omp_pool->mp_num_free;
+    }
+
+    return total;
+}
+
+
+int
+os_mbuf_pool_init(struct os_mbuf_pool *omp, struct os_mempool *mp,
+                  uint16_t buf_len, uint16_t nbufs)
+{
+    omp->omp_databuf_len = buf_len - sizeof(struct os_mbuf);
+    omp->omp_pool = mp;
+
+    return (0);
+}
+
+struct os_mbuf *
+os_mbuf_get(struct os_mbuf_pool *omp, uint16_t leadingspace)
+{
+    struct os_mbuf *om;
+
+    os_trace_api_u32x2(OS_TRACE_ID_MBUF_GET, (uint32_t)omp,
+                       (uint32_t)(uintptr_t)leadingspace);
+
+    if (leadingspace > omp->omp_databuf_len) {
+        om = NULL;
+        goto done;
+    }
+
+    om = os_memblock_get(omp->omp_pool);
+    if (!om) {
+        goto done;
+    }
+
+    SLIST_NEXT(om, om_next) = NULL;
+    om->om_flags = 0;
+    om->om_pkthdr_len = 0;
+    om->om_len = 0;
+    om->om_data = (&om->om_databuf[0] + leadingspace);
+    om->om_omp = omp;
+
+done:
+    os_trace_api_ret_u32(OS_TRACE_ID_MBUF_GET, (uint32_t)(uintptr_t)om);
+    return om;
+}
+
+struct os_mbuf *
+os_mbuf_get_pkthdr(struct os_mbuf_pool *omp, uint8_t user_pkthdr_len)
+{
+    uint16_t pkthdr_len;
+    struct os_mbuf_pkthdr *pkthdr;
+    struct os_mbuf *om;
+
+    os_trace_api_u32x2(OS_TRACE_ID_MBUF_GET_PKTHDR, (uint32_t)(uintptr_t)omp,
+                       (uint32_t)user_pkthdr_len);
+
+    /* User packet header must fit inside mbuf */
+    pkthdr_len = user_pkthdr_len + sizeof(struct os_mbuf_pkthdr);
+    if ((pkthdr_len > omp->omp_databuf_len) || (pkthdr_len > 255)) {
+        om = NULL;
+        goto done;
+    }
+
+    om = os_mbuf_get(omp, 0);
+    if (om) {
+        om->om_pkthdr_len = pkthdr_len;
+        om->om_data += pkthdr_len;
+
+        pkthdr = OS_MBUF_PKTHDR(om);
+        pkthdr->omp_len = 0;
+        pkthdr->omp_flags = 0;
+        STAILQ_NEXT(pkthdr, omp_next) = NULL;
+    }
+
+done:
+    os_trace_api_ret_u32(OS_TRACE_ID_MBUF_GET_PKTHDR, (uint32_t)(uintptr_t)om);
+    return om;
+}
+
+int
+os_mbuf_free(struct os_mbuf *om)
+{
+    int rc;
+
+    os_trace_api_u32(OS_TRACE_ID_MBUF_FREE, (uint32_t)(uintptr_t)om);
+
+    if (om->om_omp != NULL) {
+        rc = os_memblock_put(om->om_omp->omp_pool, om);
+        if (rc != 0) {
+            goto done;
+        }
+    }
+
+    rc = 0;
+
+done:
+    os_trace_api_ret_u32(OS_TRACE_ID_MBUF_FREE, (uint32_t)rc);
+    return (rc);
+}
+
+int
+os_mbuf_free_chain(struct os_mbuf *om)
+{
+    struct os_mbuf *next;
+    int rc;
+
+    os_trace_api_u32(OS_TRACE_ID_MBUF_FREE_CHAIN, (uint32_t)(uintptr_t)om);
+
+    while (om != NULL) {
+        next = SLIST_NEXT(om, om_next);
+
+        rc = os_mbuf_free(om);
+        if (rc != 0) {
+            goto done;
+        }
+
+        om = next;
+    }
+
+    rc = 0;
+
+done:
+    os_trace_api_ret_u32(OS_TRACE_ID_MBUF_FREE_CHAIN, (uint32_t)rc);
+    return (rc);
+}
+
+/**
+ * Copy a packet header from one mbuf to another.
+ *
+ * @param omp The mbuf pool associated with these buffers
+ * @param new_buf The new buffer to copy the packet header into
+ * @param old_buf The old buffer to copy the packet header from
+ */
+static inline void
+_os_mbuf_copypkthdr(struct os_mbuf *new_buf, struct os_mbuf *old_buf)
+{
+    assert(new_buf->om_len == 0);
+
+    memcpy(&new_buf->om_databuf[0], &old_buf->om_databuf[0],
+           old_buf->om_pkthdr_len);
+    new_buf->om_pkthdr_len = old_buf->om_pkthdr_len;
+    new_buf->om_data = new_buf->om_databuf + old_buf->om_pkthdr_len;
+}
+
+uint16_t
+os_mbuf_len(const struct os_mbuf *om)
+{
+    uint16_t len;
+
+    len = 0;
+    while (om != NULL) {
+        len += om->om_len;
+        om = SLIST_NEXT(om, om_next);
+    }
+
+    return len;
+}
+
+int
+os_mbuf_append(struct os_mbuf *om, const void *data,  uint16_t len)
+{
+    struct os_mbuf_pool *omp;
+    struct os_mbuf *last;
+    struct os_mbuf *new;
+    int remainder;
+    int space;
+    int rc;
+
+    if (om == NULL) {
+        rc = OS_EINVAL;
+        goto err;
+    }
+
+    omp = om->om_omp;
+
+    /* Scroll to last mbuf in the chain */
+    last = om;
+    while (SLIST_NEXT(last, om_next) != NULL) {
+        last = SLIST_NEXT(last, om_next);
+    }
+
+    remainder = len;
+    space = OS_MBUF_TRAILINGSPACE(last);
+
+    /* If room in current mbuf, copy the first part of the data into the
+     * remaining space in that mbuf.
+     */
+    if (space > 0) {
+        if (space > remainder) {
+            space = remainder;
+        }
+
+        memcpy(OS_MBUF_DATA(last, uint8_t *) + last->om_len , data, space);
+
+        last->om_len += space;
+        data += space;
+        remainder -= space;
+    }
+
+    /* Take the remaining data, and keep allocating new mbufs and copying
+     * data into it, until data is exhausted.
+     */
+    while (remainder > 0) {
+        new = os_mbuf_get(omp, 0);
+        if (!new) {
+            break;
+        }
+
+        new->om_len = min(omp->omp_databuf_len, remainder);
+        memcpy(OS_MBUF_DATA(new, void *), data, new->om_len);
+        data += new->om_len;
+        remainder -= new->om_len;
+        SLIST_NEXT(last, om_next) = new;
+        last = new;
+    }
+
+    /* Adjust the packet header length in the buffer */
+    if (OS_MBUF_IS_PKTHDR(om)) {
+        OS_MBUF_PKTHDR(om)->omp_len += len - remainder;
+    }
+
+    if (remainder != 0) {
+        rc = OS_ENOMEM;
+        goto err;
+    }
+
+
+    return (0);
+err:
+    return (rc);
+}
+
+int
+os_mbuf_appendfrom(struct os_mbuf *dst, const struct os_mbuf *src,
+                   uint16_t src_off, uint16_t len)
+{
+    const struct os_mbuf *src_cur_om;
+    uint16_t src_cur_off;
+    uint16_t chunk_sz;
+    int rc;
+
+    src_cur_om = os_mbuf_off(src, src_off, &src_cur_off);
+    while (len > 0) {
+        if (src_cur_om == NULL) {
+            return OS_EINVAL;
+        }
+
+        chunk_sz = min(len, src_cur_om->om_len - src_cur_off);
+        rc = os_mbuf_append(dst, src_cur_om->om_data + src_cur_off, chunk_sz);
+        if (rc != 0) {
+            return rc;
+        }
+
+        len -= chunk_sz;
+        src_cur_om = SLIST_NEXT(src_cur_om, om_next);
+        src_cur_off = 0;
+    }
+
+    return 0;
+}
+
+struct os_mbuf *
+os_mbuf_dup(struct os_mbuf *om)
+{
+    struct os_mbuf_pool *omp;
+    struct os_mbuf *head;
+    struct os_mbuf *copy;
+
+    omp = om->om_omp;
+
+    head = NULL;
+    copy = NULL;
+
+    for (; om != NULL; om = SLIST_NEXT(om, om_next)) {
+        if (head) {
+            SLIST_NEXT(copy, om_next) = os_mbuf_get(omp,
+                    OS_MBUF_LEADINGSPACE(om));
+            if (!SLIST_NEXT(copy, om_next)) {
+                os_mbuf_free_chain(head);
+                goto err;
+            }
+
+            copy = SLIST_NEXT(copy, om_next);
+        } else {
+            head = os_mbuf_get(omp, OS_MBUF_LEADINGSPACE(om));
+            if (!head) {
+                goto err;
+            }
+
+            if (OS_MBUF_IS_PKTHDR(om)) {
+                _os_mbuf_copypkthdr(head, om);
+            }
+            copy = head;
+        }
+        copy->om_flags = om->om_flags;
+        copy->om_len = om->om_len;
+        memcpy(OS_MBUF_DATA(copy, uint8_t *), OS_MBUF_DATA(om, uint8_t *),
+                om->om_len);
+    }
+
+    return (head);
+err:
+    return (NULL);
+}
+
+struct os_mbuf *
+os_mbuf_off(const struct os_mbuf *om, int off, uint16_t *out_off)
+{
+    struct os_mbuf *next;
+    struct os_mbuf *cur;
+
+    /* Cast away const. */
+    cur = (struct os_mbuf *)om;
+
+    while (1) {
+        if (cur == NULL) {
+            return NULL;
+        }
+
+        next = SLIST_NEXT(cur, om_next);
+
+        if (cur->om_len > off ||
+            (cur->om_len == off && next == NULL)) {
+
+            *out_off = off;
+            return cur;
+        }
+
+        off -= cur->om_len;
+        cur = next;
+    }
+}
+
+int
+os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst)
+{
+    unsigned int count;
+    uint8_t *udst;
+
+    if (!len) {
+        return 0;
+    }
+
+    udst = dst;
+
+    while (off > 0) {
+        if (!m) {
+            return (-1);
+        }
+
+        if (off < m->om_len)
+            break;
+        off -= m->om_len;
+        m = SLIST_NEXT(m, om_next);
+    }
+    while (len > 0 && m != NULL) {
+        count = min(m->om_len - off, len);
+        memcpy(udst, m->om_data + off, count);
+        len -= count;
+        udst += count;
+        off = 0;
+        m = SLIST_NEXT(m, om_next);
+    }
+
+    return (len > 0 ? -1 : 0);
+}
+
+void
+os_mbuf_adj(struct os_mbuf *mp, int req_len)
+{
+    int len = req_len;
+    struct os_mbuf *m;
+    int count;
+
+    if ((m = mp) == NULL)
+        return;
+    if (len >= 0) {
+        /*
+         * Trim from head.
+         */
+        while (m != NULL && len > 0) {
+            if (m->om_len <= len) {
+                len -= m->om_len;
+                m->om_len = 0;
+                m = SLIST_NEXT(m, om_next);
+            } else {
+                m->om_len -= len;
+                m->om_data += len;
+                len = 0;
+            }
+        }
+        if (OS_MBUF_IS_PKTHDR(mp))
+            OS_MBUF_PKTHDR(mp)->omp_len -= (req_len - len);
+    } else {
+        /*
+         * Trim from tail.  Scan the mbuf chain,
+         * calculating its length and finding the last mbuf.
+         * If the adjustment only affects this mbuf, then just
+         * adjust and return.  Otherwise, rescan and truncate
+         * after the remaining size.
+         */
+        len = -len;
+        count = 0;
+        for (;;) {
+            count += m->om_len;
+            if (SLIST_NEXT(m, om_next) == (struct os_mbuf *)0)
+                break;
+            m = SLIST_NEXT(m, om_next);
+        }
+        if (m->om_len >= len) {
+            m->om_len -= len;
+            if (OS_MBUF_IS_PKTHDR(mp))
+                OS_MBUF_PKTHDR(mp)->omp_len -= len;
+            return;
+        }
+        count -= len;
+        if (count < 0)
+            count = 0;
+        /*
+         * Correct length for chain is "count".
+         * Find the mbuf with last data, adjust its length,
+         * and toss data from remaining mbufs on chain.
+         */
+        m = mp;
+        if (OS_MBUF_IS_PKTHDR(m))
+            OS_MBUF_PKTHDR(m)->omp_len = count;
+        for (; m; m = SLIST_NEXT(m, om_next)) {
+            if (m->om_len >= count) {
+                m->om_len = count;
+                if (SLIST_NEXT(m, om_next) != NULL) {
+                    os_mbuf_free_chain(SLIST_NEXT(m, om_next));
+                    SLIST_NEXT(m, om_next) = NULL;
+                }
+                break;
+            }
+            count -= m->om_len;
+        }
+    }
+}
+
+int
+os_mbuf_cmpf(const struct os_mbuf *om, int off, const void *data, int len)
+{
+    uint16_t chunk_sz;
+    uint16_t data_off;
+    uint16_t om_off;
+    int rc;
+
+    if (len <= 0) {
+        return 0;
+    }
+
+    data_off = 0;
+    om = os_mbuf_off(om, off, &om_off);
+    while (1) {
+        if (om == NULL) {
+            return INT_MAX;
+        }
+
+        chunk_sz = min(om->om_len - om_off, len - data_off);
+        if (chunk_sz > 0) {
+            rc = memcmp(om->om_data + om_off, data + data_off, chunk_sz);
+            if (rc != 0) {
+                return rc;
+            }
+        }
+
+        data_off += chunk_sz;
+        if (data_off == len) {
+            return 0;
+        }
+
+        om = SLIST_NEXT(om, om_next);
+        om_off = 0;
+
+        if (om == NULL) {
+            return INT_MAX;
+        }
+    }
+}
+
+int
+os_mbuf_cmpm(const struct os_mbuf *om1, uint16_t offset1,
+             const struct os_mbuf *om2, uint16_t offset2,
+             uint16_t len)
+{
+    const struct os_mbuf *cur1;
+    const struct os_mbuf *cur2;
+    uint16_t bytes_remaining;
+    uint16_t chunk_sz;
+    uint16_t om1_left;
+    uint16_t om2_left;
+    uint16_t om1_off;
+    uint16_t om2_off;
+    int rc;
+
+    om1_off = 0;
+    om2_off = 0;
+
+    cur1 = os_mbuf_off(om1, offset1, &om1_off);
+    cur2 = os_mbuf_off(om2, offset2, &om2_off);
+
+    bytes_remaining = len;
+    while (1) {
+        if (bytes_remaining == 0) {
+            return 0;
+        }
+
+        while (cur1 != NULL && om1_off >= cur1->om_len) {
+            cur1 = SLIST_NEXT(cur1, om_next);
+            om1_off = 0;
+        }
+        while (cur2 != NULL && om2_off >= cur2->om_len) {
+            cur2 = SLIST_NEXT(cur2, om_next);
+            om2_off = 0;
+        }
+
+        if (cur1 == NULL || cur2 == NULL) {
+            return INT_MAX;
+        }
+
+        om1_left = cur1->om_len - om1_off;
+        om2_left = cur2->om_len - om2_off;
+        chunk_sz = min(min(om1_left, om2_left), bytes_remaining);
+
+        rc = memcmp(cur1->om_data + om1_off, cur2->om_data + om2_off,
+                    chunk_sz);
+        if (rc != 0) {
+            return rc;
+        }
+
+        om1_off += chunk_sz;
+        om2_off += chunk_sz;
+        bytes_remaining -= chunk_sz;
+    }
+}
+
+struct os_mbuf *
+os_mbuf_prepend(struct os_mbuf *om, int len)
+{
+    struct os_mbuf *p;
+    int leading;
+
+    while (1) {
+        /* Fill the available space at the front of the head of the chain, as
+         * needed.
+         */
+        leading = min(len, OS_MBUF_LEADINGSPACE(om));
+
+        om->om_data -= leading;
+        om->om_len += leading;
+        if (OS_MBUF_IS_PKTHDR(om)) {
+            OS_MBUF_PKTHDR(om)->omp_len += leading;
+        }
+
+        len -= leading;
+        if (len == 0) {
+            break;
+        }
+
+        /* The current head didn't have enough space; allocate a new head. */
+        if (OS_MBUF_IS_PKTHDR(om)) {
+            p = os_mbuf_get_pkthdr(om->om_omp,
+                om->om_pkthdr_len - sizeof (struct os_mbuf_pkthdr));
+        } else {
+            p = os_mbuf_get(om->om_omp, 0);
+        }
+        if (p == NULL) {
+            os_mbuf_free_chain(om);
+            om = NULL;
+            break;
+        }
+
+        if (OS_MBUF_IS_PKTHDR(om)) {
+            _os_mbuf_copypkthdr(p, om);
+            om->om_pkthdr_len = 0;
+        }
+
+        /* Move the new head's data pointer to the end so that data can be
+         * prepended.
+         */
+        p->om_data += OS_MBUF_TRAILINGSPACE(p);
+
+        SLIST_NEXT(p, om_next) = om;
+        om = p;
+    }
+
+    return om;
+}
+
+struct os_mbuf *
+os_mbuf_prepend_pullup(struct os_mbuf *om, uint16_t len)
+{
+    om = os_mbuf_prepend(om, len);
+    if (om == NULL) {
+        return NULL;
+    }
+
+    om = os_mbuf_pullup(om, len);
+    if (om == NULL) {
+        return NULL;
+    }
+
+    return om;
+}
+
+int
+os_mbuf_copyinto(struct os_mbuf *om, int off, const void *src, int len)
+{
+    struct os_mbuf *next;
+    struct os_mbuf *cur;
+    const uint8_t *sptr;
+    uint16_t cur_off;
+    int copylen;
+    int rc;
+
+    /* Find the mbuf,offset pair for the start of the destination. */
+    cur = os_mbuf_off(om, off, &cur_off);
+    if (cur == NULL) {
+        return -1;
+    }
+
+    /* Overwrite existing data until we reach the end of the chain. */
+    sptr = src;
+    while (1) {
+        copylen = min(cur->om_len - cur_off, len);
+        if (copylen > 0) {
+            memcpy(cur->om_data + cur_off, sptr, copylen);
+            sptr += copylen;
+            len -= copylen;
+
+            copylen = 0;
+        }
+
+        if (len == 0) {
+            /* All the source data fit in the existing mbuf chain. */
+            return 0;
+        }
+
+        next = SLIST_NEXT(cur, om_next);
+        if (next == NULL) {
+            break;
+        }
+
+        cur = next;
+        cur_off = 0;
+    }
+
+    /* Append the remaining data to the end of the chain. */
+    rc = os_mbuf_append(cur, sptr, len);
+    if (rc != 0) {
+        return rc;
+    }
+
+    /* Fix up the packet header, if one is present. */
+    if (OS_MBUF_IS_PKTHDR(om)) {
+        OS_MBUF_PKTHDR(om)->omp_len =
+            max(OS_MBUF_PKTHDR(om)->omp_len, off + len);
+    }
+
+    return 0;
+}
+
+void
+os_mbuf_concat(struct os_mbuf *first, struct os_mbuf *second)
+{
+    struct os_mbuf *next;
+    struct os_mbuf *cur;
+
+    /* Point 'cur' to the last buffer in the first chain. */
+    cur = first;
+    while (1) {
+        next = SLIST_NEXT(cur, om_next);
+        if (next == NULL) {
+            break;
+        }
+
+        cur = next;
+    }
+
+    /* Attach the second chain to the end of the first. */
+    SLIST_NEXT(cur, om_next) = second;
+
+    /* If the first chain has a packet header, calculate the length of the
+     * second chain and add it to the header length.
+     */
+    if (OS_MBUF_IS_PKTHDR(first)) {
+        if (OS_MBUF_IS_PKTHDR(second)) {
+            OS_MBUF_PKTHDR(first)->omp_len += OS_MBUF_PKTHDR(second)->omp_len;
+        } else {
+            for (cur = second; cur != NULL; cur = SLIST_NEXT(cur, om_next)) {
+                OS_MBUF_PKTHDR(first)->omp_len += cur->om_len;
+            }
+        }
+    }
+
+    second->om_pkthdr_len = 0;
+}
+
+void *
+os_mbuf_extend(struct os_mbuf *om, uint16_t len)
+{
+    struct os_mbuf *newm;
+    struct os_mbuf *last;
+    void *data;
+
+    if (len > om->om_omp->omp_databuf_len) {
+        return NULL;
+    }
+
+    /* Scroll to last mbuf in the chain */
+    last = om;
+    while (SLIST_NEXT(last, om_next) != NULL) {
+        last = SLIST_NEXT(last, om_next);
+    }
+
+    if (OS_MBUF_TRAILINGSPACE(last) < len) {
+        newm = os_mbuf_get(om->om_omp, 0);
+        if (newm == NULL) {
+            return NULL;
+        }
+
+        SLIST_NEXT(last, om_next) = newm;
+        last = newm;
+    }
+
+    data = last->om_data + last->om_len;
+    last->om_len += len;
+
+    if (OS_MBUF_IS_PKTHDR(om)) {
+        OS_MBUF_PKTHDR(om)->omp_len += len;
+    }
+
+    return data;
+}
+
+
+struct os_mbuf *
+os_mbuf_pullup(struct os_mbuf *om, uint16_t len)
+{
+    struct os_mbuf_pool *omp;
+    struct os_mbuf *next;
+    struct os_mbuf *om2;
+    int count;
+    int space;
+
+    omp = om->om_omp;
+
+    /*
+     * If first mbuf has no cluster, and has room for len bytes
+     * without shifting current data, pullup into it,
+     * otherwise allocate a new mbuf to prepend to the chain.
+     */
+    if (om->om_len >= len) {
+        return (om);
+    }
+    if (om->om_len + OS_MBUF_TRAILINGSPACE(om) >= len &&
+        SLIST_NEXT(om, om_next)) {
+        om2 = om;
+        om = SLIST_NEXT(om, om_next);
+        len -= om2->om_len;
+    } else {
+        if (len > omp->omp_databuf_len - om->om_pkthdr_len) {
+            goto bad;
+        }
+
+        om2 = os_mbuf_get(omp, 0);
+        if (om2 == NULL) {
+            goto bad;
+        }
+
+        if (OS_MBUF_IS_PKTHDR(om)) {
+            _os_mbuf_copypkthdr(om2, om);
+        }
+    }
+    space = OS_MBUF_TRAILINGSPACE(om2);
+    do {
+        count = min(min(len, space), om->om_len);
+        memcpy(om2->om_data + om2->om_len, om->om_data, count);
+        len -= count;
+        om2->om_len += count;
+        om->om_len -= count;
+        space -= count;
+        if (om->om_len) {
+            om->om_data += count;
+        } else {
+            next = SLIST_NEXT(om, om_next);
+            os_mbuf_free(om);
+            om = next;
+        }
+    } while (len > 0 && om);
+    if (len > 0) {
+        os_mbuf_free(om2);
+        goto bad;
+    }
+    SLIST_NEXT(om2, om_next) = om;
+    return (om2);
+bad:
+    os_mbuf_free_chain(om);
+    return (NULL);
+}
+
+struct os_mbuf *
+os_mbuf_trim_front(struct os_mbuf *om)
+{
+    struct os_mbuf *next;
+    struct os_mbuf *cur;
+
+    /* Abort early if there is nothing to trim. */
+    if (om->om_len != 0) {
+        return om;
+    }
+
+    /* Starting with the second mbuf in the chain, continue removing and
+     * freeing mbufs until an non-empty one is encountered.
+     */
+    cur = SLIST_NEXT(om, om_next);
+    while (cur != NULL && cur->om_len == 0) {
+        next = SLIST_NEXT(cur, om_next);
+
+        SLIST_NEXT(om, om_next) = next;
+        os_mbuf_free(cur);
+
+        cur = next;
+    }
+
+    if (cur == NULL) {
+        /* All buffers after the first have been freed. */
+        return om;
+    }
+
+    /* Try to remove the first mbuf in the chain.  If this buffer contains a
+     * packet header, make sure the second buffer can accommodate it.
+     */
+    if (OS_MBUF_LEADINGSPACE(cur) >= om->om_pkthdr_len) {
+        /* Second buffer has room; copy packet header. */
+        cur->om_pkthdr_len = om->om_pkthdr_len;
+        memcpy(OS_MBUF_PKTHDR(cur), OS_MBUF_PKTHDR(om), om->om_pkthdr_len);
+
+        /* Free first buffer. */
+        os_mbuf_free(om);
+        om = cur;
+    }
+
+    return om;
+}
+
+int
+os_mbuf_widen(struct os_mbuf *om, uint16_t off, uint16_t len)
+{
+    struct os_mbuf *first_new;
+    struct os_mbuf *edge_om;
+    struct os_mbuf *prev;
+    struct os_mbuf *cur;
+    uint16_t rem_len;
+    uint16_t sub_off;
+    int rc;
+
+    /* Locate the mbuf and offset within the chain where the gap will be
+     * inserted.
+     */
+    edge_om = os_mbuf_off(om, off, &sub_off);
+    if (edge_om == NULL) {
+        return OS_EINVAL;
+    }
+
+    /* If the mbuf has sufficient capacity for the gap, just make room within
+     * the mbuf.
+     */
+    if (OS_MBUF_TRAILINGSPACE(edge_om) >= len) {
+        memmove(edge_om->om_data + sub_off + len,
+                edge_om->om_data + sub_off,
+                edge_om->om_len - sub_off);
+        edge_om->om_len += len;
+        if (OS_MBUF_IS_PKTHDR(om)) {
+            OS_MBUF_PKTHDR(om)->omp_len += len;
+        }
+        return 0;
+    }
+
+    /* Otherwise, allocate new mbufs until the chain has sufficient capacity
+     * for the gap.
+     */
+    rem_len = len;
+    first_new = NULL;
+    prev = NULL;
+    while (rem_len > 0) {
+        cur = os_mbuf_get(om->om_omp, 0);
+        if (cur == NULL) {
+            /* Free only the mbufs that this function allocated. */
+            os_mbuf_free_chain(first_new);
+            return OS_ENOMEM;
+        }
+
+        /* Remember the start of the chain of new mbufs. */
+        if (first_new == NULL) {
+            first_new = cur;
+        }
+
+        if (rem_len > OS_MBUF_TRAILINGSPACE(cur)) {
+            cur->om_len = OS_MBUF_TRAILINGSPACE(cur);
+        } else {
+            cur->om_len = rem_len;
+        }
+        rem_len -= cur->om_len;
+
+        if (prev != NULL) {
+            SLIST_NEXT(prev, om_next) = cur;
+        }
+        prev = cur;
+    }
+
+    /* Move the misplaced data from the edge mbuf over to the right side of the
+     * gap.
+     */
+    rc = os_mbuf_append(prev, edge_om->om_data + sub_off,
+                        edge_om->om_len - sub_off);
+    if (rc != 0) {
+        os_mbuf_free_chain(first_new);
+        return OS_ENOMEM;
+    }
+    edge_om->om_len = sub_off;
+
+    /* Insert the gap into the chain. */
+    SLIST_NEXT(prev, om_next) = SLIST_NEXT(edge_om, om_next);
+    SLIST_NEXT(edge_om, om_next) = first_new;
+
+    if (OS_MBUF_IS_PKTHDR(om)) {
+        OS_MBUF_PKTHDR(om)->omp_len += len;
+    }
+
+    return 0;
+}
+
+struct os_mbuf *
+os_mbuf_pack_chains(struct os_mbuf *m1, struct os_mbuf *m2)
+{
+    uint16_t rem_len;
+    uint16_t copylen;
+    uint8_t *dptr;
+    struct os_mbuf *cur;
+    struct os_mbuf *next;
+
+    /* If m1 is NULL, return NULL */
+    if (m1 == NULL) {
+        return NULL;
+    }
+
+    /*
+     * Concatenate the two chains to start. This will discard packet header in
+     * m2 and adjust packet length in m1 if m1 has a packet header.
+     */
+    if (m2 != NULL) {
+        os_mbuf_concat(m1, m2);
+    }
+
+    cur = m1;
+    while (1) {
+        /* If there is leading space in the mbuf, move data up */
+        if (OS_MBUF_LEADINGSPACE(cur)) {
+            dptr = &cur->om_databuf[0];
+            if (OS_MBUF_IS_PKTHDR(cur)) {
+                dptr += cur->om_pkthdr_len;
+            }
+            memmove(dptr, cur->om_data, cur->om_len);
+            cur->om_data = dptr;
+        }
+
+        /* Set pointer to where we will begin copying data in current mbuf */
+        dptr = cur->om_data + cur->om_len;
+
+        /* Get a pointer to the next buf we want to absorb */
+        next = SLIST_NEXT(cur, om_next);
+
+        /*
+         * Is there trailing space in the mbuf? If so, copy data from
+         * following mbufs into the current mbuf
+         */
+        rem_len = OS_MBUF_TRAILINGSPACE(cur);
+        while (rem_len && next) {
+            copylen = min(rem_len, next->om_len);
+            memcpy(dptr, next->om_data, copylen);
+            cur->om_len += copylen;
+            dptr += copylen;
+            rem_len -= copylen;
+
+            /*
+             * We copied bytes from the next mbuf. Move the data pointer
+             * and subtract from its length
+             */
+            next->om_data += copylen;
+            next->om_len -= copylen;
+
+            /*
+             * Keep removing and freeing consecutive zero length mbufs,
+             * stopping when we find one with data in it or we have
+             * reached the end. This will prevent any zero length mbufs
+             * from remaining in the chain.
+             */
+            while (next->om_len == 0) {
+                SLIST_NEXT(cur, om_next) = SLIST_NEXT(next, om_next);
+                os_mbuf_free(next);
+                next = SLIST_NEXT(cur, om_next);
+                if (next == NULL) {
+                    break;
+                }
+            }
+        }
+
+        /* If no mbufs are left, we are done */
+        if (next == NULL) {
+            break;
+        }
+
+        /* Move cur to next as we filled up current */
+        cur = next;
+    }
+
+    return m1;
+}

+ 476 - 0
third_party/nimble-1.6.0/porting/nimble/src/os_mempool.c

@@ -0,0 +1,476 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "os/os.h"
+#include "os/os_trace_api.h"
+
+#include <string.h>
+#include <assert.h>
+#include <stdbool.h>
+#include "syscfg/syscfg.h"
+#if !MYNEWT_VAL(OS_SYSVIEW_TRACE_MEMPOOL)
+#define OS_TRACE_DISABLE_FILE_API
+#endif
+
+#define OS_MEM_TRUE_BLOCK_SIZE(bsize)   OS_ALIGN(bsize, OS_ALIGNMENT)
+#if MYNEWT_VAL(OS_MEMPOOL_GUARD)
+#define OS_MEMPOOL_TRUE_BLOCK_SIZE(mp)                                  \
+    (((mp)->mp_flags & OS_MEMPOOL_F_EXT) ?                              \
+     OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size) :                       \
+     (OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size) + sizeof(os_membuf_t)))
+#else
+#define OS_MEMPOOL_TRUE_BLOCK_SIZE(mp) OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size)
+#endif
+
+STAILQ_HEAD(, os_mempool) g_os_mempool_list;
+
+#if MYNEWT_VAL(OS_MEMPOOL_POISON)
+static uint32_t os_mem_poison = 0xde7ec7ed;
+
+static_assert(sizeof(struct os_memblock) % 4 == 0, "sizeof(struct os_memblock) shall be aligned to 4");
+static_assert(sizeof(os_mem_poison) == 4, "sizeof(os_mem_poison) shall be 4");
+
+static void
+os_mempool_poison(const struct os_mempool *mp, void *start)
+{
+    uint32_t *p;
+    uint32_t *end;
+    int sz;
+
+    sz = OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size);
+    p = start;
+    end = p + sz / 4;
+    p += sizeof(struct os_memblock) / 4;
+
+    while (p < end) {
+        *p = os_mem_poison;
+        p++;
+    }
+}
+
+static void
+os_mempool_poison_check(const struct os_mempool *mp, void *start)
+{
+    uint32_t *p;
+    uint32_t *end;
+    int sz;
+
+    sz = OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size);
+    p = start;
+    end = p + sz / 4;
+    p += sizeof(struct os_memblock) / 4;
+
+    while (p < end) {
+        assert(*p == os_mem_poison);
+        p++;
+    }
+}
+#else
+#define os_mempool_poison(mp, start)
+#define os_mempool_poison_check(mp, start)
+#endif
+#if MYNEWT_VAL(OS_MEMPOOL_GUARD)
+#define OS_MEMPOOL_GUARD_PATTERN 0xBAFF1ED1
+
+static void
+os_mempool_guard(const struct os_mempool *mp, void *start)
+{
+    uint32_t *tgt;
+
+    if ((mp->mp_flags & OS_MEMPOOL_F_EXT) == 0) {
+        tgt = (uint32_t *)((uintptr_t)start +
+                           OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size));
+        *tgt = OS_MEMPOOL_GUARD_PATTERN;
+    }
+}
+
+static void
+os_mempool_guard_check(const struct os_mempool *mp, void *start)
+{
+    uint32_t *tgt;
+
+    if ((mp->mp_flags & OS_MEMPOOL_F_EXT) == 0) {
+        tgt = (uint32_t *)((uintptr_t)start +
+                           OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size));
+        assert(*tgt == OS_MEMPOOL_GUARD_PATTERN);
+    }
+}
+#else
+#define os_mempool_guard(mp, start)
+#define os_mempool_guard_check(mp, start)
+#endif
+
+static os_error_t
+os_mempool_init_internal(struct os_mempool *mp, uint16_t blocks,
+                         uint32_t block_size, void *membuf, char *name,
+                         uint8_t flags)
+{
+    int true_block_size;
+    int i;
+    uint8_t *block_addr;
+    struct os_memblock *block_ptr;
+
+    /* Check for valid parameters */
+    if (!mp || (block_size == 0)) {
+        return OS_INVALID_PARM;
+    }
+
+    if ((!membuf) && (blocks != 0)) {
+        return OS_INVALID_PARM;
+    }
+
+    if (membuf != NULL) {
+        /* Blocks need to be sized properly and memory buffer should be
+         * aligned
+         */
+        if (((uint32_t)(uintptr_t)membuf & (OS_ALIGNMENT - 1)) != 0) {
+            return OS_MEM_NOT_ALIGNED;
+        }
+    }
+
+    /* Initialize the memory pool structure */
+    mp->mp_block_size = block_size;
+    mp->mp_num_free = blocks;
+    mp->mp_min_free = blocks;
+    mp->mp_flags = flags;
+    mp->mp_num_blocks = blocks;
+    mp->mp_membuf_addr = (uint32_t)(uintptr_t)membuf;
+    mp->name = name;
+    SLIST_FIRST(mp) = membuf;
+
+    if (blocks > 0) {
+        os_mempool_poison(mp, membuf);
+        os_mempool_guard(mp, membuf);
+        true_block_size = OS_MEMPOOL_TRUE_BLOCK_SIZE(mp);
+
+        /* Chain the memory blocks to the free list */
+        block_addr = (uint8_t *)membuf;
+        block_ptr = (struct os_memblock *)block_addr;
+        for (i = 1; i < blocks; i++) {
+            block_addr += true_block_size;
+            os_mempool_poison(mp, block_addr);
+            os_mempool_guard(mp, block_addr);
+            SLIST_NEXT(block_ptr, mb_next) = (struct os_memblock *)block_addr;
+            block_ptr = (struct os_memblock *)block_addr;
+        }
+
+        /* Last one in the list should be NULL */
+        SLIST_NEXT(block_ptr, mb_next) = NULL;
+    }
+
+    STAILQ_INSERT_TAIL(&g_os_mempool_list, mp, mp_list);
+
+    return OS_OK;
+}
+
+os_error_t
+os_mempool_init(struct os_mempool *mp, uint16_t blocks, uint32_t block_size,
+                void *membuf, char *name)
+{
+    return os_mempool_init_internal(mp, blocks, block_size, membuf, name, 0);
+}
+
+os_error_t
+os_mempool_ext_init(struct os_mempool_ext *mpe, uint16_t blocks,
+                    uint32_t block_size, void *membuf, char *name)
+{
+    int rc;
+
+    rc = os_mempool_init_internal(&mpe->mpe_mp, blocks, block_size, membuf,
+                                  name, OS_MEMPOOL_F_EXT);
+    if (rc != 0) {
+        return rc;
+    }
+
+    mpe->mpe_put_cb = NULL;
+    mpe->mpe_put_arg = NULL;
+
+    return 0;
+}
+
+os_error_t
+os_mempool_unregister(struct os_mempool *mp)
+{
+    struct os_mempool *prev;
+    struct os_mempool *next;
+    struct os_mempool *cur;
+
+    /* Remove the mempool from the global stailq.  This is done manually rather
+     * than with `STAILQ_REMOVE` to allow for a graceful failure if the mempool
+     * isn't found.
+     */
+
+    prev = NULL;
+    STAILQ_FOREACH(cur, &g_os_mempool_list, mp_list) {
+        if (cur == mp) {
+            break;
+        }
+        prev = cur;
+    }
+
+    if (cur == NULL) {
+        return OS_INVALID_PARM;
+    }
+
+    if (prev == NULL) {
+        STAILQ_REMOVE_HEAD(&g_os_mempool_list, mp_list);
+    } else {
+        next = STAILQ_NEXT(cur, mp_list);
+        if (next == NULL) {
+            g_os_mempool_list.stqh_last = &STAILQ_NEXT(prev, mp_list);
+        }
+
+        STAILQ_NEXT(prev, mp_list) = next;
+    }
+
+    return 0;
+}
+
+os_error_t
+os_mempool_clear(struct os_mempool *mp)
+{
+    struct os_memblock *block_ptr;
+    int true_block_size;
+    uint8_t *block_addr;
+    uint16_t blocks;
+
+    if (!mp) {
+        return OS_INVALID_PARM;
+    }
+
+    true_block_size = OS_MEMPOOL_TRUE_BLOCK_SIZE(mp);
+
+    /* cleanup the memory pool structure */
+    mp->mp_num_free = mp->mp_num_blocks;
+    mp->mp_min_free = mp->mp_num_blocks;
+    os_mempool_poison(mp, (void *)mp->mp_membuf_addr);
+    os_mempool_guard(mp, (void *)mp->mp_membuf_addr);
+    SLIST_FIRST(mp) = (void *)(uintptr_t)mp->mp_membuf_addr;
+
+    /* Chain the memory blocks to the free list */
+    block_addr = (uint8_t *)(uintptr_t)mp->mp_membuf_addr;
+    block_ptr = (struct os_memblock *)block_addr;
+    blocks = mp->mp_num_blocks;
+
+    while (blocks > 1) {
+        block_addr += true_block_size;
+        os_mempool_poison(mp, block_addr);
+        os_mempool_guard(mp, block_addr);
+        SLIST_NEXT(block_ptr, mb_next) = (struct os_memblock *)block_addr;
+        block_ptr = (struct os_memblock *)block_addr;
+        --blocks;
+    }
+
+    /* Last one in the list should be NULL */
+    SLIST_NEXT(block_ptr, mb_next) = NULL;
+
+    return OS_OK;
+}
+
+bool
+os_mempool_is_sane(const struct os_mempool *mp)
+{
+    struct os_memblock *block;
+
+    /* Verify that each block in the free list belongs to the mempool. */
+    SLIST_FOREACH(block, mp, mb_next) {
+        if (!os_memblock_from(mp, block)) {
+            return false;
+        }
+        os_mempool_poison_check(mp, block);
+        os_mempool_guard_check(mp, block);
+    }
+
+    return true;
+}
+
+int
+os_memblock_from(const struct os_mempool *mp, const void *block_addr)
+{
+    uint32_t true_block_size;
+    uintptr_t baddr32;
+    uint32_t end;
+
+    static_assert(sizeof block_addr == sizeof baddr32,
+                  "Pointer to void must be 32-bits.");
+
+    baddr32 = (uint32_t)(uintptr_t)block_addr;
+    true_block_size = OS_MEMPOOL_TRUE_BLOCK_SIZE(mp);
+    end = mp->mp_membuf_addr + (mp->mp_num_blocks * true_block_size);
+
+    /* Check that the block is in the memory buffer range. */
+    if ((baddr32 < mp->mp_membuf_addr) || (baddr32 >= end)) {
+        return 0;
+    }
+
+    /* All freed blocks should be on true block size boundaries! */
+    if (((baddr32 - mp->mp_membuf_addr) % true_block_size) != 0) {
+        return 0;
+    }
+
+    return 1;
+}
+
+void *
+os_memblock_get(struct os_mempool *mp)
+{
+    os_sr_t sr;
+    struct os_memblock *block;
+
+    os_trace_api_u32(OS_TRACE_ID_MEMBLOCK_GET, (uint32_t)(uintptr_t)mp);
+
+    /* Check to make sure they passed in a memory pool (or something) */
+    block = NULL;
+    if (mp) {
+        OS_ENTER_CRITICAL(sr);
+        /* Check for any free */
+        if (mp->mp_num_free) {
+            /* Get a free block */
+            block = SLIST_FIRST(mp);
+
+            /* Set new free list head */
+            SLIST_FIRST(mp) = SLIST_NEXT(block, mb_next);
+
+            /* Decrement number free by 1 */
+            mp->mp_num_free--;
+            if (mp->mp_min_free > mp->mp_num_free) {
+                mp->mp_min_free = mp->mp_num_free;
+            }
+        }
+        OS_EXIT_CRITICAL(sr);
+
+        if (block) {
+            os_mempool_poison_check(mp, block);
+            os_mempool_guard_check(mp, block);
+        }
+    }
+
+    os_trace_api_ret_u32(OS_TRACE_ID_MEMBLOCK_GET, (uint32_t)(uintptr_t)block);
+
+    return (void *)block;
+}
+
+os_error_t
+os_memblock_put_from_cb(struct os_mempool *mp, void *block_addr)
+{
+    os_sr_t sr;
+    struct os_memblock *block;
+
+    os_trace_api_u32x2(OS_TRACE_ID_MEMBLOCK_PUT_FROM_CB, (uint32_t)(uintptr_t)mp,
+                       (uint32_t)(uintptr_t)block_addr);
+
+    os_mempool_guard_check(mp, block_addr);
+    os_mempool_poison(mp, block_addr);
+
+    block = (struct os_memblock *)block_addr;
+    OS_ENTER_CRITICAL(sr);
+
+    /* Chain current free list pointer to this block; make this block head */
+    SLIST_NEXT(block, mb_next) = SLIST_FIRST(mp);
+    SLIST_FIRST(mp) = block;
+
+    /* XXX: Should we check that the number free <= number blocks? */
+    /* Increment number free */
+    mp->mp_num_free++;
+
+    OS_EXIT_CRITICAL(sr);
+
+    os_trace_api_ret_u32(OS_TRACE_ID_MEMBLOCK_PUT_FROM_CB, (uint32_t)OS_OK);
+
+    return OS_OK;
+}
+
+os_error_t
+os_memblock_put(struct os_mempool *mp, void *block_addr)
+{
+    struct os_mempool_ext *mpe;
+    os_error_t ret;
+#if MYNEWT_VAL(OS_MEMPOOL_CHECK)
+    struct os_memblock *block;
+#endif
+
+    os_trace_api_u32x2(OS_TRACE_ID_MEMBLOCK_PUT, (uint32_t)(uintptr_t)mp,
+                       (uint32_t)(uintptr_t)block_addr);
+
+    /* Make sure parameters are valid */
+    if ((mp == NULL) || (block_addr == NULL)) {
+        ret = OS_INVALID_PARM;
+        goto done;
+    }
+
+#if MYNEWT_VAL(OS_MEMPOOL_CHECK)
+    /* Check that the block we are freeing is a valid block! */
+    assert(os_memblock_from(mp, block_addr));
+
+    /*
+     * Check for duplicate free.
+     */
+    SLIST_FOREACH(block, mp, mb_next) {
+        assert(block != (struct os_memblock *)block_addr);
+    }
+#endif
+    /* If this is an extended mempool with a put callback, call the callback
+     * instead of freeing the block directly.
+     */
+    if (mp->mp_flags & OS_MEMPOOL_F_EXT) {
+        mpe = (struct os_mempool_ext *)mp;
+        if (mpe->mpe_put_cb != NULL) {
+            ret = mpe->mpe_put_cb(mpe, block_addr, mpe->mpe_put_arg);
+            goto done;
+        }
+    }
+
+    /* No callback; free the block. */
+    ret = os_memblock_put_from_cb(mp, block_addr);
+
+done:
+    os_trace_api_ret_u32(OS_TRACE_ID_MEMBLOCK_PUT, (uint32_t)ret);
+    return ret;
+}
+
+struct os_mempool *
+os_mempool_info_get_next(struct os_mempool *mp, struct os_mempool_info *omi)
+{
+    struct os_mempool *cur;
+
+    if (mp == NULL) {
+        cur = STAILQ_FIRST(&g_os_mempool_list);
+    } else {
+        cur = STAILQ_NEXT(mp, mp_list);
+    }
+
+    if (cur == NULL) {
+        return (NULL);
+    }
+
+    omi->omi_block_size = cur->mp_block_size;
+    omi->omi_num_blocks = cur->mp_num_blocks;
+    omi->omi_num_free = cur->mp_num_free;
+    omi->omi_min_free = cur->mp_min_free;
+    omi->omi_name[0] = '\0';
+    strncat(omi->omi_name, cur->name, sizeof(omi->omi_name) - 1);
+
+    return (cur);
+}
+
+void
+os_mempool_module_init(void)
+{
+    STAILQ_INIT(&g_os_mempool_list);
+}

+ 156 - 0
third_party/nimble-1.6.0/porting/nimble/src/os_msys_init.c

@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include "os/os.h"
+#include "mem/mem.h"
+#include "sysinit/sysinit.h"
+
+static STAILQ_HEAD(, os_mbuf_pool) g_msys_pool_list =
+    STAILQ_HEAD_INITIALIZER(g_msys_pool_list);
+
+#if MYNEWT_VAL(MSYS_1_BLOCK_COUNT) > 0
+#define SYSINIT_MSYS_1_MEMBLOCK_SIZE                \
+    OS_ALIGN(MYNEWT_VAL(MSYS_1_BLOCK_SIZE), 4)
+#define SYSINIT_MSYS_1_MEMPOOL_SIZE                 \
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(MSYS_1_BLOCK_COUNT),  \
+                    SYSINIT_MSYS_1_MEMBLOCK_SIZE)
+static os_membuf_t os_msys_1_data[SYSINIT_MSYS_1_MEMPOOL_SIZE];
+static struct os_mbuf_pool os_msys_1_mbuf_pool;
+static struct os_mempool os_msys_1_mempool;
+#endif
+
+#if MYNEWT_VAL(MSYS_2_BLOCK_COUNT) > 0
+#define SYSINIT_MSYS_2_MEMBLOCK_SIZE                \
+    OS_ALIGN(MYNEWT_VAL(MSYS_2_BLOCK_SIZE), 4)
+#define SYSINIT_MSYS_2_MEMPOOL_SIZE                 \
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(MSYS_2_BLOCK_COUNT),  \
+                    SYSINIT_MSYS_2_MEMBLOCK_SIZE)
+static os_membuf_t os_msys_2_data[SYSINIT_MSYS_2_MEMPOOL_SIZE];
+static struct os_mbuf_pool os_msys_2_mbuf_pool;
+static struct os_mempool os_msys_2_mempool;
+#endif
+
+#define OS_MSYS_SANITY_ENABLED                  \
+    (MYNEWT_VAL(MSYS_1_SANITY_MIN_COUNT) > 0 || \
+     MYNEWT_VAL(MSYS_2_SANITY_MIN_COUNT) > 0)
+
+#if OS_MSYS_SANITY_ENABLED
+static struct os_sanity_check os_msys_sc;
+#endif
+
+#if OS_MSYS_SANITY_ENABLED
+
+/**
+ * Retrieves the minimum safe buffer count for an msys pool.  That is, the
+ * lowest a pool's buffer count can be without causing the sanity check to
+ * fail.
+ *
+ * @param idx                   The index of the msys pool to query.
+ *
+ * @return                      The msys pool's minimum safe buffer count.
+ */
+static int
+os_msys_sanity_min_count(int idx)
+{
+    switch (idx) {
+    case 0:
+        return MYNEWT_VAL(MSYS_1_SANITY_MIN_COUNT);
+
+    case 1:
+        return MYNEWT_VAL(MSYS_2_SANITY_MIN_COUNT);
+
+    default:
+        assert(0);
+        return 0;
+    }
+}
+
+static int
+os_msys_sanity(struct os_sanity_check *sc, void *arg)
+{
+    const struct os_mbuf_pool *omp;
+    int min_count;
+    int idx;
+
+    idx = 0;
+    STAILQ_FOREACH(omp, &g_msys_pool_list, omp_next) {
+        min_count = os_msys_sanity_min_count(idx);
+        if (omp->omp_pool->mp_num_free < min_count) {
+            return OS_ENOMEM;
+        }
+
+        idx++;
+    }
+
+    return 0;
+}
+#endif
+
+static void
+os_msys_init_once(void *data, struct os_mempool *mempool,
+                  struct os_mbuf_pool *mbuf_pool,
+                  int block_count, int block_size, char *name)
+{
+    int rc;
+
+    rc = mem_init_mbuf_pool(data, mempool, mbuf_pool, block_count, block_size,
+                            name);
+    SYSINIT_PANIC_ASSERT(rc == 0);
+
+    rc = os_msys_register(mbuf_pool);
+    SYSINIT_PANIC_ASSERT(rc == 0);
+}
+
+void
+os_msys_init(void)
+{
+    int rc;
+
+    os_msys_reset();
+
+    (void)os_msys_init_once;
+    (void)rc;
+
+#if MYNEWT_VAL(MSYS_1_BLOCK_COUNT) > 0
+    os_msys_init_once(os_msys_1_data,
+                      &os_msys_1_mempool,
+                      &os_msys_1_mbuf_pool,
+                      MYNEWT_VAL(MSYS_1_BLOCK_COUNT),
+                      SYSINIT_MSYS_1_MEMBLOCK_SIZE,
+                      "msys_1");
+#endif
+
+#if MYNEWT_VAL(MSYS_2_BLOCK_COUNT) > 0
+    os_msys_init_once(os_msys_2_data,
+                      &os_msys_2_mempool,
+                      &os_msys_2_mbuf_pool,
+                      MYNEWT_VAL(MSYS_2_BLOCK_COUNT),
+                      SYSINIT_MSYS_2_MEMBLOCK_SIZE,
+                      "msys_2");
+#endif
+
+#if OS_MSYS_SANITY_ENABLED
+    os_msys_sc.sc_func = os_msys_sanity;
+    os_msys_sc.sc_checkin_itvl =
+        OS_TICKS_PER_SEC * MYNEWT_VAL(MSYS_SANITY_TIMEOUT) / 1000;
+    rc = os_sanity_check_register(&os_msys_sc);
+    SYSINIT_PANIC_ASSERT(rc == 0);
+#endif
+}

+ 14 - 0
third_party/nimble-1.6.0/porting/npl/freertos/include/console/console.h

@@ -0,0 +1,14 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _CONSOLE_H
+#define _CONSOLE_H
+
+#include <stdio.h>
+
+#define console_printf printf
+
+#endif

+ 300 - 0
third_party/nimble-1.6.0/porting/npl/freertos/include/nimble/nimble_npl_os.h

@@ -0,0 +1,300 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _NIMBLE_NPL_OS_H_
+#define _NIMBLE_NPL_OS_H_
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+#include "FreeRTOS.h"
+#include "queue.h"
+#include "semphr.h"
+#include "task.h"
+#include "timers.h"
+#include "syscfg/syscfg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BLE_NPL_OS_ALIGNMENT    4
+
+#define BLE_NPL_TIME_FOREVER    portMAX_DELAY
+
+/* This should be compatible with TickType_t */
+typedef uint32_t ble_npl_time_t;
+typedef int32_t ble_npl_stime_t;
+
+struct ble_npl_event {
+    bool queued;
+    ble_npl_event_fn *fn;
+    void *arg;
+};
+
+struct ble_npl_eventq {
+    QueueHandle_t q;
+};
+
+struct ble_npl_callout {
+    TimerHandle_t handle;
+    struct ble_npl_eventq *evq;
+    struct ble_npl_event ev;
+};
+
+struct ble_npl_mutex {
+    SemaphoreHandle_t handle;
+};
+
+struct ble_npl_sem {
+    SemaphoreHandle_t handle;
+};
+
+/*
+ * Simple APIs are just defined as static inline below, but some are a bit more
+ * complex or require some global state variables and thus are defined in .c
+ * file instead and static inline wrapper just calls proper implementation.
+ * We need declarations of these functions and they are defined in header below.
+ */
+#include "npl_freertos.h"
+
+static inline bool
+ble_npl_os_started(void)
+{
+    return xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED;
+}
+
+static inline void *
+ble_npl_get_current_task_id(void)
+{
+    return xTaskGetCurrentTaskHandle();
+}
+
+static inline void
+ble_npl_eventq_init(struct ble_npl_eventq *evq)
+{
+    evq->q = xQueueCreate(32, sizeof(struct ble_npl_eventq *));
+}
+
+static inline struct ble_npl_event *
+ble_npl_eventq_get(struct ble_npl_eventq *evq, ble_npl_time_t tmo)
+{
+    return npl_freertos_eventq_get(evq, tmo);
+}
+
+static inline void
+ble_npl_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_event *ev)
+{
+    npl_freertos_eventq_put(evq, ev);
+}
+
+static inline void
+ble_npl_eventq_remove(struct ble_npl_eventq *evq, struct ble_npl_event *ev)
+{
+    npl_freertos_eventq_remove(evq, ev);
+}
+
+static inline void
+ble_npl_event_run(struct ble_npl_event *ev)
+{
+    ev->fn(ev);
+}
+
+static inline bool
+ble_npl_eventq_is_empty(struct ble_npl_eventq *evq)
+{
+    return xQueueIsQueueEmptyFromISR(evq->q);
+}
+
+static inline void
+ble_npl_event_init(struct ble_npl_event *ev, ble_npl_event_fn *fn,
+                   void *arg)
+{
+    memset(ev, 0, sizeof(*ev));
+    ev->fn = fn;
+    ev->arg = arg;
+}
+
+static inline bool
+ble_npl_event_is_queued(struct ble_npl_event *ev)
+{
+    return ev->queued;
+}
+
+static inline void *
+ble_npl_event_get_arg(struct ble_npl_event *ev)
+{
+    return ev->arg;
+}
+
+static inline void
+ble_npl_event_set_arg(struct ble_npl_event *ev, void *arg)
+{
+    ev->arg = arg;
+}
+
+static inline ble_npl_error_t
+ble_npl_mutex_init(struct ble_npl_mutex *mu)
+{
+    return npl_freertos_mutex_init(mu);
+}
+
+static inline ble_npl_error_t
+ble_npl_mutex_pend(struct ble_npl_mutex *mu, ble_npl_time_t timeout)
+{
+    return npl_freertos_mutex_pend(mu, timeout);
+}
+
+static inline ble_npl_error_t
+ble_npl_mutex_release(struct ble_npl_mutex *mu)
+{
+    return npl_freertos_mutex_release(mu);
+}
+
+static inline ble_npl_error_t
+ble_npl_sem_init(struct ble_npl_sem *sem, uint16_t tokens)
+{
+    return npl_freertos_sem_init(sem, tokens);
+}
+
+static inline ble_npl_error_t
+ble_npl_sem_pend(struct ble_npl_sem *sem, ble_npl_time_t timeout)
+{
+    return npl_freertos_sem_pend(sem, timeout);
+}
+
+static inline ble_npl_error_t
+ble_npl_sem_release(struct ble_npl_sem *sem)
+{
+    return npl_freertos_sem_release(sem);
+}
+
+static inline uint16_t
+ble_npl_sem_get_count(struct ble_npl_sem *sem)
+{
+    return uxSemaphoreGetCount(sem->handle);
+}
+
+static inline void
+ble_npl_callout_init(struct ble_npl_callout *co, struct ble_npl_eventq *evq,
+                     ble_npl_event_fn *ev_cb, void *ev_arg)
+{
+    npl_freertos_callout_init(co, evq, ev_cb, ev_arg);
+}
+
+static inline ble_npl_error_t
+ble_npl_callout_reset(struct ble_npl_callout *co, ble_npl_time_t ticks)
+{
+    return npl_freertos_callout_reset(co, ticks);
+}
+
+static inline void
+ble_npl_callout_stop(struct ble_npl_callout *co)
+{
+    xTimerStop(co->handle, portMAX_DELAY);
+}
+
+static inline bool
+ble_npl_callout_is_active(struct ble_npl_callout *co)
+{
+    return xTimerIsTimerActive(co->handle) == pdTRUE;
+}
+
+static inline ble_npl_time_t
+ble_npl_callout_get_ticks(struct ble_npl_callout *co)
+{
+    return xTimerGetExpiryTime(co->handle);
+}
+
+static inline uint32_t
+ble_npl_callout_remaining_ticks(struct ble_npl_callout *co,
+                                ble_npl_time_t time)
+{
+    return npl_freertos_callout_remaining_ticks(co, time);
+}
+
+static inline void
+ble_npl_callout_set_arg(struct ble_npl_callout *co, void *arg)
+{
+    co->ev.arg = arg;
+}
+
+static inline uint32_t
+ble_npl_time_get(void)
+{
+    return xTaskGetTickCountFromISR();
+}
+
+static inline ble_npl_error_t
+ble_npl_time_ms_to_ticks(uint32_t ms, ble_npl_time_t *out_ticks)
+{
+    return npl_freertos_time_ms_to_ticks(ms, out_ticks);
+}
+
+static inline ble_npl_error_t
+ble_npl_time_ticks_to_ms(ble_npl_time_t ticks, uint32_t *out_ms)
+{
+    return ble_npl_time_ticks_to_ms(ticks, out_ms);
+}
+
+static inline ble_npl_time_t
+ble_npl_time_ms_to_ticks32(uint32_t ms)
+{
+    return ms * configTICK_RATE_HZ / 1000;
+}
+
+static inline uint32_t
+ble_npl_time_ticks_to_ms32(ble_npl_time_t ticks)
+{
+    return ticks * 1000 / configTICK_RATE_HZ;
+}
+
+static inline void
+ble_npl_time_delay(ble_npl_time_t ticks)
+{
+    vTaskDelay(ticks);
+}
+
+#if NIMBLE_CFG_CONTROLLER
+static inline void
+ble_npl_hw_set_isr(int irqn, void (*addr)(void))
+{
+    npl_freertos_hw_set_isr(irqn, addr);
+}
+#endif
+
+static inline uint32_t
+ble_npl_hw_enter_critical(void)
+{
+    vTaskEnterCritical();
+    return 0;
+}
+
+static inline void
+ble_npl_hw_exit_critical(uint32_t ctx)
+{
+    vTaskExitCritical();
+
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _NPL_H_ */

+ 35 - 0
third_party/nimble-1.6.0/porting/npl/freertos/include/nimble/nimble_npl_os_log.h

@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _NIMBLE_NPL_OS_LOG_H_
+#define _NIMBLE_NPL_OS_LOG_H_
+
+#include <stdio.h>
+
+#define BLE_HS_LOG_DEBUG(...) printf(__VA_ARGS__)
+#define BLE_HS_LOG_INFO(...) printf(__VA_ARGS__)
+#define BLE_HS_LOG_WARN(...) printf(__VA_ARGS__)
+#define BLE_HS_LOG_ERROR(...) printf(__VA_ARGS__)
+#define BLE_HS_LOG_CRITICAL(...) printf(__VA_ARGS__)
+#define BLE_HS_LOG_DISABLED(...) printf(__VA_ARGS__)
+
+#define BLE_EATT_LOG_DEBUG(...) printf(__VA_ARGS__)
+#define BLE_EATT_LOG_ERROR(...) printf(__VA_ARGS__)
+
+#endif  /* _NIMBLE_NPL_OS_LOG_H_ */

+ 35 - 0
third_party/nimble-1.6.0/porting/npl/freertos/include/nimble/nimble_port_freertos.h

@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _NIMBLE_PORT_FREERTOS_H
+#define _NIMBLE_PORT_FREERTOS_H
+
+#include "nimble/nimble_npl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void nimble_port_freertos_init(TaskFunction_t host_task_fn);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NIMBLE_PORT_FREERTOS_H */

+ 76 - 0
third_party/nimble-1.6.0/porting/npl/freertos/include/nimble/npl_freertos.h

@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _NPL_FREERTOS_H_
+#define _NPL_FREERTOS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ble_npl_event *npl_freertos_eventq_get(struct ble_npl_eventq *evq,
+                                              ble_npl_time_t tmo);
+
+void npl_freertos_eventq_put(struct ble_npl_eventq *evq,
+                             struct ble_npl_event *ev);
+
+void npl_freertos_eventq_remove(struct ble_npl_eventq *evq,
+                                struct ble_npl_event *ev);
+
+ble_npl_error_t npl_freertos_mutex_init(struct ble_npl_mutex *mu);
+
+ble_npl_error_t npl_freertos_mutex_pend(struct ble_npl_mutex *mu,
+                                        ble_npl_time_t timeout);
+
+ble_npl_error_t npl_freertos_mutex_release(struct ble_npl_mutex *mu);
+
+ble_npl_error_t npl_freertos_sem_init(struct ble_npl_sem *sem, uint16_t tokens);
+
+ble_npl_error_t npl_freertos_sem_pend(struct ble_npl_sem *sem,
+                                      ble_npl_time_t timeout);
+
+ble_npl_error_t npl_freertos_sem_release(struct ble_npl_sem *sem);
+
+void npl_freertos_callout_init(struct ble_npl_callout *co,
+                               struct ble_npl_eventq *evq,
+                               ble_npl_event_fn *ev_cb, void *ev_arg);
+
+ble_npl_error_t npl_freertos_callout_reset(struct ble_npl_callout *co,
+                                           ble_npl_time_t ticks);
+
+ble_npl_time_t npl_freertos_callout_remaining_ticks(struct ble_npl_callout *co,
+						    ble_npl_time_t now);
+
+ble_npl_error_t npl_freertos_time_ms_to_ticks(uint32_t ms,
+                                              ble_npl_time_t *out_ticks);
+
+ble_npl_error_t npl_freertos_time_ticks_to_ms(ble_npl_time_t ticks,
+                                              uint32_t *out_ms);
+
+void npl_freertos_hw_set_isr(int irqn, void (*addr)(void));
+
+uint32_t npl_freertos_hw_enter_critical(void);
+
+void npl_freertos_hw_exit_critical(uint32_t ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _NPL_FREERTOS_H_ */

+ 1344 - 0
third_party/nimble-1.6.0/porting/npl/freertos/include/syscfg/syscfg.h

@@ -0,0 +1,1344 @@
+/**
+ * This file was generated by Apache newt version: 1.12.0-dev
+ */
+
+#ifndef H_MYNEWT_SYSCFG_
+#define H_MYNEWT_SYSCFG_
+
+/**
+ * This macro exists to ensure code includes this header when needed.  If code
+ * checks the existence of a setting directly via ifdef without including this
+ * header, the setting macro will silently evaluate to 0.  In contrast, an
+ * attempt to use these macros without including this header will result in a
+ * compiler error.
+ */
+#define MYNEWT_VAL(_name)                       MYNEWT_VAL_ ## _name
+#define MYNEWT_VAL_CHOICE(_name, _val)          MYNEWT_VAL_ ## _name ## __ ## _val
+
+#ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE
+#define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200)
+#endif
+
+#ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME
+#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME "trng"
+#endif
+
+#ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG
+#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG (0)
+#endif
+
+/*** @apache-mynewt-core/hw/bsp/native */
+#ifndef MYNEWT_VAL_BSP_SIMULATED
+#define MYNEWT_VAL_BSP_SIMULATED (1)
+#endif
+
+/*** @apache-mynewt-core/hw/hal */
+#ifndef MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS
+#define MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS (1)
+#endif
+
+#ifndef MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT
+#define MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT (0)
+#endif
+
+#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ
+#define MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ (16)
+#endif
+
+#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_ERASES
+#define MYNEWT_VAL_HAL_FLASH_VERIFY_ERASES (0)
+#endif
+
+#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES
+#define MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES (0)
+#endif
+
+#ifndef MYNEWT_VAL_HAL_SBRK
+#define MYNEWT_VAL_HAL_SBRK (1)
+#endif
+
+#ifndef MYNEWT_VAL_HAL_SYSTEM_RESET_CB
+#define MYNEWT_VAL_HAL_SYSTEM_RESET_CB (0)
+#endif
+
+/*** @apache-mynewt-core/hw/mcu/native */
+#ifndef MYNEWT_VAL_I2C_0
+#define MYNEWT_VAL_I2C_0 (0)
+#endif
+
+#ifndef MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE
+#define MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE (1)
+#endif
+
+#ifndef MYNEWT_VAL_MCU_FLASH_STYLE_NORDIC
+#define MYNEWT_VAL_MCU_FLASH_STYLE_NORDIC (0)
+#endif
+
+#ifndef MYNEWT_VAL_MCU_FLASH_STYLE_ST
+#define MYNEWT_VAL_MCU_FLASH_STYLE_ST (1)
+#endif
+
+#ifndef MYNEWT_VAL_MCU_NATIVE
+#define MYNEWT_VAL_MCU_NATIVE (1)
+#endif
+
+#ifndef MYNEWT_VAL_MCU_NATIVE_USE_SIGNALS
+#define MYNEWT_VAL_MCU_NATIVE_USE_SIGNALS (1)
+#endif
+
+#ifndef MYNEWT_VAL_MCU_TIMER_POLLER_PRIO
+#define MYNEWT_VAL_MCU_TIMER_POLLER_PRIO (0)
+#endif
+
+#ifndef MYNEWT_VAL_MCU_UART_POLLER_PRIO
+#define MYNEWT_VAL_MCU_UART_POLLER_PRIO (1)
+#endif
+
+/*** @apache-mynewt-core/kernel/os */
+#ifndef MYNEWT_VAL_FLOAT_USER
+#define MYNEWT_VAL_FLOAT_USER (0)
+#endif
+
+#ifndef MYNEWT_VAL_MSYS_1_BLOCK_COUNT
+#define MYNEWT_VAL_MSYS_1_BLOCK_COUNT (12)
+#endif
+
+#ifndef MYNEWT_VAL_MSYS_1_BLOCK_SIZE
+#define MYNEWT_VAL_MSYS_1_BLOCK_SIZE (292)
+#endif
+
+#ifndef MYNEWT_VAL_MSYS_1_SANITY_MIN_COUNT
+#define MYNEWT_VAL_MSYS_1_SANITY_MIN_COUNT (0)
+#endif
+
+#ifndef MYNEWT_VAL_MSYS_2_BLOCK_COUNT
+#define MYNEWT_VAL_MSYS_2_BLOCK_COUNT (0)
+#endif
+
+#ifndef MYNEWT_VAL_MSYS_2_BLOCK_SIZE
+#define MYNEWT_VAL_MSYS_2_BLOCK_SIZE (0)
+#endif
+
+#ifndef MYNEWT_VAL_MSYS_2_SANITY_MIN_COUNT
+#define MYNEWT_VAL_MSYS_2_SANITY_MIN_COUNT (0)
+#endif
+
+#ifndef MYNEWT_VAL_MSYS_SANITY_TIMEOUT
+#define MYNEWT_VAL_MSYS_SANITY_TIMEOUT (60000)
+#endif
+
+#ifndef MYNEWT_VAL_OS_ASSERT_CB
+#define MYNEWT_VAL_OS_ASSERT_CB (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_CLI
+#define MYNEWT_VAL_OS_CLI (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_COREDUMP
+#define MYNEWT_VAL_OS_COREDUMP (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_COREDUMP_CB
+#define MYNEWT_VAL_OS_COREDUMP_CB (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_CPUTIME_FREQ
+#define MYNEWT_VAL_OS_CPUTIME_FREQ (1000000)
+#endif
+
+#ifndef MYNEWT_VAL_OS_CPUTIME_TIMER_NUM
+#define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (0)
+#endif
+
+/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */
+#ifndef MYNEWT_VAL_OS_CRASH_FILE_LINE
+#define MYNEWT_VAL_OS_CRASH_FILE_LINE (1)
+#endif
+
+#ifndef MYNEWT_VAL_OS_CRASH_LOG
+#define MYNEWT_VAL_OS_CRASH_LOG (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_CRASH_RESTORE_REGS
+#define MYNEWT_VAL_OS_CRASH_RESTORE_REGS (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_CRASH_STACKTRACE
+#define MYNEWT_VAL_OS_CRASH_STACKTRACE (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_CTX_SW_STACK_CHECK
+#define MYNEWT_VAL_OS_CTX_SW_STACK_CHECK (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_CTX_SW_STACK_GUARD
+#define MYNEWT_VAL_OS_CTX_SW_STACK_GUARD (4)
+#endif
+
+#ifndef MYNEWT_VAL_OS_DEBUG_MODE
+#define MYNEWT_VAL_OS_DEBUG_MODE (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_EVENTQ_DEBUG
+#define MYNEWT_VAL_OS_EVENTQ_DEBUG (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_EVENTQ_MONITOR
+#define MYNEWT_VAL_OS_EVENTQ_MONITOR (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX
+#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX (600000)
+#endif
+
+/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */
+#ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN
+#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (1)
+#endif
+
+#ifndef MYNEWT_VAL_OS_MAIN_STACK_SIZE
+#define MYNEWT_VAL_OS_MAIN_STACK_SIZE (1024)
+#endif
+
+#ifndef MYNEWT_VAL_OS_MAIN_TASK_PRIO
+#define MYNEWT_VAL_OS_MAIN_TASK_PRIO (127)
+#endif
+
+#ifndef MYNEWT_VAL_OS_MAIN_TASK_SANITY_ITVL_MS
+#define MYNEWT_VAL_OS_MAIN_TASK_SANITY_ITVL_MS (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_MEMPOOL_CHECK
+#define MYNEWT_VAL_OS_MEMPOOL_CHECK (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_MEMPOOL_GUARD
+#define MYNEWT_VAL_OS_MEMPOOL_GUARD (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_MEMPOOL_POISON
+#define MYNEWT_VAL_OS_MEMPOOL_POISON (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_SCHEDULING
+#define MYNEWT_VAL_OS_SCHEDULING (1)
+#endif
+
+#ifndef MYNEWT_VAL_OS_SYSINIT_STAGE
+#define MYNEWT_VAL_OS_SYSINIT_STAGE (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_SYSVIEW
+#define MYNEWT_VAL_OS_SYSVIEW (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_CALLOUT
+#define MYNEWT_VAL_OS_SYSVIEW_TRACE_CALLOUT (1)
+#endif
+
+#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_EVENTQ
+#define MYNEWT_VAL_OS_SYSVIEW_TRACE_EVENTQ (1)
+#endif
+
+#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_MBUF
+#define MYNEWT_VAL_OS_SYSVIEW_TRACE_MBUF (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_MEMPOOL
+#define MYNEWT_VAL_OS_SYSVIEW_TRACE_MEMPOOL (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_MUTEX
+#define MYNEWT_VAL_OS_SYSVIEW_TRACE_MUTEX (1)
+#endif
+
+#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_SEM
+#define MYNEWT_VAL_OS_SYSVIEW_TRACE_SEM (1)
+#endif
+
+#ifndef MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME
+#define MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME (0)
+#endif
+
+/* Overridden by @apache-mynewt-core/hw/mcu/native (defined by @apache-mynewt-core/kernel/os) */
+#ifndef MYNEWT_VAL_OS_TICKS_PER_SEC
+#define MYNEWT_VAL_OS_TICKS_PER_SEC (100)
+#endif
+
+#ifndef MYNEWT_VAL_OS_TIME_DEBUG
+#define MYNEWT_VAL_OS_TIME_DEBUG (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_WATCHDOG_MONITOR
+#define MYNEWT_VAL_OS_WATCHDOG_MONITOR (0)
+#endif
+
+#ifndef MYNEWT_VAL_SANITY_INTERVAL
+#define MYNEWT_VAL_SANITY_INTERVAL (15000)
+#endif
+
+#ifndef MYNEWT_VAL_WATCHDOG_INTERVAL
+#define MYNEWT_VAL_WATCHDOG_INTERVAL (30000)
+#endif
+
+/*** @apache-mynewt-core/net/ip/native_sockets */
+#ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX
+#define MYNEWT_VAL_NATIVE_SOCKETS_MAX (8)
+#endif
+
+#ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX_UDP
+#define MYNEWT_VAL_NATIVE_SOCKETS_MAX_UDP (2048)
+#endif
+
+#ifndef MYNEWT_VAL_NATIVE_SOCKETS_POLL_INTERVAL_MS
+#define MYNEWT_VAL_NATIVE_SOCKETS_POLL_INTERVAL_MS (200)
+#endif
+
+#undef MYNEWT_VAL_NATIVE_SOCKETS_POLL_ITVL
+
+#ifndef MYNEWT_VAL_NATIVE_SOCKETS_PRIO
+#define MYNEWT_VAL_NATIVE_SOCKETS_PRIO (2)
+#endif
+
+#ifndef MYNEWT_VAL_NATIVE_SOCKETS_STACK_SZ
+#define MYNEWT_VAL_NATIVE_SOCKETS_STACK_SZ (4096)
+#endif
+
+#ifndef MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE
+#define MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE (200)
+#endif
+
+/*** @apache-mynewt-core/sys/console/stub */
+#ifndef MYNEWT_VAL_CONSOLE_UART_BAUD
+#define MYNEWT_VAL_CONSOLE_UART_BAUD (115200)
+#endif
+
+#ifndef MYNEWT_VAL_CONSOLE_UART_DEV
+#define MYNEWT_VAL_CONSOLE_UART_DEV "uart0"
+#endif
+
+#ifndef MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL
+#define MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL (UART_FLOW_CTL_NONE)
+#endif
+
+/*** @apache-mynewt-core/sys/flash_map */
+#ifndef MYNEWT_VAL_FLASH_MAP_MAX_AREAS
+#define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10)
+#endif
+
+#ifndef MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG
+#define MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG (0)
+#endif
+
+#ifndef MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE
+#define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (9)
+#endif
+
+/*** @apache-mynewt-core/sys/log/common */
+#ifndef MYNEWT_VAL_DFLT_LOG_LVL
+#define MYNEWT_VAL_DFLT_LOG_LVL (1)
+#endif
+
+#ifndef MYNEWT_VAL_DFLT_LOG_MOD
+#define MYNEWT_VAL_DFLT_LOG_MOD (0)
+#endif
+
+#ifndef MYNEWT_VAL_LOG_GLOBAL_IDX
+#define MYNEWT_VAL_LOG_GLOBAL_IDX (1)
+#endif
+
+/*** @apache-mynewt-core/sys/log/modlog */
+#ifndef MYNEWT_VAL_MODLOG_CONSOLE_DFLT
+#define MYNEWT_VAL_MODLOG_CONSOLE_DFLT (1)
+#endif
+
+#ifndef MYNEWT_VAL_MODLOG_LOG_MACROS
+#define MYNEWT_VAL_MODLOG_LOG_MACROS (0)
+#endif
+
+#ifndef MYNEWT_VAL_MODLOG_MAX_MAPPINGS
+#define MYNEWT_VAL_MODLOG_MAX_MAPPINGS (16)
+#endif
+
+#ifndef MYNEWT_VAL_MODLOG_MAX_PRINTF_LEN
+#define MYNEWT_VAL_MODLOG_MAX_PRINTF_LEN (128)
+#endif
+
+#ifndef MYNEWT_VAL_MODLOG_SYSINIT_STAGE
+#define MYNEWT_VAL_MODLOG_SYSINIT_STAGE (100)
+#endif
+
+/*** @apache-mynewt-core/sys/log/stub */
+#ifndef MYNEWT_VAL_LOG_CONSOLE
+#define MYNEWT_VAL_LOG_CONSOLE (1)
+#endif
+
+#ifndef MYNEWT_VAL_LOG_FCB
+#define MYNEWT_VAL_LOG_FCB (0)
+#endif
+
+#ifndef MYNEWT_VAL_LOG_FCB_SLOT1
+#define MYNEWT_VAL_LOG_FCB_SLOT1 (0)
+#endif
+
+#ifndef MYNEWT_VAL_LOG_LEVEL
+#define MYNEWT_VAL_LOG_LEVEL (255)
+#endif
+
+/*** @apache-mynewt-core/sys/sys */
+#ifndef MYNEWT_VAL_DEBUG_PANIC_ENABLED
+#define MYNEWT_VAL_DEBUG_PANIC_ENABLED (1)
+#endif
+
+/*** @apache-mynewt-core/sys/sysdown */
+#ifndef MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN
+#define MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN (1)
+#endif
+
+#ifndef MYNEWT_VAL_SYSDOWN_PANIC_FILE_LINE
+#define MYNEWT_VAL_SYSDOWN_PANIC_FILE_LINE (0)
+#endif
+
+#ifndef MYNEWT_VAL_SYSDOWN_PANIC_MESSAGE
+#define MYNEWT_VAL_SYSDOWN_PANIC_MESSAGE (0)
+#endif
+
+#ifndef MYNEWT_VAL_SYSDOWN_TIMEOUT_MS
+#define MYNEWT_VAL_SYSDOWN_TIMEOUT_MS (10000)
+#endif
+
+/*** @apache-mynewt-core/sys/sysinit */
+#ifndef MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT
+#define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1)
+#endif
+
+/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */
+#ifndef MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE
+#define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (1)
+#endif
+
+/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */
+#ifndef MYNEWT_VAL_SYSINIT_PANIC_MESSAGE
+#define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (1)
+#endif
+
+/*** @apache-mynewt-core/util/rwlock */
+#ifndef MYNEWT_VAL_RWLOCK_DEBUG
+#define MYNEWT_VAL_RWLOCK_DEBUG (0)
+#endif
+
+/*** @apache-mynewt-nimble/nimble */
+#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING
+#define MYNEWT_VAL_BLE_CONN_SUBRATING (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_EXT_ADV
+#define MYNEWT_VAL_BLE_EXT_ADV (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE
+#define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (31)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HCI_VS
+#define MYNEWT_VAL_BLE_HCI_VS (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET
+#define MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ISO
+#define MYNEWT_VAL_BLE_ISO (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ISO_BROADCASTER
+#define MYNEWT_VAL_BLE_ISO_BROADCASTER (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ISO_TEST
+#define MYNEWT_VAL_BLE_ISO_TEST (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MAX_CONNECTIONS
+#define MYNEWT_VAL_BLE_MAX_CONNECTIONS (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS
+#define MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES
+#define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV
+#define MYNEWT_VAL_BLE_PERIODIC_ADV (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS
+#define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER
+#define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_PHY_2M
+#define MYNEWT_VAL_BLE_PHY_2M (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_PHY_CODED
+#define MYNEWT_VAL_BLE_PHY_CODED (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_POWER_CONTROL
+#define MYNEWT_VAL_BLE_POWER_CONTROL (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER
+#define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ROLE_CENTRAL
+#define MYNEWT_VAL_BLE_ROLE_CENTRAL (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ROLE_OBSERVER
+#define MYNEWT_VAL_BLE_ROLE_OBSERVER (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ROLE_PERIPHERAL
+#define MYNEWT_VAL_BLE_ROLE_PERIPHERAL (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_VERSION
+#define MYNEWT_VAL_BLE_VERSION (50)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_WHITELIST
+#define MYNEWT_VAL_BLE_WHITELIST (1)
+#endif
+
+/*** @apache-mynewt-nimble/nimble/host */
+#ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU
+#define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO
+#define MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_TYPE
+#define MYNEWT_VAL_BLE_ATT_SVR_FIND_TYPE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_INDICATE
+#define MYNEWT_VAL_BLE_ATT_SVR_INDICATE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES
+#define MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES (64)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY
+#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI
+#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI (MYNEWT_VAL_BLE_ATT_SVR_NOTIFY && (MYNEWT_VAL_BLE_VERSION >= 52))
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE
+#define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE_TMO
+#define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE_TMO (30000)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ
+#define MYNEWT_VAL_BLE_ATT_SVR_READ (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_BLOB
+#define MYNEWT_VAL_BLE_ATT_SVR_READ_BLOB (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_GROUP_TYPE
+#define MYNEWT_VAL_BLE_ATT_SVR_READ_GROUP_TYPE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_MULT
+#define MYNEWT_VAL_BLE_ATT_SVR_READ_MULT (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE
+#define MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_SIGNED_WRITE
+#define MYNEWT_VAL_BLE_ATT_SVR_SIGNED_WRITE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_WRITE
+#define MYNEWT_VAL_BLE_ATT_SVR_WRITE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP
+#define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM
+#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL
+#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD
+#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_EATT_MTU
+#define MYNEWT_VAL_BLE_EATT_MTU (128)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE
+#define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_CHRS
+#define MYNEWT_VAL_BLE_GATT_DISC_ALL_CHRS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_DSCS
+#define MYNEWT_VAL_BLE_GATT_DISC_ALL_DSCS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_SVCS
+#define MYNEWT_VAL_BLE_GATT_DISC_ALL_SVCS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_DISC_CHR_UUID
+#define MYNEWT_VAL_BLE_GATT_DISC_CHR_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_DISC_SVC_UUID
+#define MYNEWT_VAL_BLE_GATT_DISC_SVC_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_FIND_INC_SVCS
+#define MYNEWT_VAL_BLE_GATT_FIND_INC_SVCS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_INDICATE
+#define MYNEWT_VAL_BLE_GATT_INDICATE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_MAX_PROCS
+#define MYNEWT_VAL_BLE_GATT_MAX_PROCS (4)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY
+#define MYNEWT_VAL_BLE_GATT_NOTIFY (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_READ
+#define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_READ_LONG
+#define MYNEWT_VAL_BLE_GATT_READ_LONG (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_READ_MAX_ATTRS
+#define MYNEWT_VAL_BLE_GATT_READ_MAX_ATTRS (8)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_READ_MULT
+#define MYNEWT_VAL_BLE_GATT_READ_MULT (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_READ_MULT_VAR
+#define MYNEWT_VAL_BLE_GATT_READ_MULT_VAR (MYNEWT_VAL_BLE_ROLE_CENTRAL && (MYNEWT_VAL_BLE_VERSION >= 52))
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_READ_UUID
+#define MYNEWT_VAL_BLE_GATT_READ_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_RESUME_RATE
+#define MYNEWT_VAL_BLE_GATT_RESUME_RATE (1000)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_SIGNED_WRITE
+#define MYNEWT_VAL_BLE_GATT_SIGNED_WRITE (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_WRITE
+#define MYNEWT_VAL_BLE_GATT_WRITE (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_WRITE_LONG
+#define MYNEWT_VAL_BLE_GATT_WRITE_LONG (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_WRITE_MAX_ATTRS
+#define MYNEWT_VAL_BLE_GATT_WRITE_MAX_ATTRS (4)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_WRITE_NO_RSP
+#define MYNEWT_VAL_BLE_GATT_WRITE_NO_RSP (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_WRITE_RELIABLE
+#define MYNEWT_VAL_BLE_GATT_WRITE_RELIABLE (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HOST
+#define MYNEWT_VAL_BLE_HOST (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_AUTO_START
+#define MYNEWT_VAL_BLE_HS_AUTO_START (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_DEBUG
+#define MYNEWT_VAL_BLE_HS_DEBUG (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL
+#define MYNEWT_VAL_BLE_HS_FLOW_CTRL (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL_ITVL
+#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_ITVL (1000)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL_THRESH
+#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_THRESH (2)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT
+#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT
+#define MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_LOG_LVL
+#define MYNEWT_VAL_BLE_HS_LOG_LVL (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_LOG_MOD
+#define MYNEWT_VAL_BLE_HS_LOG_MOD (4)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS
+#define MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_REQUIRE_OS
+#define MYNEWT_VAL_BLE_HS_REQUIRE_OS (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN
+#define MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN_TIMEOUT
+#define MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN_TIMEOUT (2000)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_SYSINIT_STAGE
+#define MYNEWT_VAL_BLE_HS_SYSINIT_STAGE (200)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM
+#define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_L2CAP_COC_MPS
+#define MYNEWT_VAL_BLE_L2CAP_COC_MPS (MYNEWT_VAL_MSYS_1_BLOCK_SIZE-8)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT
+#define MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC
+#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS
+#define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_L2CAP_MAX_CHANS
+#define MYNEWT_VAL_BLE_L2CAP_MAX_CHANS (3*MYNEWT_VAL_BLE_MAX_CONNECTIONS)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_L2CAP_RX_FRAG_TIMEOUT
+#define MYNEWT_VAL_BLE_L2CAP_RX_FRAG_TIMEOUT (30000)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS
+#define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MAX_BIG
+#define MYNEWT_VAL_BLE_MAX_BIG (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MAX_BIS
+#define MYNEWT_VAL_BLE_MAX_BIS (4)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH
+#define MYNEWT_VAL_BLE_MESH (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_RPA_TIMEOUT
+#define MYNEWT_VAL_BLE_RPA_TIMEOUT (300)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_BONDING
+#define MYNEWT_VAL_BLE_SM_BONDING (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_CSIS_SIRK
+#define MYNEWT_VAL_BLE_SM_CSIS_SIRK (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_IO_CAP
+#define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_NO_INPUT_OUTPUT)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_KEYPRESS
+#define MYNEWT_VAL_BLE_SM_KEYPRESS (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_LEGACY
+#define MYNEWT_VAL_BLE_SM_LEGACY (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_LVL
+#define MYNEWT_VAL_BLE_SM_LVL (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_MAX_PROCS
+#define MYNEWT_VAL_BLE_SM_MAX_PROCS (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_MITM
+#define MYNEWT_VAL_BLE_SM_MITM (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG
+#define MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_OUR_KEY_DIST
+#define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_SC
+#define MYNEWT_VAL_BLE_SM_SC (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS
+#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY
+#define MYNEWT_VAL_BLE_SM_SC_ONLY (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST
+#define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_STORE_MAX_BONDS
+#define MYNEWT_VAL_BLE_STORE_MAX_BONDS (3)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_STORE_MAX_CCCDS
+#define MYNEWT_VAL_BLE_STORE_MAX_CCCDS (8)
+#endif
+
+/*** @apache-mynewt-nimble/nimble/host/services/ans */
+#ifndef MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT
+#define MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_ANS_SYSINIT_STAGE
+#define MYNEWT_VAL_BLE_SVC_ANS_SYSINIT_STAGE (303)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT
+#define MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT (0)
+#endif
+
+/*** @apache-mynewt-nimble/nimble/host/services/bas */
+#ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE
+#define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_READ_PERM
+#define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_READ_PERM (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_BAS_SYSINIT_STAGE
+#define MYNEWT_VAL_BLE_SVC_BAS_SYSINIT_STAGE (303)
+#endif
+
+/*** @apache-mynewt-nimble/nimble/host/services/dis */
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM
+#define MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM (-1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT
+#define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT (NULL)
+#endif
+
+/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM
+#define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM (-1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT
+#define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT (NULL)
+#endif
+
+/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM
+#define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM (-1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT
+#define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT (NULL)
+#endif
+
+/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM
+#define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM (-1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT
+#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT "Apache Mynewt NimBLE"
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_READ_PERM
+#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_READ_PERM (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT
+#define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT (NULL)
+#endif
+
+/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM
+#define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM (-1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT
+#define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT (NULL)
+#endif
+
+/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM
+#define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM (-1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSINIT_STAGE
+#define MYNEWT_VAL_BLE_SVC_DIS_SYSINIT_STAGE (303)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_DEFAULT
+#define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_DEFAULT (NULL)
+#endif
+
+/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */
+#ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM
+#define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM (-1)
+#endif
+
+/*** @apache-mynewt-nimble/nimble/host/services/gap */
+#ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE
+#define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE_WRITE_PERM
+#define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE_WRITE_PERM (-1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION
+#define MYNEWT_VAL_BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION (-1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME
+#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME "nimble"
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH
+#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH (31)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM
+#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM (-1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL
+#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL
+#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_SLAVE_LATENCY
+#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SLAVE_LATENCY (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_SUPERVISION_TMO
+#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SUPERVISION_TMO (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_GAP_SYSINIT_STAGE
+#define MYNEWT_VAL_BLE_SVC_GAP_SYSINIT_STAGE (301)
+#endif
+
+/*** @apache-mynewt-nimble/nimble/host/services/gatt */
+#ifndef MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE
+#define MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE (302)
+#endif
+
+/*** @apache-mynewt-nimble/nimble/host/services/ias */
+#ifndef MYNEWT_VAL_BLE_SVC_IAS_SYSINIT_STAGE
+#define MYNEWT_VAL_BLE_SVC_IAS_SYSINIT_STAGE (303)
+#endif
+
+/*** @apache-mynewt-nimble/nimble/host/services/ipss */
+#ifndef MYNEWT_VAL_BLE_SVC_IPSS_SYSINIT_STAGE
+#define MYNEWT_VAL_BLE_SVC_IPSS_SYSINIT_STAGE (303)
+#endif
+
+/*** @apache-mynewt-nimble/nimble/host/services/lls */
+#ifndef MYNEWT_VAL_BLE_SVC_LLS_SYSINIT_STAGE
+#define MYNEWT_VAL_BLE_SVC_LLS_SYSINIT_STAGE (303)
+#endif
+
+/*** @apache-mynewt-nimble/nimble/host/services/tps */
+#ifndef MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE
+#define MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE (303)
+#endif
+
+/*** @apache-mynewt-nimble/nimble/transport */
+#undef MYNEWT_VAL_BLE_ACL_BUF_COUNT
+
+#undef MYNEWT_VAL_BLE_ACL_BUF_SIZE
+
+#undef MYNEWT_VAL_BLE_HCI_BRIDGE
+
+#undef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE
+
+#undef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT
+
+#undef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT
+
+#undef MYNEWT_VAL_BLE_HCI_TRANSPORT
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE
+#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_RTT
+#define MYNEWT_VAL_BLE_MONITOR_RTT (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED
+#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME
+#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME "btmonitor"
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE
+#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_UART
+#define MYNEWT_VAL_BLE_MONITOR_UART (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE
+#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE
+#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV
+#define MYNEWT_VAL_BLE_MONITOR_UART_DEV "uart0"
+#endif
+
+#ifndef MYNEWT_VAL_BLE_TRANSPORT
+#define MYNEWT_VAL_BLE_TRANSPORT (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT
+#define MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT (10)
+#endif
+
+/* Value copied from BLE_TRANSPORT_ACL_COUNT */
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT
+#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT (10)
+#endif
+
+/* Value copied from BLE_TRANSPORT_ACL_COUNT */
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT
+#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT (10)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE
+#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (251)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT
+#define MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT (4)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT
+#define MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT (16)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE
+#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (70)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__cdc
+#define MYNEWT_VAL_BLE_TRANSPORT_HS__cdc (0)
+#endif
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__custom
+#define MYNEWT_VAL_BLE_TRANSPORT_HS__custom (0)
+#endif
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac
+#define MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac (0)
+#endif
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__native
+#define MYNEWT_VAL_BLE_TRANSPORT_HS__native (1)
+#endif
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340
+#define MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340 (0)
+#endif
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__uart
+#define MYNEWT_VAL_BLE_TRANSPORT_HS__uart (0)
+#endif
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__usb
+#define MYNEWT_VAL_BLE_TRANSPORT_HS__usb (0)
+#endif
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS
+#define MYNEWT_VAL_BLE_TRANSPORT_HS (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT
+#define MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT (10)
+#endif
+
+/* Value copied from BLE_TRANSPORT_ISO_COUNT */
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT
+#define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT (10)
+#endif
+
+/* Value copied from BLE_TRANSPORT_ISO_COUNT */
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT
+#define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT (10)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE
+#define MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE (300)
+#endif
+
+/* Overridden by @apache-mynewt-nimble/porting/targets/porting_default (defined by @apache-mynewt-nimble/nimble/transport) */
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3
+#define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0)
+#endif
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__custom
+#define MYNEWT_VAL_BLE_TRANSPORT_LL__custom (0)
+#endif
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac
+#define MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac (0)
+#endif
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__emspi
+#define MYNEWT_VAL_BLE_TRANSPORT_LL__emspi (0)
+#endif
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__native
+#define MYNEWT_VAL_BLE_TRANSPORT_LL__native (0)
+#endif
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340
+#define MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340 (0)
+#endif
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__socket
+#define MYNEWT_VAL_BLE_TRANSPORT_LL__socket (1)
+#endif
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__uart_ll
+#define MYNEWT_VAL_BLE_TRANSPORT_LL__uart_ll (0)
+#endif
+#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL
+#define MYNEWT_VAL_BLE_TRANSPORT_LL (1)
+#endif
+
+/*** @apache-mynewt-nimble/nimble/transport/socket */
+#ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE
+#define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SOCK_LINUX_DEV
+#define MYNEWT_VAL_BLE_SOCK_LINUX_DEV (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SOCK_STACK_SIZE
+#define MYNEWT_VAL_BLE_SOCK_STACK_SIZE (80)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SOCK_TASK_PRIO
+#define MYNEWT_VAL_BLE_SOCK_TASK_PRIO (9)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SOCK_TCP_PORT
+#define MYNEWT_VAL_BLE_SOCK_TCP_PORT (14433)
+#endif
+
+/* Overridden by @apache-mynewt-nimble/porting/targets/porting_default (defined by @apache-mynewt-nimble/nimble/transport/socket) */
+#ifndef MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE
+#define MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SOCK_USE_NUTTX
+#define MYNEWT_VAL_BLE_SOCK_USE_NUTTX (0)
+#endif
+
+/* Overridden by @apache-mynewt-nimble/porting/targets/porting_default (defined by @apache-mynewt-nimble/nimble/transport/socket) */
+#ifndef MYNEWT_VAL_BLE_SOCK_USE_TCP
+#define MYNEWT_VAL_BLE_SOCK_USE_TCP (0)
+#endif
+
+/*** newt */
+#ifndef MYNEWT_VAL_APP_NAME
+#define MYNEWT_VAL_APP_NAME "dummy_app"
+#endif
+
+#ifndef MYNEWT_VAL_APP_dummy_app
+#define MYNEWT_VAL_APP_dummy_app (1)
+#endif
+
+#ifndef MYNEWT_VAL_ARCH_NAME
+#define MYNEWT_VAL_ARCH_NAME "sim"
+#endif
+
+#ifndef MYNEWT_VAL_ARCH_sim
+#define MYNEWT_VAL_ARCH_sim (1)
+#endif
+
+#ifndef MYNEWT_VAL_BSP_NAME
+#define MYNEWT_VAL_BSP_NAME "native"
+#endif
+
+#ifndef MYNEWT_VAL_BSP_native
+#define MYNEWT_VAL_BSP_native (1)
+#endif
+
+#ifndef MYNEWT_VAL_NEWT_FEATURE_LOGCFG
+#define MYNEWT_VAL_NEWT_FEATURE_LOGCFG (1)
+#endif
+
+#ifndef MYNEWT_VAL_NEWT_FEATURE_SYSDOWN
+#define MYNEWT_VAL_NEWT_FEATURE_SYSDOWN (1)
+#endif
+
+#ifndef MYNEWT_VAL_TARGET_NAME
+#define MYNEWT_VAL_TARGET_NAME "porting_default"
+#endif
+
+#ifndef MYNEWT_VAL_TARGET_porting_default
+#define MYNEWT_VAL_TARGET_porting_default (1)
+#endif
+
+/*** Included packages */
+#define MYNEWT_PKG_apache_mynewt_core__compiler_sim 1
+#define MYNEWT_PKG_apache_mynewt_core__crypto_tinycrypt 1
+#define MYNEWT_PKG_apache_mynewt_core__hw_bsp_native 1
+#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_flash_enc_flash 1
+#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_flash_enc_flash_ef_tinycrypt 1
+#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_trng 1
+#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_trng_trng_sw 1
+#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart 1
+#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart_uart_hal 1
+#define MYNEWT_PKG_apache_mynewt_core__hw_hal 1
+#define MYNEWT_PKG_apache_mynewt_core__hw_mcu_native 1
+#define MYNEWT_PKG_apache_mynewt_core__kernel_os 1
+#define MYNEWT_PKG_apache_mynewt_core__kernel_sim 1
+#define MYNEWT_PKG_apache_mynewt_core__net_ip_mn_socket 1
+#define MYNEWT_PKG_apache_mynewt_core__net_ip_native_sockets 1
+#define MYNEWT_PKG_apache_mynewt_core__sys_console_stub 1
+#define MYNEWT_PKG_apache_mynewt_core__sys_defs 1
+#define MYNEWT_PKG_apache_mynewt_core__sys_flash_map 1
+#define MYNEWT_PKG_apache_mynewt_core__sys_log_common 1
+#define MYNEWT_PKG_apache_mynewt_core__sys_log_modlog 1
+#define MYNEWT_PKG_apache_mynewt_core__sys_log_stub 1
+#define MYNEWT_PKG_apache_mynewt_core__sys_stats_stub 1
+#define MYNEWT_PKG_apache_mynewt_core__sys_sys 1
+#define MYNEWT_PKG_apache_mynewt_core__sys_sysdown 1
+#define MYNEWT_PKG_apache_mynewt_core__sys_sysinit 1
+#define MYNEWT_PKG_apache_mynewt_core__util_mem 1
+#define MYNEWT_PKG_apache_mynewt_core__util_rwlock 1
+#define MYNEWT_PKG_apache_mynewt_nimble__nimble 1
+#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host 1
+#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ans 1
+#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_bas 1
+#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_dis 1
+#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gap 1
+#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gatt 1
+#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ias 1
+#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ipss 1
+#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_lls 1
+#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_tps 1
+#define MYNEWT_PKG_apache_mynewt_nimble__nimble_transport 1
+#define MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_socket 1
+#define MYNEWT_PKG_apache_mynewt_nimble__porting_npl_mynewt 1
+#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1
+#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_porting_default 1
+
+/*** Included APIs */
+#define MYNEWT_API_TRNG_HW_IMPL 1
+#define MYNEWT_API_ble_transport 1
+#define MYNEWT_API_console 1
+#define MYNEWT_API_log 1
+#define MYNEWT_API_stats 1
+
+#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY 0
+#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV 0
+#define MYNEWT_VAL_BLE_LL_DTM_EXTENSIONS 0
+#define MYNEWT_VAL_BLE_CONTROLLER 0
+#define default_RNG_defined 0
+#define BLETEST_THROUGHPUT_TEST 0
+#define MYNEWT_VAL_TRNG 0
+#define MYNEWT_VAL_SELFTEST 0
+
+#define NIMBLE_CFG_CONTROLLER 0
+#define BLE_TRANSPORT_IPC 0
+#define BLE_TRANSPORT_IPC_ON_LL 0
+#define BLE_TRANSPORT_IPC_ON_HS 0
+#define MYNEWT_VAL_BLE_STORE_CONFIG_PERSIST 0
+#define MYNEWT_VAL_BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL 0
+#define MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_common_hci_ipc 0
+
+#define static_assert _Static_assert
+
+#endif

+ 51 - 0
third_party/nimble-1.6.0/porting/npl/freertos/src/nimble_port_freertos.c

@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <stddef.h>
+#include "FreeRTOS.h"
+#include "task.h"
+#include "nimble/nimble_port.h"
+
+#if NIMBLE_CFG_CONTROLLER
+static TaskHandle_t ll_task_h;
+#endif
+static TaskHandle_t host_task_h;
+
+void
+nimble_port_freertos_init(TaskFunction_t host_task_fn)
+{
+#if NIMBLE_CFG_CONTROLLER
+    /*
+     * Create task where NimBLE LL will run. This one is required as LL has its
+     * own event queue and should have highest priority. The task function is
+     * provided by NimBLE and in case of FreeRTOS it does not need to be wrapped
+     * since it has compatible prototype.
+     */
+    xTaskCreate(nimble_port_ll_task_func, "ll", configMINIMAL_STACK_SIZE + 400,
+                NULL, configMAX_PRIORITIES - 1, &ll_task_h);
+#endif
+
+    /*
+     * Create task where NimBLE host will run. It is not strictly necessary to
+     * have separate task for NimBLE host, but since something needs to handle
+     * default queue it is just easier to make separate task which does this.
+     */
+    xTaskCreate(host_task_fn, "ble", configMINIMAL_STACK_SIZE + 400,
+                NULL, tskIDLE_PRIORITY + 1, &host_task_h);
+}

+ 351 - 0
third_party/nimble-1.6.0/porting/npl/freertos/src/npl_os_freertos.c

@@ -0,0 +1,351 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <string.h>
+#include "nimble/nimble_npl.h"
+
+/* Include the file that defines the SCB for your HW. */
+#ifdef NIMBLE_NPL_OS_EXTRA_INCLUDE
+#include NIMBLE_NPL_OS_EXTRA_INCLUDE
+#endif
+
+static inline bool
+in_isr(void)
+{
+    return (xPortIsInsideInterrupt());
+}
+
+struct ble_npl_event *
+npl_freertos_eventq_get(struct ble_npl_eventq *evq, ble_npl_time_t tmo)
+{
+    struct ble_npl_event *ev = NULL;
+    BaseType_t woken;
+    BaseType_t ret;
+
+    if (in_isr()) {
+        assert(tmo == 0);
+        ret = xQueueReceiveFromISR(evq->q, &ev, &woken);
+        portYIELD_FROM_ISR(woken);
+    } else {
+        ret = xQueueReceive(evq->q, &ev, tmo);
+    }
+    assert(ret == pdPASS || ret == errQUEUE_EMPTY);
+
+    if (ev) {
+        ev->queued = false;
+    }
+
+    return ev;
+}
+
+void
+npl_freertos_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_event *ev)
+{
+    BaseType_t woken;
+    BaseType_t ret;
+
+    if (ev->queued) {
+        return;
+    }
+
+    ev->queued = true;
+
+    if (in_isr()) {
+        ret = xQueueSendToBackFromISR(evq->q, &ev, &woken);
+        portYIELD_FROM_ISR(woken);
+    } else {
+        ret = xQueueSendToBack(evq->q, &ev, portMAX_DELAY);
+    }
+
+    assert(ret == pdPASS);
+}
+
+void
+npl_freertos_eventq_remove(struct ble_npl_eventq *evq,
+                      struct ble_npl_event *ev)
+{
+    struct ble_npl_event *tmp_ev;
+    BaseType_t ret;
+    int i;
+    int count;
+    BaseType_t woken, woken2;
+
+    if (!ev->queued) {
+        return;
+    }
+
+    /*
+     * XXX We cannot extract element from inside FreeRTOS queue so as a quick
+     * workaround we'll just remove all elements and add them back except the
+     * one we need to remove. This is silly, but works for now - we probably
+     * better use counting semaphore with os_queue to handle this in future.
+     */
+
+    if (in_isr()) {
+        woken = pdFALSE;
+
+        count = uxQueueMessagesWaitingFromISR(evq->q);
+        for (i = 0; i < count; i++) {
+            ret = xQueueReceiveFromISR(evq->q, &tmp_ev, &woken2);
+            assert(ret == pdPASS);
+            woken |= woken2;
+
+            if (tmp_ev == ev) {
+                continue;
+            }
+
+            ret = xQueueSendToBackFromISR(evq->q, &tmp_ev, &woken2);
+            assert(ret == pdPASS);
+            woken |= woken2;
+        }
+
+        portYIELD_FROM_ISR(woken);
+    } else {
+        vTaskEnterCritical();
+
+        count = uxQueueMessagesWaiting(evq->q);
+        for (i = 0; i < count; i++) {
+            ret = xQueueReceive(evq->q, &tmp_ev, 0);
+            assert(ret == pdPASS);
+
+            if (tmp_ev == ev) {
+                continue;
+            }
+
+            ret = xQueueSendToBack(evq->q, &tmp_ev, 0);
+            assert(ret == pdPASS);
+        }
+
+        vTaskExitCritical();
+    }
+
+    ev->queued = 0;
+}
+
+ble_npl_error_t
+npl_freertos_mutex_init(struct ble_npl_mutex *mu)
+{
+    if (!mu) {
+        return BLE_NPL_INVALID_PARAM;
+    }
+
+    mu->handle = xSemaphoreCreateRecursiveMutex();
+    assert(mu->handle);
+
+    return BLE_NPL_OK;
+}
+
+ble_npl_error_t
+npl_freertos_mutex_pend(struct ble_npl_mutex *mu, ble_npl_time_t timeout)
+{
+    BaseType_t ret;
+
+    if (!mu) {
+        return BLE_NPL_INVALID_PARAM;
+    }
+
+    assert(mu->handle);
+
+    if (in_isr()) {
+        ret = pdFAIL;
+        assert(0);
+    } else {
+        ret = xSemaphoreTakeRecursive(mu->handle, timeout);
+    }
+
+    return ret == pdPASS ? BLE_NPL_OK : BLE_NPL_TIMEOUT;
+}
+
+ble_npl_error_t
+npl_freertos_mutex_release(struct ble_npl_mutex *mu)
+{
+    if (!mu) {
+        return BLE_NPL_INVALID_PARAM;
+    }
+
+    assert(mu->handle);
+
+    if (in_isr()) {
+        assert(0);
+    } else {
+        if (xSemaphoreGiveRecursive(mu->handle) != pdPASS) {
+            return BLE_NPL_BAD_MUTEX;
+        }
+    }
+
+    return BLE_NPL_OK;
+}
+
+ble_npl_error_t
+npl_freertos_sem_init(struct ble_npl_sem *sem, uint16_t tokens)
+{
+    if (!sem) {
+        return BLE_NPL_INVALID_PARAM;
+    }
+
+    sem->handle = xSemaphoreCreateCounting(128, tokens);
+    assert(sem->handle);
+
+    return BLE_NPL_OK;
+}
+
+ble_npl_error_t
+npl_freertos_sem_pend(struct ble_npl_sem *sem, ble_npl_time_t timeout)
+{
+    BaseType_t woken;
+    BaseType_t ret;
+
+    if (!sem) {
+        return BLE_NPL_INVALID_PARAM;
+    }
+
+    assert(sem->handle);
+
+    if (in_isr()) {
+        assert(timeout == 0);
+        ret = xSemaphoreTakeFromISR(sem->handle, &woken);
+        portYIELD_FROM_ISR(woken);
+    } else {
+        ret = xSemaphoreTake(sem->handle, timeout);
+    }
+
+    return ret == pdPASS ? BLE_NPL_OK : BLE_NPL_TIMEOUT;
+}
+
+ble_npl_error_t
+npl_freertos_sem_release(struct ble_npl_sem *sem)
+{
+    BaseType_t ret;
+    BaseType_t woken;
+
+    if (!sem) {
+        return BLE_NPL_INVALID_PARAM;
+    }
+
+    assert(sem->handle);
+
+    if (in_isr()) {
+        ret = xSemaphoreGiveFromISR(sem->handle, &woken);
+        portYIELD_FROM_ISR(woken);
+    } else {
+        ret = xSemaphoreGive(sem->handle);
+    }
+
+    assert(ret == pdPASS);
+    return BLE_NPL_OK;
+}
+
+static void
+os_callout_timer_cb(TimerHandle_t timer)
+{
+    struct ble_npl_callout *co;
+
+    co = pvTimerGetTimerID(timer);
+    assert(co);
+
+    if (co->evq) {
+        ble_npl_eventq_put(co->evq, &co->ev);
+    } else {
+        co->ev.fn(&co->ev);
+    }
+}
+
+void
+npl_freertos_callout_init(struct ble_npl_callout *co, struct ble_npl_eventq *evq,
+                     ble_npl_event_fn *ev_cb, void *ev_arg)
+{
+    memset(co, 0, sizeof(*co));
+    co->handle = xTimerCreate("co", 1, pdFALSE, co, os_callout_timer_cb);
+    co->evq = evq;
+    ble_npl_event_init(&co->ev, ev_cb, ev_arg);
+}
+
+ble_npl_error_t
+npl_freertos_callout_reset(struct ble_npl_callout *co, ble_npl_time_t ticks)
+{
+    BaseType_t woken1, woken2, woken3;
+
+    if (ticks == 0) {
+        ticks = 1;
+    }
+
+    if (in_isr()) {
+        xTimerStopFromISR(co->handle, &woken1);
+        xTimerChangePeriodFromISR(co->handle, ticks, &woken2);
+        xTimerResetFromISR(co->handle, &woken3);
+
+        portYIELD_FROM_ISR(woken1 || woken2 || woken3);
+    } else {
+        xTimerStop(co->handle, portMAX_DELAY);
+        xTimerChangePeriod(co->handle, ticks, portMAX_DELAY);
+        xTimerReset(co->handle, portMAX_DELAY);
+    }
+
+    return BLE_NPL_OK;
+}
+
+ble_npl_time_t
+npl_freertos_callout_remaining_ticks(struct ble_npl_callout *co,
+                                     ble_npl_time_t now)
+{
+    ble_npl_time_t rt;
+    uint32_t exp;
+
+    exp = xTimerGetExpiryTime(co->handle);
+
+    if (exp > now) {
+        rt = exp - now;
+    } else {
+        rt = 0;
+    }
+
+    return rt;
+}
+
+ble_npl_error_t
+npl_freertos_time_ms_to_ticks(uint32_t ms, ble_npl_time_t *out_ticks)
+{
+    uint64_t ticks;
+
+    ticks = ((uint64_t)ms * configTICK_RATE_HZ) / 1000;
+    if (ticks > UINT32_MAX) {
+        return BLE_NPL_EINVAL;
+    }
+
+    *out_ticks = ticks;
+
+    return 0;
+}
+
+ble_npl_error_t
+npl_freertos_time_ticks_to_ms(ble_npl_time_t ticks, uint32_t *out_ms)
+{
+    uint64_t ms;
+
+    ms = ((uint64_t)ticks * 1000) / configTICK_RATE_HZ;
+    if (ms > UINT32_MAX) {
+        return BLE_NPL_EINVAL;
+     }
+
+    *out_ms = ms;
+
+    return 0;
+}

+ 0 - 0
third_party/zephyr_bluetooth-3.x.x/ble_hci_usbh.c → third_party/zephyr_bluetooth-2.x.x/ble_hci_usbh.c