diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index e4186b274..dc96eb75b 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -23,6 +23,8 @@ #include #include "host/ble_hs.h" #include "host/ble_hs_adv.h" +#include "syscfg/syscfg.h" + #ifdef __cplusplus extern "C" { #endif @@ -698,6 +700,11 @@ int ble_gap_set_prefered_default_le_phy(uint8_t tx_phys_mask, #define BLE_GAP_LE_PHY_CODED_S8 2 int ble_gap_set_prefered_le_phy(uint16_t conn_handle, uint8_t tx_phys_mask, uint8_t rx_phys_mask, uint16_t phy_opts); + +#if MYNEWT_VAL(BLE_MESH) +int ble_gap_mesh_cb_register(ble_gap_event_fn *cb, void *cb_arg); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/host/include/host/ble_hs_adv.h b/nimble/host/include/host/ble_hs_adv.h index 23c21559b..c0b46d27e 100644 --- a/nimble/host/include/host/ble_hs_adv.h +++ b/nimble/host/include/host/ble_hs_adv.h @@ -126,6 +126,9 @@ struct ble_hs_adv_fields { #define BLE_HS_ADV_TYPE_SVC_DATA_UUID32 0x20 #define BLE_HS_ADV_TYPE_SVC_DATA_UUID128 0x21 #define BLE_HS_ADV_TYPE_URI 0x24 +#define BLE_HS_ADV_TYPE_MESH_PROV 0x29 +#define BLE_HS_ADV_TYPE_MESH_MESSAGE 0x2a +#define BLE_HS_ADV_TYPE_MESH_BEACON 0x2b #define BLE_HS_ADV_TYPE_MFG_DATA 0xff #define BLE_HS_ADV_FLAGS_LEN 1 diff --git a/nimble/host/mesh/include/mesh/atomic.h b/nimble/host/mesh/include/mesh/atomic.h new file mode 100644 index 000000000..9af3344f8 --- /dev/null +++ b/nimble/host/mesh/include/mesh/atomic.h @@ -0,0 +1,386 @@ +/* atomic operations */ + +/* + * Copyright (c) 1997-2015, Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ATOMIC_H__ +#define __ATOMIC_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef int atomic_t; +typedef atomic_t atomic_val_t; + +/** + * @defgroup atomic_apis Atomic Services APIs + * @ingroup kernel_apis + * @{ + */ + +/** + * @brief Atomic compare-and-set. + * + * This routine performs an atomic compare-and-set on @a target. If the current + * value of @a target equals @a old_value, @a target is set to @a new_value. + * If the current value of @a target does not equal @a old_value, @a target + * is left unchanged. + * + * @param target Address of atomic variable. + * @param old_value Original value to compare against. + * @param new_value New value to store. + * @return 1 if @a new_value is written, 0 otherwise. + */ +static inline int atomic_cas(atomic_t *target, atomic_val_t old_value, + atomic_val_t new_value) +{ + return __atomic_compare_exchange_n(target, &old_value, new_value, + 0, __ATOMIC_SEQ_CST, + __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic addition. + * + * This routine performs an atomic addition on @a target. + * + * @param target Address of atomic variable. + * @param value Value to add. + * + * @return Previous value of @a target. + */ +static inline atomic_val_t atomic_add(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_add(target, value, __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic subtraction. + * + * This routine performs an atomic subtraction on @a target. + * + * @param target Address of atomic variable. + * @param value Value to subtract. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_sub(target, value, __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic increment. + * + * This routine performs an atomic increment by 1 on @a target. + * + * @param target Address of atomic variable. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_inc(atomic_t *target) +{ + return atomic_add(target, 1); +} + +/** + * + * @brief Atomic decrement. + * + * This routine performs an atomic decrement by 1 on @a target. + * + * @param target Address of atomic variable. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_dec(atomic_t *target) +{ + return atomic_sub(target, 1); +} + +/** + * + * @brief Atomic get. + * + * This routine performs an atomic read on @a target. + * + * @param target Address of atomic variable. + * + * @return Value of @a target. + */ + +static inline atomic_val_t atomic_get(const atomic_t *target) +{ + return __atomic_load_n(target, __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic get-and-set. + * + * This routine atomically sets @a target to @a value and returns + * the previous value of @a target. + * + * @param target Address of atomic variable. + * @param value Value to write to @a target. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_set(atomic_t *target, atomic_val_t value) +{ + /* This builtin, as described by Intel, is not a traditional + * test-and-set operation, but rather an atomic exchange operation. It + * writes value into *ptr, and returns the previous contents of *ptr. + */ + return __atomic_exchange_n(target, value, __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic clear. + * + * This routine atomically sets @a target to zero and returns its previous + * value. (Hence, it is equivalent to atomic_set(target, 0).) + * + * @param target Address of atomic variable. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_clear(atomic_t *target) +{ + return atomic_set(target, 0); +} + +/** + * + * @brief Atomic bitwise inclusive OR. + * + * This routine atomically sets @a target to the bitwise inclusive OR of + * @a target and @a value. + * + * @param target Address of atomic variable. + * @param value Value to OR. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_or(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_or(target, value, __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic bitwise exclusive OR (XOR). + * + * This routine atomically sets @a target to the bitwise exclusive OR (XOR) of + * @a target and @a value. + * + * @param target Address of atomic variable. + * @param value Value to XOR + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_xor(target, value, __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic bitwise AND. + * + * This routine atomically sets @a target to the bitwise AND of @a target + * and @a value. + * + * @param target Address of atomic variable. + * @param value Value to AND. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_and(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_and(target, value, __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic bitwise NAND. + * + * This routine atomically sets @a target to the bitwise NAND of @a target + * and @a value. (This operation is equivalent to target = ~(target & value).) + * + * @param target Address of atomic variable. + * @param value Value to NAND. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_nand(target, value, __ATOMIC_SEQ_CST); +} + + /** + * @brief Initialize an atomic variable. + * + * This macro can be used to initialize an atomic variable. For example, + * @code atomic_t my_var = ATOMIC_INIT(75); @endcode + * + * @param i Value to assign to atomic variable. + */ +#define ATOMIC_INIT(i) (i) + + /** + * @cond INTERNAL_HIDDEN + */ + +#define ATOMIC_BITS (sizeof(atomic_val_t) * 8) +#define ATOMIC_MASK(bit) (1 << ((bit) & (ATOMIC_BITS - 1))) +#define ATOMIC_ELEM(addr, bit) ((addr) + ((bit) / ATOMIC_BITS)) + + /** + * INTERNAL_HIDDEN @endcond + */ + + /** + * @brief Define an array of atomic variables. + * + * This macro defines an array of atomic variables containing at least + * @a num_bits bits. + * + * @note + * If used from file scope, the bits of the array are initialized to zero; + * if used from within a function, the bits are left uninitialized. + * + * @param name Name of array of atomic variables. + * @param num_bits Number of bits needed. + */ +#define ATOMIC_DEFINE(name, num_bits) \ + atomic_t name[1 + ((num_bits) - 1) / ATOMIC_BITS] + + /** + * @brief Atomically test a bit. + * + * This routine tests whether bit number @a bit of @a target is set or not. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return 1 if the bit was set, 0 if it wasn't. + */ + static inline int + atomic_test_bit(const atomic_t *target, int bit) + { + atomic_val_t val = atomic_get(ATOMIC_ELEM(target, bit)); + + return (1 & (val >> (bit & (ATOMIC_BITS - 1)))); + } + + /** + * @brief Atomically test and clear a bit. + * + * Atomically clear bit number @a bit of @a target and return its old value. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return 1 if the bit was set, 0 if it wasn't. + */ + static inline int + atomic_test_and_clear_bit(atomic_t *target, int bit) + { + atomic_val_t mask = ATOMIC_MASK(bit); + atomic_val_t old; + + old = atomic_and(ATOMIC_ELEM(target, bit), ~mask); + + return (old & mask) != 0; + } + + /** + * @brief Atomically set a bit. + * + * Atomically set bit number @a bit of @a target and return its old value. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return 1 if the bit was set, 0 if it wasn't. + */ + static inline int + atomic_test_and_set_bit(atomic_t *target, int bit) + { + atomic_val_t mask = ATOMIC_MASK(bit); + atomic_val_t old; + + old = atomic_or(ATOMIC_ELEM(target, bit), mask); + + return (old & mask) != 0; + } + + /** + * @brief Atomically clear a bit. + * + * Atomically clear bit number @a bit of @a target. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return N/A + */ + static inline void + atomic_clear_bit(atomic_t *target, int bit) + { + atomic_val_t mask = ATOMIC_MASK(bit); + + atomic_and(ATOMIC_ELEM(target, bit), ~mask); + } + + /** + * @brief Atomically set a bit. + * + * Atomically set bit number @a bit of @a target. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return N/A + */ + static inline void + atomic_set_bit(atomic_t *target, int bit) + { + atomic_val_t mask = ATOMIC_MASK(bit); + + atomic_or(ATOMIC_ELEM(target, bit), mask); + } + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ATOMIC_H__ */ diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h new file mode 100644 index 000000000..ad271161a --- /dev/null +++ b/nimble/host/mesh/include/mesh/glue.h @@ -0,0 +1,318 @@ +/* + * 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 _MESH_GLUE_ +#define _MESH_GLUE_ + +#include + +#include "syscfg/syscfg.h" + +#include "os/os_mbuf.h" +#include "os/os_mbuf.h" +#include "os/os_callout.h" +#include "os/os_eventq.h" + +#include "atomic.h" +#include "nimble/ble.h" +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "../src/ble_sm_priv.h" +#include "../src/ble_hs_hci_priv.h" + +#include "tinycrypt/aes.h" +#include "tinycrypt/constants.h" +#include "tinycrypt/utils.h" +#include "tinycrypt/cmac_mode.h" +#include "tinycrypt/ecc_dh.h" + +#define u8_t uint8_t +#define s8_t int8_t +#define u16_t uint16_t +#define u32_t uint32_t +#define u64_t uint64_t +#define s64_t int64_t +#define s32_t int32_t +typedef size_t ssize_t; + +/** @brief Helper to declare elements of bt_data arrays + * + * This macro is mainly for creating an array of struct bt_data + * elements which is then passed to bt_le_adv_start(). + * + * @param _type Type of advertising data field + * @param _data Pointer to the data field payload + * @param _data_len Number of bytes behind the _data pointer + */ +#define BT_DATA(_type, _data, _data_len) \ + { \ + .type = (_type), \ + .data_len = (_data_len), \ + .data = (const u8_t *)(_data), \ + } + +/** @brief Helper to declare elements of bt_data arrays + * + * This macro is mainly for creating an array of struct bt_data + * elements which is then passed to bt_le_adv_start(). + * + * @param _type Type of advertising data field + * @param _bytes Variable number of single-byte parameters + */ +#define BT_DATA_BYTES(_type, _bytes...) \ + BT_DATA(_type, ((u8_t []) { _bytes }), \ + sizeof((u8_t []) { _bytes })) + +/* EIR/AD data type definitions */ +#define BT_DATA_FLAGS 0x01 /* AD flags */ +#define BT_DATA_UUID16_SOME 0x02 /* 16-bit UUID, more available */ +#define BT_DATA_UUID16_ALL 0x03 /* 16-bit UUID, all listed */ +#define BT_DATA_UUID32_SOME 0x04 /* 32-bit UUID, more available */ +#define BT_DATA_UUID32_ALL 0x05 /* 32-bit UUID, all listed */ +#define BT_DATA_UUID128_SOME 0x06 /* 128-bit UUID, more available */ +#define BT_DATA_UUID128_ALL 0x07 /* 128-bit UUID, all listed */ +#define BT_DATA_NAME_SHORTENED 0x08 /* Shortened name */ +#define BT_DATA_NAME_COMPLETE 0x09 /* Complete name */ +#define BT_DATA_TX_POWER 0x0a /* Tx Power */ +#define BT_DATA_SOLICIT16 0x14 /* Solicit UUIDs, 16-bit */ +#define BT_DATA_SOLICIT128 0x15 /* Solicit UUIDs, 128-bit */ +#define BT_DATA_SVC_DATA16 0x16 /* Service data, 16-bit UUID */ +#define BT_DATA_GAP_APPEARANCE 0x19 /* GAP appearance */ +#define BT_DATA_SOLICIT32 0x1f /* Solicit UUIDs, 32-bit */ +#define BT_DATA_SVC_DATA32 0x20 /* Service data, 32-bit UUID */ +#define BT_DATA_SVC_DATA128 0x21 /* Service data, 128-bit UUID */ +#define BT_DATA_MESH_PROV 0x29 /* Mesh Provisioning PDU */ +#define BT_DATA_MESH_MESSAGE 0x2a /* Mesh Networking PDU */ +#define BT_DATA_MESH_BEACON 0x2b /* Mesh Beacon */ + +#define BT_DATA_MANUFACTURER_DATA 0xff /* Manufacturer Specific Data */ + +#define BT_LE_AD_LIMITED 0x01 /* Limited Discoverable */ +#define BT_LE_AD_GENERAL 0x02 /* General Discoverable */ +#define BT_LE_AD_NO_BREDR 0x04 /* BR/EDR not supported */ + +#define sys_put_be16(a,b) put_be16(b, a) +#define sys_put_le16(a,b) put_le16(b, a) +#define sys_put_be32(a,b) put_be32(b, a) +#define sys_get_be16(a) get_be16(a) +#define sys_get_le16(a) get_le16(a) +#define sys_get_be32(a) get_be32(a) +#define sys_cpu_to_be16(a) htobe16(a) +#define sys_cpu_to_be32(a) htobe32(a) +#define sys_be32_to_cpu(a) be32toh(a) +#define sys_be16_to_cpu(a) be16toh(a) +#define sys_le16_to_cpu(a) le16toh(a) + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define CODE_UNREACHABLE __builtin_unreachable() +#define __ASSERT(code, str) \ + do { \ + if (!(code)) BT_ERR(str); \ + assert(code); \ + } while (0); + +#define __packed __attribute__((__packed__)) + +#define MSEC_PER_SEC (1000) +#define K_MSEC(ms) (ms) +#define K_SECONDS(s) K_MSEC((s) * MSEC_PER_SEC) +#define K_MINUTES(m) K_SECONDS((m) * 60) +#define K_HOURS(h) K_MINUTES((h) * 60) + +#define BT_GAP_ADV_FAST_INT_MIN_1 0x0030 /* 30 ms */ +#define BT_GAP_ADV_FAST_INT_MAX_1 0x0060 /* 60 ms */ +#define BT_GAP_ADV_FAST_INT_MIN_2 0x00a0 /* 100 ms */ +#define BT_GAP_ADV_FAST_INT_MAX_2 0x00f0 /* 150 ms */ +#define BT_GAP_ADV_SLOW_INT_MIN 0x0640 /* 1 s */ +#define BT_GAP_ADV_SLOW_INT_MAX 0x0780 /* 1.2 s */ + +#define BT_WARN(fmt, ...) BLE_HS_LOG(WARN, "%s: " fmt "\n", __func__, ## __VA_ARGS__); +#define BT_DBG(fmt, ...) BLE_HS_LOG(DEBUG, "%s: " fmt "\n", __func__, ## __VA_ARGS__); +#define BT_INFO(fmt, ...) BLE_HS_LOG(INFO, "%s: " fmt "\n", __func__, ## __VA_ARGS__); +#define BT_ERR(fmt, ...) BLE_HS_LOG(ERROR, "%s: " fmt "\n", __func__, ## __VA_ARGS__); +#define BT_GATT_ERR(_att_err) (-(_att_err)) + +typedef ble_addr_t bt_addr_le_t; + +#define k_fifo_init(queue) os_eventq_init(queue) +#define net_buf_simple_tailroom(buf) OS_MBUF_TRAILINGSPACE(buf) +#define net_buf_tailroom(buf) net_buf_simple_tailroom(buf) +#define net_buf_headroom(buf) ((buf)->om_data - &(buf)->om_databuf[buf->om_pkthdr_len]) +#define net_buf_simple_headroom(buf) net_buf_headroom(buf) +#define net_buf_simple_tail(buf) ((buf)->om_data + (buf)->om_len) + +struct net_buf_simple_state { + /** Offset of the data pointer from the beginning of the storage */ + u16_t offset; + /** Length of data */ + u16_t len; +}; + +static inline struct os_mbuf * NET_BUF_SIMPLE(uint16_t size) +{ + struct os_mbuf *buf; + + buf = os_msys_get(size, 0); + assert(buf); + + return buf; +} + +#define K_NO_WAIT (0) +#define K_FOREVER (-1) + +/* This is by purpose */ +static inline void net_buf_simple_init(struct os_mbuf *buf, + size_t reserve_head) +{ + /* This is called in Zephyr after init. + * Note in Mynewt case we don't care abour reserved head*/ + buf->om_data = &buf->om_databuf[buf->om_pkthdr_len] + reserve_head; + buf->om_len = 0; +} + +void net_buf_put(struct os_eventq *fifo, struct os_mbuf *buf); +void * net_buf_ref(struct os_mbuf *om); +void net_buf_unref(struct os_mbuf *om); +uint16_t net_buf_simple_pull_le16(struct os_mbuf *om); +uint16_t net_buf_simple_pull_be16(struct os_mbuf *om); +uint32_t net_buf_simple_pull_be32(struct os_mbuf *om); +uint8_t net_buf_simple_pull_u8(struct os_mbuf *om); +void net_buf_simple_add_le16(struct os_mbuf *om, uint16_t val); +void net_buf_simple_add_be16(struct os_mbuf *om, uint16_t val); +void net_buf_simple_add_u8(struct os_mbuf *om, uint8_t val); +void net_buf_simple_add_be32(struct os_mbuf *om, uint32_t val); +void net_buf_add_zeros(struct os_mbuf *om, uint8_t len); +void net_buf_simple_push_le16(struct os_mbuf *om, uint16_t val); +void net_buf_simple_push_be16(struct os_mbuf *om, uint16_t val); +void net_buf_simple_push_u8(struct os_mbuf *om, uint8_t val); +void *net_buf_simple_pull(struct os_mbuf *om, uint8_t len); +void *net_buf_simple_add(struct os_mbuf *om, uint8_t len); +bool k_fifo_is_empty(struct os_eventq *q); +void * net_buf_get(struct os_eventq *fifo,s32_t t); +uint8_t *net_buf_simple_push(struct os_mbuf *om, uint8_t len); +void net_buf_reserve(struct os_mbuf *om, size_t reserve); + +#define net_buf_add_mem(a,b,c) os_mbuf_append(a,b,c) +#define net_buf_simple_add_mem(a,b,c) os_mbuf_append(a,b,c) +#define net_buf_add_u8(a,b) net_buf_simple_add_u8(a,b) +#define net_buf_add(a,b) net_buf_simple_add(a,b) + +#define net_buf_clone(a, b) os_mbuf_dup(a) +#define net_buf_add_be32(a, b) net_buf_simple_add_be32(a, b) +#define net_buf_add_be16(a, b) net_buf_simple_add_be16(a, b) + +#define bt_le_adv_stop() ble_gap_adv_stop() +#define BT_GATT_CCC_NOTIFY BLE_GATT_CHR_PROP_NOTIFY +#define bt_gatt_attr ble_gatt_attr + +/** Description of different data types that can be encoded into + * advertising data. Used to form arrays that are passed to the + * bt_le_adv_start() function. + */ +struct bt_data { + u8_t type; + u8_t data_len; + const u8_t *data; +}; + +struct bt_pub_key_cb { + /** @brief Callback type for Public Key generation. + * + * Used to notify of the local public key or that the local key is not + * available (either because of a failure to read it or because it is + * being regenerated). + * + * @param key The local public key, or NULL in case of no key. + */ + void (*func)(const u8_t key[64]); + + struct bt_pub_key_cb *_next; +}; + +typedef void (*bt_dh_key_cb_t)(const u8_t key[32]); +int bt_dh_key_gen(const u8_t remote_pk[64], bt_dh_key_cb_t cb); +int bt_pub_key_gen(struct bt_pub_key_cb *new_cb); +uint8_t *bt_pub_key_get(void); +int bt_rand(void *buf, size_t len); +const char * bt_hex(const void *buf, size_t len); +int bt_encrypt_be(const uint8_t *key, const uint8_t *plaintext, uint8_t *enc_data); +void bt_mesh_register_gatt(void); +int bt_le_adv_start(const struct ble_gap_adv_params *param, + const struct bt_data *ad, size_t ad_len, + const struct bt_data *sd, size_t sd_len); + +struct k_delayed_work { + struct os_callout work; +}; + +void k_work_init(struct os_callout *work, os_event_fn handler); +void k_delayed_work_init(struct k_delayed_work *w, os_event_fn *f); +void k_delayed_work_cancel(struct k_delayed_work *w); +void k_delayed_work_submit(struct k_delayed_work *w, uint32_t ms); +int64_t k_uptime_get(void); +u32_t k_uptime_get_32(void); +void k_work_submit(struct os_callout *w); +void k_work_add_arg(struct os_callout *w, void *arg); +void k_delayed_work_add_arg(struct k_delayed_work *w, void *arg); +uint32_t k_delayed_work_remaining_get(struct k_delayed_work *w); + +static inline void net_buf_simple_save(struct os_mbuf *buf, + struct net_buf_simple_state *state) +{ + state->offset = net_buf_simple_headroom(buf); + state->len = buf->om_len; +} + +static inline void net_buf_simple_restore(struct os_mbuf *buf, + struct net_buf_simple_state *state) +{ + buf->om_data = &buf->om_databuf[buf->om_pkthdr_len] + state->offset; + buf->om_len = state->len; +} + +static inline void sys_memcpy_swap(void *dst, const void *src, size_t length) +{ + __ASSERT(((src < dst && (src + length) <= dst) || + (src > dst && (dst + length) <= src)), + "Source and destination buffers must not overlap"); + + src += length - 1; + + for (; length > 0; length--) { + *((u8_t *)dst++) = *((u8_t *)src--); + } +} + +#define popcount(x) __builtin_popcount(x) + +static inline unsigned int find_lsb_set(u32_t op) +{ + return __builtin_ffs(op); +} + +static inline unsigned int find_msb_set(u32_t op) +{ + if (!op) + return 0; + + return 32 - __builtin_clz(op); +} + +#endif diff --git a/nimble/host/mesh/include/mesh/mesh.h b/nimble/host/mesh/include/mesh/mesh.h new file mode 100644 index 000000000..27bc32b96 --- /dev/null +++ b/nimble/host/mesh/include/mesh/mesh.h @@ -0,0 +1,617 @@ +/** @file + * @brief Bluetooth Mesh Profile APIs. + */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_MESH_H +#define __BT_MESH_H + +#include +#include +#include +#include + +#include "mesh/glue.h" + +/** + * @brief Parsing state of a buffer. + * + * This is used for temporarily storing the parsing state of a buffer + * while giving control of the parsing to a routine which we don't + * control. + */ + +#define BIT(x) (1U << (x)) +#define BIT_MASK(n) (BIT(n) - 1) + +/** + * @brief Bluetooth Mesh Proxy + * @defgroup bt_mesh_proxy Bluetooth Mesh Proxy + * @ingroup bt_mesh + * @{ + */ + +/** + * @brief Enable advertising with Node Identity. + * + * This API requires that GATT Proxy support has been enabled. Once called + * each subnet will start advertising using Node Identity for the next + * 60 seconds. + * + * @return 0 on success, or (negative) error code on failure. + */ +int +bt_mesh_proxy_identity_enable(void); + +/** + * @} + */ + +/** + * @brief Bluetooth Mesh Composition + * @defgroup bt_comp Bluetooth Mesh Composition + * @ingroup bt_mesh + * @{ + */ + +#define BT_MESH_ADDR_UNASSIGNED 0x0000 +#define BT_MESH_ADDR_ALL_NODES 0xffff +#define BT_MESH_ADDR_PROXIES 0xfffc +#define BT_MESH_ADDR_FRIENDS 0xfffd +#define BT_MESH_ADDR_RELAYS 0xfffe + +#define BT_MESH_KEY_UNUSED 0xffff +#define BT_MESH_KEY_DEV 0xfffe + +/** + * @brief Bluetooth Mesh Element + * @defgroup bt_mesh_elem Bluetooth Mesh Element + * @ingroup bt_comp + * @{ + */ + +/** Helper to define a mesh element within an array. + * + * @param _loc Location Descriptor. + * @param _mods Array of models + * @param _vnd_mods Array of vendor models. + */ +#define BT_MESH_ELEM(_loc, _mods, _vnd_mods) \ +{ \ + .loc = (_loc), \ + .model_count = ARRAY_SIZE(_mods), \ + .models = (_mods), \ + .vnd_model_count = ARRAY_SIZE(_vnd_mods), \ + .vnd_models = (_vnd_mods), \ +} + +/** Abstraction that describes a Mesh Element */ +struct bt_mesh_elem +{ + /* Unicast Address. Set at runtime during provisioning. */ + u16_t addr; + + /* Location Descriptor (GATT Bluetooth Namespace Descriptors) */ + const u16_t loc; + + const u8_t model_count; + const u8_t vnd_model_count; + + struct bt_mesh_model * const models; + struct bt_mesh_model * const vnd_models; +}; + +/** + * @} + */ + +/** + * @brief Bluetooth Mesh Model + * @defgroup bt_mesh_model Bluetooth Mesh Model + * @ingroup bt_comp + * @{ + */ + +/* Foundation Models */ +#define BT_MESH_MODEL_ID_CFG_SRV 0x0000 +#define BT_MESH_MODEL_ID_CFG_CLI 0x0001 +#define BT_MESH_MODEL_ID_HEALTH_SRV 0x0002 +#define BT_MESH_MODEL_ID_HEALTH_CLI 0x0003 + +/* Models from the Mesh Model Specification */ +#define BT_MESH_MODEL_ID_GEN_ONOFF_SRV 0x1000 +#define BT_MESH_MODEL_ID_GEN_ONOFF_CLI 0x1001 +#define BT_MESH_MODEL_ID_GEN_LEVEL_SRV 0x1002 +#define BT_MESH_MODEL_ID_GEN_LEVEL_CLI 0x1003 +#define BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV 0x1004 +#define BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI 0x1005 +#define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV 0x1006 +#define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV 0x1007 +#define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI 0x1008 +#define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV 0x1009 +#define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV 0x100a +#define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_CLI 0x100b +#define BT_MESH_MODEL_ID_GEN_BATTERY_SRV 0x100c +#define BT_MESH_MODEL_ID_GEN_BATTERY_CLI 0x100d +#define BT_MESH_MODEL_ID_GEN_LOCATION_SRV 0x100e +#define BT_MESH_MODEL_ID_GEN_LOCATION_SETUPSRV 0x100f +#define BT_MESH_MODEL_ID_GEN_LOCATION_CLI 0x1010 +#define BT_MESH_MODEL_ID_GEN_ADMIN_PROP_SRV 0x1011 +#define BT_MESH_MODEL_ID_GEN_MANUFACTURER_PROP_SRV 0x1012 +#define BT_MESH_MODEL_ID_GEN_USER_PROP_SRV 0x1013 +#define BT_MESH_MODEL_ID_GEN_CLIENT_PROP_SRV 0x1014 +#define BT_MESH_MODEL_ID_GEN_PROP_CLI 0x1015 +#define BT_MESH_MODEL_ID_SENSOR_SRV 0x1100 +#define BT_MESH_MODEL_ID_SENSOR_SETUP_SRV 0x1101 +#define BT_MESH_MODEL_ID_SENSOR_CLI 0x1102 +#define BT_MESH_MODEL_ID_TIME_SRV 0x1200 +#define BT_MESH_MODEL_ID_TIME_SETUP_SRV 0x1201 +#define BT_MESH_MODEL_ID_TIME_CLI 0x1202 +#define BT_MESH_MODEL_ID_SCENE_SRV 0x1203 +#define BT_MESH_MODEL_ID_SCENE_SETUP_SRV 0x1204 +#define BT_MESH_MODEL_ID_SCENE_CLI 0x1205 +#define BT_MESH_MODEL_ID_SCHEDULER_SRV 0x1206 +#define BT_MESH_MODEL_ID_SCHEDULER_SETUP_SRV 0x1207 +#define BT_MESH_MODEL_ID_SCHEDULER_CLI 0x1208 +#define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV 0x1300 +#define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV 0x1301 +#define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_CLI 0x1302 +#define BT_MESH_MODEL_ID_LIGHT_CTL_SRV 0x1303 +#define BT_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV 0x1304 +#define BT_MESH_MODEL_ID_LIGHT_CTL_CLI 0x1305 +#define BT_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV 0x1306 +#define BT_MESH_MODEL_ID_LIGHT_HSL_SRV 0x1307 +#define BT_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV 0x1308 +#define BT_MESH_MODEL_ID_LIGHT_HSL_CLI 0x1309 +#define BT_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV 0x130a +#define BT_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV 0x130b +#define BT_MESH_MODEL_ID_LIGHT_XYL_SRV 0x130c +#define BT_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV 0x130d +#define BT_MESH_MODEL_ID_LIGHT_XYL_CLI 0x130e +#define BT_MESH_MODEL_ID_LIGHT_LC_SRV 0x130f +#define BT_MESH_MODEL_ID_LIGHT_LC_SETUPSRV 0x1310 +#define BT_MESH_MODEL_ID_LIGHT_LC_CLI 0x1311 + +/** Message sending context. */ +struct bt_mesh_msg_ctx +{ + /** NetKey Index of the subnet to send the message on. */ + u16_t net_idx; + + /** AppKey Index to encrypt the message with. */ + u16_t app_idx; + + /** Remote address. */ + u16_t addr; + + /** Received TTL value. Not used for sending. */ + u8_t recv_ttl :7; + + /** Whether friend credentials are used. */ + u8_t friend_cred :1; + + /** TTL, or BT_MESH_TTL_DEFAULT for default TTL. */ + u8_t send_ttl; +}; + +struct bt_mesh_model_op +{ + /* OpCode encoded using the BT_MESH_MODEL_OP_* macros */ + const u32_t opcode; + + /* Minimum required message length */ + const size_t min_len; + + /* Message handler for the opcode */ + void + (* const func)(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf); +}; + +#define BT_MESH_MODEL_OP_1(b0) (b0) +#define BT_MESH_MODEL_OP_2(b0, b1) (((b0) << 8) | (b1)) +#define BT_MESH_MODEL_OP_3(b0, cid) ((((b0) << 16) | 0xc00000) | (cid)) + +#define BT_MESH_MODEL_OP_END { 0, 0, NULL } +#define BT_MESH_MODEL_NO_OPS ((struct bt_mesh_model_op []) \ + { BT_MESH_MODEL_OP_END }) + +/** Helper to define an empty model array */ +#define BT_MESH_MODEL_EMPTY ((struct bt_mesh_model []){}) + +#define BT_MESH_MODEL(_id, _op, _pub, _user_data) \ +{ \ + .id = (_id), \ + .op = _op, \ + .keys = { [0 ... (MYNEWT_VAL(BLE_MESH_MODEL_KEY_COUNT) - 1)] = \ + BT_MESH_KEY_UNUSED }, \ + .pub = _pub, \ + .groups = { [0 ... (MYNEWT_VAL(BLE_MESH_MODEL_GROUP_COUNT) - 1)] = \ + BT_MESH_ADDR_UNASSIGNED }, \ + .user_data = _user_data, \ +} + +#define BT_MESH_MODEL_VND(_company, _id, _op, _pub, _user_data) \ +{ \ + .vnd.company = (_company), \ + .vnd.id = (_id), \ + .op = _op, \ + .pub = _pub, \ + .keys = { [0 ... (MYNEWT_VAL(BLE_MESH_MODEL_KEY_COUNT) - 1)] = \ + BT_MESH_KEY_UNUSED }, \ + .groups = { [0 ... (MYNEWT_VAL(BLE_MESH_MODEL_GROUP_COUNT) - 1)] = \ + BT_MESH_ADDR_UNASSIGNED }, \ + .user_data = _user_data, \ +} + +/** Mesh Configuration Server Model Context */ +struct bt_mesh_cfg +{ + struct bt_mesh_model *model; + + u8_t net_transmit; /* Network Transmit state */ + u8_t relay; /* Relay Mode state */ + u8_t relay_retransmit; /* Relay Retransmit state */ + u8_t beacon; /* Secure Network Beacon state */ + u8_t gatt_proxy; /* GATT Proxy state */ + u8_t frnd; /* Friend state */ + u8_t default_ttl; /* Default TTL */ + + /* Heartbeat Publication */ + struct + { + struct k_delayed_work timer; + + u16_t dst;u16_t count;u8_t period;u8_t ttl;u16_t feat;u16_t net_idx; + } hb_pub; + + /* Heartbeat Subscription */ + struct + { + s64_t expiry; + + u16_t src;u16_t dst;u16_t count;u8_t min_hops;u8_t max_hops; + + /* Optional subscription tracking function */ + void + (*func)(u8_t hops, u16_t feat); + } hb_sub; +}; + +extern const struct bt_mesh_model_op bt_mesh_cfg_op[]; + +#define BT_MESH_MODEL_CFG_SRV(srv_data) \ + BT_MESH_MODEL(BT_MESH_MODEL_ID_CFG_SRV, \ + bt_mesh_cfg_op, NULL, srv_data) + +/** @def BT_MESH_TRANSMIT + * + * @brief Encode transmission count & interval steps. + * + * @param count Number of retransmissions (first transmission is excluded). + * @param int_ms Interval steps in milliseconds. Must be greater than 0 + * and a multiple of 10. + * + * @return Mesh transmit value that can be used e.g. for the default + * values of the configuration model data. + */ +#define BT_MESH_TRANSMIT(count, int_ms) ((count) | (((int_ms / 10) - 1) << 3)) + +/** Mesh Health Server Model Context */ +struct bt_mesh_health +{ + struct bt_mesh_model *model; + + /* Health Period (divider) */ + u8_t period; + + /* Fetch current faults */ + int + (*fault_get_cur)(struct bt_mesh_model *model, u8_t *test_id, + u16_t *company_id, + u8_t *faults, + u8_t *fault_count); + + /* Fetch registered faults */ + int + (*fault_get_reg)(struct bt_mesh_model *model, u16_t company_id, + u8_t *test_id, + u8_t *faults, + u8_t *fault_count); + + /* Clear registered faults */ + int + (*fault_clear)(struct bt_mesh_model *model, u16_t company_id); + + /* Run a specific test */ + int + (*fault_test)(struct bt_mesh_model *model, u8_t test_id, + u16_t company_id); + + /* Attention Timer state */ + struct + { + struct k_delayed_work timer; + void + (*on)(struct bt_mesh_model *model); + void + (*off)(struct bt_mesh_model *model); + } attention; +}; + +int +bt_mesh_fault_update(struct bt_mesh_elem *elem); + +extern const struct bt_mesh_model_op bt_mesh_health_op[]; +extern struct bt_mesh_model_pub bt_mesh_health_pub; + +#define BT_MESH_MODEL_HEALTH_SRV(srv_data) \ + BT_MESH_MODEL(BT_MESH_MODEL_ID_HEALTH_SRV, \ + bt_mesh_health_op, &bt_mesh_health_pub, \ + srv_data) + +struct bt_mesh_model_pub +{ + /* Self-reference for easy lookup */ + struct bt_mesh_model *mod; + + u16_t addr; /* Publish Address */ + u16_t key; /* Publish AppKey Index */ + + u32_t ttl :8, /* Publish Time to Live */ + retransmit :8, /* Retransmit Count & Interval Steps */ + period :8, /* Publish Period */ + period_div :4, /* Divisor for the Period */ + cred :1; /* Friendship Credentials Flag */ + + /* Publish callback */ + void + (*func)(struct bt_mesh_model *mod); + + /* Publish Period Timer */ + struct k_delayed_work timer; +}; + +/** Abstraction that describes a Mesh Model instance */ +struct bt_mesh_model +{ + union + { + const u16_t id; + struct + { + u16_t company;u16_t id; + } vnd; + }; + + /* The Element this Model belongs to */ + struct bt_mesh_elem *elem; + + /* Model Publication */ + struct bt_mesh_model_pub * const pub; + + /* AppKey List */ + u16_t keys[MYNEWT_VAL(BLE_MESH_MODEL_KEY_COUNT)]; + + /* Subscription List (group or virtual addresses) */ + u16_t groups[MYNEWT_VAL(BLE_MESH_MODEL_GROUP_COUNT)]; + + const struct bt_mesh_model_op * const op; + + /* Model-specific user data */ + void *user_data; +}; + +typedef void +(*bt_mesh_cb_t)(int err, void *cb_data); + +void +bt_mesh_model_msg_init(struct os_mbuf *msg, u32_t opcode); + +/** Special TTL value to request using configured default TTL */ +#define BT_MESH_TTL_DEFAULT 0xff + +/** Maximum allowed TTL value */ +#define BT_MESH_TTL_MAX 0x7f + +/** + * @brief Send an Access Layer message. + * + * @param model Mesh (client) Model that the message belongs to. + * @param ctx Message context, includes keys, TTL, etc. + * @param msg Access Layer payload (the actual message to be sent). + * @param cb Optional "message sent" callback. + * @param cb_data User data to be passed to the callback. + * + * @return 0 on success, or (negative) error code on failure. + */ +int +bt_mesh_model_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *msg, bt_mesh_cb_t cb, void *cb_data); + +/** + * @brief Send a model publication message. + * + * @param model Mesh (client) Model that's publishing the message. + * @param msg Access Layer message to publish. + * + * @return 0 on success, or (negative) error code on failure. + */ +int +bt_mesh_model_publish(struct bt_mesh_model *model, struct os_mbuf *msg); + +/** + * @} + */ + +/** Node Composition */ +struct bt_mesh_comp +{ + u16_t cid;u16_t pid;u16_t vid; + + size_t elem_count; + struct bt_mesh_elem *elem; +}; + +/** + * @} + */ + +/** + * @brief Bluetooth Mesh Provisioning + * @defgroup bt_mesh_prov Bluetooth Mesh Provisioning + * @ingroup bt_mesh + * @{ + */ + +typedef enum +{ + BT_MESH_NO_OUTPUT = 0, + BT_MESH_BLINK = BIT(0), + BT_MESH_BEEP = BIT(1), + BT_MESH_VIBRATE = BIT(2), + BT_MESH_DISPLAY_NUMBER = BIT(3), + BT_MESH_DISPLAY_STRING = BIT(4), +} bt_mesh_output_action; + +typedef enum +{ + BT_MESH_NO_INPUT = 0, + BT_MESH_PUSH = BIT(0), + BT_MESH_TWIST = BIT(1), + BT_MESH_ENTER_NUMBER = BIT(2), + BT_MESH_ENTER_STRING = BIT(3), +} bt_mesh_input_action; + +struct bt_mesh_prov +{ + const u8_t *uuid; + + u8_t *static_val;u8_t static_val_len; + + u8_t output_size;u16_t output_actions; + + u8_t input_size;u16_t input_actions; + + int + (*output_number)(bt_mesh_output_action act, u32_t num); + int + (*output_string)(const char *str); + + int + (*input)(bt_mesh_input_action act, u8_t size); + + void + (*complete)(void); +}; + +int +bt_mesh_input_string(const char *str); +int +bt_mesh_input_number(u32_t num); + +/** + * @} + */ + +/** + * @brief Bluetooth Mesh + * @defgroup bt_mesh Bluetooth Mesh + * @ingroup bluetooth + * @{ + */ + +/* Primary Network Key index */ +#define BT_MESH_NET_PRIMARY 0x000 + +#define BT_MESH_RELAY_DISABLED 0x00 +#define BT_MESH_RELAY_ENABLED 0x01 +#define BT_MESH_RELAY_NOT_SUPPORTED 0x02 + +#define BT_MESH_BEACON_DISABLED 0x00 +#define BT_MESH_BEACON_ENABLED 0x01 + +#define BT_MESH_GATT_PROXY_DISABLED 0x00 +#define BT_MESH_GATT_PROXY_ENABLED 0x01 +#define BT_MESH_GATT_PROXY_NOT_SUPPORTED 0x02 + +#define BT_MESH_FRIEND_DISABLED 0x00 +#define BT_MESH_FRIEND_ENABLED 0x01 +#define BT_MESH_FRIEND_NOT_SUPPORTED 0x02 + +#define BT_MESH_NODE_IDENTITY_STOPPED 0x00 +#define BT_MESH_NODE_IDENTITY_RUNNING 0x01 +#define BT_MESH_NODE_IDENTITY_NOT_SUPPORTED 0x02 + +/* Features */ +#define BT_MESH_FEAT_RELAY BIT(0) +#define BT_MESH_FEAT_PROXY BIT(1) +#define BT_MESH_FEAT_FRIEND BIT(2) +#define BT_MESH_FEAT_LOW_POWER BIT(3) + +/** @brief Initialize Mesh support + * + * @param own_addr_type Node address type + * @param prov Node provisioning information. + * @param comp Node Composition. + * + * @return Zero on success or (negative) error code otherwise. + */ +int +bt_mesh_init(uint8_t own_addr_type, const struct bt_mesh_prov *prov, + const struct bt_mesh_comp *comp); + +/** @brief Reset the state of the local Mesh node. + * + * Resets the state of the node, which in turn causes it to start sending + * out unprovisioned beacons. + */ +void +bt_mesh_reset(void); + +/** @brief Provision the local Mesh Node. + * + * This API should normally not be used directly by the application. The + * only exception is for testing purposes where manual provisioning is + * desired without an actual external provisioner. + * + * @param net_key Network Key + * @param net_idx Network Key Index + * @param flags Provisioning Flags + * @param iv_index IV Index + * @param seq Sequence Number (0 if newly provisioned). + * @param addr Primary element address + * @param dev_key Device Key + * + * @return Zero on success or (negative) error code otherwise. + */ +int +bt_mesh_provision(const u8_t net_key[16], u16_t net_idx, +u8_t flags, + u32_t iv_index, u32_t seq, + u16_t addr, + const u8_t dev_key[16]); + +/** @brief Toggle the Low Power feature of the local device + * + * Enables or disables the Low Power feature of the local device. This is + * exposed as a run-time feature, since the device might want to change + * this e.g. based on being plugged into a stable power source or running + * from a battery power source. + * + * @param enable true to enable LPN functionality, false to disable it. + * + * @return Zero on success or (negative) error code otherwise. + */ +int +bt_mesh_lpn_set(bool enable); + +/** + * @} + */ + +#endif /* __BT_MESH_H */ diff --git a/nimble/host/mesh/pkg.yml b/nimble/host/mesh/pkg.yml new file mode 100644 index 000000000..57993e948 --- /dev/null +++ b/nimble/host/mesh/pkg.yml @@ -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. +# + +pkg.name: net/nimble/host/mesh +pkg.description: Bluetooth Mesh +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - ble + - bluetooth + - mesh + +pkg.deps: + - kernel/os + - net/nimble + - util/mem + - net/nimble/host + - crypto/tinycrypt + +pkg.req_apis: + - log + - stats diff --git a/nimble/host/mesh/src/Kconfig b/nimble/host/mesh/src/Kconfig deleted file mode 100644 index 3d06718f9..000000000 --- a/nimble/host/mesh/src/Kconfig +++ /dev/null @@ -1,377 +0,0 @@ -# Kconfig - Bluetooth Mesh configuration options - -# -# Copyright (c) 2017 Intel Corporation -# -# SPDX-License-Identifier: Apache-2.0 -# - -menuconfig BLUETOOTH_MESH - bool "Smart Mesh support" - select TINYCRYPT - select TINYCRYPT_AES - select TINYCRYPT_AES_CMAC - help - This option enables Smart Mesh support. The specific features - that will be available is dependent on other features that have - been enabled in the stack, such as GATT support. - -if BLUETOOTH_MESH - -# Virtual option enabled whenever Generic Provisioning layer is needed -config BLUETOOTH_MESH_PROV - bool - -config BLUETOOTH_MESH_PB_ADV - bool "Provisioning support using the advertising bearer (PB-ADV)" - select BLUETOOTH_MESH_PROV - default y - help - Enable this option to allow the device to be provisioned over - the advertising bearer. - -if BLUETOOTH_CONN - -# Virtual option enabled whenever any Proxy protocol is needed -config BLUETOOTH_MESH_PROXY - bool - -config BLUETOOTH_MESH_PB_GATT - bool "Provisioning support using GATT (PB-GATT)" - select BLUETOOTH_MESH_PROXY - select BLUETOOTH_MESH_PROV - help - Enable this option to allow the device to be provisioned over - GATT. - -config BLUETOOTH_MESH_GATT_PROXY - bool "GATT Proxy Service" - select BLUETOOTH_MESH_PROXY - help - This option enables support for the Mesh GATT Proxy Service, - i.e. the ability to act as a proxy between a Mesh GATT Client - and a Mesh network. - -if BLUETOOTH_MESH_PROXY - -config BLUETOOTH_MESH_PROXY_FILTER_SIZE - int "Maximum number of filter entries per Proxy Client" - default 1 - default 3 if BLUETOOTH_MESH_GATT_PROXY - range 1 32767 - help - This option specifies how many Proxy Filter entries the local - node supports. - -endif # BLUETOOTH_MESH_PROXY - -endif # BLUETOOTH_CONN - -config BLUETOOTH_MESH_LOCAL_INTERFACE - bool "Local network interface" - default y - help - This is needed in order to send messages between two local Mesh - elements. Only disable it if you're sure this will not be needed - (which helps save a little bit of memory). - -config BLUETOOTH_MESH_SELF_TEST - bool "Perform self-tests" - help - This option adds extra self-tests which are run every time - mesh networking is initialized. - -config BLUETOOTH_MESH_IV_UPDATE_TEST - bool "Test the IV Update Procedure" - help - This option removes the 96 hour limit of the IV Update - Procedure and lets the state be changed at any time. - -config BLUETOOTH_MESH_SUBNET_COUNT - int "Maximum number of mesh subnets per network" - default 1 - range 1 4096 - help - This option specifies how many subnets a Mesh network can - participate in at the same time. - -config BLUETOOTH_MESH_APP_KEY_COUNT - int "Maximum number of application keys per network" - default 1 - range 1 4096 - help - This option specifies how many application keys the device can - store per network. - -config BLUETOOTH_MESH_MODEL_KEY_COUNT - int "Maximum number of application keys per model" - default 1 - range 1 4096 - help - This option specifies how many application keys each model can - at most be bound to. - -config BLUETOOTH_MESH_MODEL_GROUP_COUNT - int "Maximum number of group address subscriptions per model" - default 1 - range 1 4096 - help - This option specifies how many group addresses each model can - at most be subscribed to. - -config BLUETOOTH_MESH_LABEL_COUNT - int "Maximum number of Label UUIDs used for Virtual Addresses" - default 1 - range 0 4096 - help - This option specifies how many Label UUIDs can be stored. - -config BLUETOOTH_MESH_CRPL - int "Maximum capacity of the replay protection list" - default 10 - range 2 65535 - help - This options specifies the maximum capacity of the replay - protection list. This option is similar to the network message - cache size, but has a different purpose. - -config BLUETOOTH_MESH_MSG_CACHE_SIZE - int "Network message cache size" - default 10 - range 2 65535 - help - Number of messages that are cached for the network. This helps - prevent unnecessary decryption operations and unnecessary - relays. This option is similar to the replay protection list, - but has a different purpose. - -config BLUETOOTH_MESH_ADV_BUF_COUNT - int "Number of advertising buffers" - default 6 - range 6 256 - help - Number of advertising buffers available. The transport layer - reserves ADV_BUF_COUNT - 3 buffers for outgoing segments. The - maximum outgoing SDU size is 12 times this number (out of which - 4 or 8 bytes is used for the Transport Layer MIC). For - example, 5 segments means the maximum SDU size is 60 bytes, - which leaves 56 bytes for application layer data using a - 4-byte MIC and 52 bytes using an 8-byte MIC. - -config BLUETOOTH_MESH_TX_SEG_MSG_COUNT - int "Maximum number of simultaneous outgoing segmented messages" - default 1 - range 1 BLUETOOTH_MESH_ADV_BUF_COUNT - help - Maximum number of simultaneous outgoing multi-segment and/or - reliable messages. - -config BLUETOOTH_MESH_RX_SEG_MSG_COUNT - int "Maximum number of simultaneous incoming segmented messages" - default 1 - range 1 255 - help - Maximum number of simultaneous incoming multi-segment and/or - reliable messages. - -config BLUETOOTH_MESH_RX_SDU_MAX - int "Maximum incoming Upper Transport Access PDU length" - default 384 - range 36 384 - help - Maximum incoming Upper Transport Access PDU length. Leave this - to the default value, unless you really need to optimize memory - usage. - -config BLUETOOTH_MESH_RELAY - bool "Relay support" - help - Support for acting as a Mesh Relay Node. - -config BLUETOOTH_MESH_LOW_POWER - bool "Support for Low Power features" - help - Enable this option to be able to act as a Low Power Node. - -if BLUETOOTH_MESH_LOW_POWER -config BLUETOOTH_MESH_LPN_RSSI_FACTOR - int "RSSIFactor, used in the Friend Offer Delay calculation" - range 0 3 - default 0 - help - The contribution of the RSSI measured by the Friend node used - in Friend Offer Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5. - -config BLUETOOTH_MESH_LPN_RECV_WIN_FACTOR - int "ReceiveWindowFactor, used in the Friend Offer Delay calculation" - range 0 3 - default 0 - help - The contribution of the supported Receive Window used in - Friend Offer Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5. - -config BLUETOOTH_MESH_LPN_MIN_QUEUE_SIZE - int "Minimum size of acceptable friend queue (MinQueueSizeLog)" - range 1 7 - default 1 - help - The MinQueueSizeLog field is defined as log_2(N), where N is - the minimum number of maximum size Lower Transport PDUs that - the Friend node can store in its Friend Queue. As an example, - MinQueueSizeLog value 1 gives N = 2, and value 7 gives N = 128. - -config BLUETOOTH_MESH_LPN_RECV_DELAY - int "Receive delay requested by the local node" - range 10 255 - default 20 - help - The ReceiveDelay is the time between the Low Power node - sending a request and listening for a response. This delay - allows the Friend node time to prepare the response. The value - is in units of milliseconds. - -config BLUETOOTH_MESH_LPN_POLL_TIMEOUT - int "The initial value of the PollTimeout timer" - range 10 244735 - default 100 - help - PollTimeout timer is used to measure time between two - consecutive requests sent by the Low Power node. If no - requests are received by the Friend node before the - PollTimeout timer expires, then the friendship is considered - terminated. The value is in units of 100 milliseconds. - -config BLUETOOTH_MESH_LPN_SCAN_LATENCY - int "Latency for enabling scanning" - range 0 50 - default 10 - help - Latency in milliseconds that it takes to enable scanning. This - is in practice how much time in advance before the Receive Window - that scanning is requested to be enabled. - -config BLUETOOTH_MESH_LPN_GROUPS - int "Number of groups the LPN can subscribe to" - range 0 16384 - default 8 - help - Maximum number of groups that the LPN can subscribe to. -endif # BLUETOOTH_MESH_LOW_POWER - -config BLUETOOTH_MESH_FRIEND - bool "Support for acting as a Friend Node" - help - Enable this option to be able to act as a Friend Node. - -if BLUETOOTH_MESH_FRIEND - -config BLUETOOTH_MESH_FRIEND_RECV_WIN - int "Friend Receive Window" - range 1 255 - default 255 - help - Receive Window in milliseconds supported by the Friend node. - -config BLUETOOTH_MESH_FRIEND_QUEUE_SIZE - int "Friend Queue Size" - range 1 BLUETOOTH_MESH_ADV_BUF_COUNT - default 16 - help - Queue Size available on the Friend node. - -config BLUETOOTH_MESH_FRIEND_SUB_LIST_SIZE - int "Friend Subscription List Size" - range 1 255 - default 16 - help - Size of the Subscription List that can be supported by a - Friend node for a Low Power node. - -config BLUETOOTH_MESH_FRIEND_LPN_COUNT - int "Number of supported LPN nodes" - range 1 1000 - default 1 - help - Number of Low Power Nodes the Friend can have a Friendship - with simultaneously. - -endif # BLUETOOTH_MESH_FRIEND - -config BLUETOOTH_MESH_DEBUG - bool "Enable debug logs" - depends on BLUETOOTH_DEBUG - help - Use this option to enable debug logs for the Bluetooth - Mesh functionality. - -if BLUETOOTH_MESH_DEBUG - -config BLUETOOTH_MESH_DEBUG_NET - bool "Network layer debug" - help - Use this option to enable Network layer debug logs for the - Bluetooth Mesh functionality. - -config BLUETOOTH_MESH_DEBUG_TRANS - bool "Transport layer debug" - help - Use this option to enable Transport layer debug logs for the - Bluetooth Mesh functionality. - -config BLUETOOTH_MESH_DEBUG_BEACON - bool "Beacon debug" - help - Use this option to enable Beacon-related debug logs for the - Bluetooth Mesh functionality. - -config BLUETOOTH_MESH_DEBUG_CRYPTO - bool "Crypto debug" - help - Use this option to enable cryptographic debug logs for the - Bluetooth Mesh functionality. - -config BLUETOOTH_MESH_DEBUG_PROV - bool "Provisioning debug" - help - Use this option to enable Provisioning debug logs for the - Bluetooth Mesh functionality. - -config BLUETOOTH_MESH_DEBUG_ACCESS - bool "Access layer debug" - help - Use this option to enable Access layer and device composition - related debug logs for Bluetooth Mesh. - -config BLUETOOTH_MESH_DEBUG_MODEL - bool "Foundation model debug" - help - Use this option to enable debug logs for the Foundation - Models. - -config BLUETOOTH_MESH_DEBUG_ADV - bool "Advertising debug" - help - Use this option to enable advertising debug logs for - the Bluetooth Mesh functionality. - -config BLUETOOTH_MESH_DEBUG_LOW_POWER - bool "Low Power debug" - help - Use this option to enable Low Power debug logs for the - Bluetooth Mesh functionality. - -config BLUETOOTH_MESH_DEBUG_FRIEND - bool "Friend debug" - help - Use this option to enable Friend debug logs for the - Bluetooth Mesh functionality. - -config BLUETOOTH_MESH_DEBUG_PROXY - bool "Proxy debug" - depends on BLUETOOTH_MESH_PROXY - help - Use this option to enable Proxy protocol debug logs. - -endif # BLUETOOTH_MESH_DEBUG - -endif # BLUETOOTH_MESH diff --git a/nimble/host/mesh/src/Makefile b/nimble/host/mesh/src/Makefile deleted file mode 100644 index e3a2b765f..000000000 --- a/nimble/host/mesh/src/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -ccflags-y +=-I$(srctree)/subsys/bluetooth - -obj-$(CONFIG_BLUETOOTH_MESH) += main.o \ - adv.o \ - beacon.o \ - net.o \ - transport.o \ - crypto.o \ - access.o \ - cfg.o \ - health.o \ - -obj-$(CONFIG_BLUETOOTH_MESH_LOW_POWER) += lpn.o - -obj-$(CONFIG_BLUETOOTH_MESH_FRIEND) += friend.o - -obj-$(CONFIG_BLUETOOTH_MESH_PROV) += prov.o - -obj-$(CONFIG_BLUETOOTH_MESH_PROXY) += proxy.o - -obj-$(CONFIG_BLUETOOTH_MESH_SELF_TEST) += test.o diff --git a/nimble/host/mesh/src/TODO b/nimble/host/mesh/src/TODO deleted file mode 100644 index cb5f4c4a2..000000000 --- a/nimble/host/mesh/src/TODO +++ /dev/null @@ -1,15 +0,0 @@ -Bluetooth Mesh implementation tasks -=================================== - - * Friend support - - * PB-GATT (Node) - - * GATT Proxy - - * Any generally useful models from the Model Specification - - * Mesh shell - - * Find a way to overlay provisioning memory with network memory - (linker magic?) diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index 848190afb..42fe03766 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -6,19 +6,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include -#include -#include -#include -#include -#include +#include +#include "mesh/mesh.h" -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_MESH_DEBUG_ACCESS) -#include "common/log.h" +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_ACCESS)) +#include "host/ble_hs_log.h" -#include "mesh.h" +#include "mesh_priv.h" #include "adv.h" #include "net.h" #include "lpn.h" @@ -94,11 +90,9 @@ s32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod) return period >> mod->pub->period_div; } -static void mod_publish(struct k_work *work) +static void mod_publish(struct os_event *work) { - struct bt_mesh_model_pub *pub = CONTAINER_OF(work, - struct bt_mesh_model_pub, - timer.work); + struct bt_mesh_model_pub *pub = work->ev_arg; s32_t period_ms; BT_DBG(""); @@ -293,12 +287,12 @@ static const struct bt_mesh_model_op *find_op(struct bt_mesh_model *models, return NULL; } -static int get_opcode(struct net_buf_simple *buf, u32_t *opcode) +static int get_opcode(struct os_mbuf *buf, u32_t *opcode) { - switch (buf->data[0] >> 6) { + switch (buf->om_data[0] >> 6) { case 0x00: case 0x01: - if (buf->data[0] == 0x7f) { + if (buf->om_data[0] == 0x7f) { BT_ERR("Ignoring RFU OpCode"); return -EINVAL; } @@ -306,7 +300,7 @@ static int get_opcode(struct net_buf_simple *buf, u32_t *opcode) *opcode = net_buf_simple_pull_u8(buf); return 0; case 0x02: - if (buf->len < 2) { + if (buf->om_len < 2) { BT_ERR("Too short payload for 2-octet OpCode"); return -EINVAL; } @@ -314,7 +308,7 @@ static int get_opcode(struct net_buf_simple *buf, u32_t *opcode) *opcode = net_buf_simple_pull_be16(buf); return 0; case 0x03: - if (buf->len < 3) { + if (buf->om_len < 3) { BT_ERR("Too short payload for 3-octet OpCode"); return -EINVAL; } @@ -345,7 +339,7 @@ bool bt_mesh_fixed_group_match(u16_t addr) } } -void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) +void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) { struct bt_mesh_model *models, *model; const struct bt_mesh_model_op *op; @@ -355,7 +349,7 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) BT_DBG("app_idx 0x%04x src 0x%04x dst 0x%04x", rx->ctx.app_idx, rx->ctx.addr, rx->dst); - BT_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("len %u: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); if (get_opcode(buf, &opcode) < 0) { BT_WARN("Unable to decode OpCode"); @@ -396,7 +390,7 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) if (op) { struct net_buf_simple_state state; - if (buf->len < op->min_len) { + if (buf->om_len < op->min_len) { BT_ERR("Too short message for OpCode 0x%08x", opcode); continue; @@ -416,7 +410,7 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) } } -void bt_mesh_model_msg_init(struct net_buf_simple *msg, u32_t opcode) +void bt_mesh_model_msg_init(struct os_mbuf *msg, u32_t opcode) { net_buf_simple_init(msg, 0); @@ -439,7 +433,7 @@ void bt_mesh_model_msg_init(struct net_buf_simple *msg, u32_t opcode) int bt_mesh_model_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *msg, bt_mesh_cb_t cb, + struct os_mbuf *msg, bt_mesh_cb_t cb, void *cb_data) { struct bt_mesh_net_tx tx = { @@ -455,14 +449,14 @@ int bt_mesh_model_send(struct bt_mesh_model *model, BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", ctx->net_idx, ctx->app_idx, ctx->addr); - BT_DBG("len %u: %s", msg->len, bt_hex(msg->data, msg->len)); + BT_DBG("len %u: %s", msg->om_len, bt_hex(msg->om_data, msg->om_len)); if (net_buf_simple_tailroom(msg) < 4) { BT_ERR("Not enough tailroom for TransMIC"); return -EINVAL; } - if (msg->len > BT_MESH_TX_SDU_MAX - 4) { + if (msg->om_len > BT_MESH_TX_SDU_MAX - 4) { BT_ERR("Too big message"); return -EMSGSIZE; } @@ -476,7 +470,7 @@ int bt_mesh_model_send(struct bt_mesh_model *model, } int bt_mesh_model_publish(struct bt_mesh_model *model, - struct net_buf_simple *msg) + struct os_mbuf *msg) { struct bt_mesh_app_key *key; struct bt_mesh_msg_ctx ctx; diff --git a/nimble/host/mesh/src/access.h b/nimble/host/mesh/src/access.h index 07b637056..bf07ad6ea 100644 --- a/nimble/host/mesh/src/access.h +++ b/nimble/host/mesh/src/access.h @@ -6,37 +6,56 @@ * SPDX-License-Identifier: Apache-2.0 */ -void bt_mesh_elem_register(struct bt_mesh_elem *elem, u8_t count); +#ifndef __ACCESS_H__ +#define __ACCESS_H__ -u8_t bt_mesh_elem_count(void); +#include "mesh/mesh.h" + +void +bt_mesh_elem_register(struct bt_mesh_elem *elem, u8_t count); + +u8_t +bt_mesh_elem_count(void); /* Find local element based on unicast or group address */ -struct bt_mesh_elem *bt_mesh_elem_find(u16_t addr); +struct bt_mesh_elem * +bt_mesh_elem_find(u16_t addr); -struct bt_mesh_model *bt_mesh_model_find_vnd(struct bt_mesh_elem *elem, - u16_t company, u16_t id); -struct bt_mesh_model *bt_mesh_model_find(struct bt_mesh_elem *elem, - u16_t id); +struct bt_mesh_model * +bt_mesh_model_find_vnd(struct bt_mesh_elem *elem, u16_t company, u16_t id); +struct bt_mesh_model * +bt_mesh_model_find(struct bt_mesh_elem *elem, u16_t id); -u16_t *bt_mesh_model_find_group(struct bt_mesh_model *mod, u16_t addr); +u16_t * +bt_mesh_model_find_group(struct bt_mesh_model *mod, u16_t addr); -bool bt_mesh_fixed_group_match(u16_t addr); +bool +bt_mesh_fixed_group_match(u16_t addr); -void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod, - struct bt_mesh_elem *elem, - bool vnd, bool primary, - void *user_data), - void *user_data); +void +bt_mesh_model_foreach( + void + (*func)(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, + bool primary, void *user_data), + void *user_data); -s32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod); +s32_t +bt_mesh_model_pub_period_get(struct bt_mesh_model *mod); -void bt_mesh_comp_provision(u16_t addr); -void bt_mesh_comp_unprovision(void); +void +bt_mesh_comp_provision(u16_t addr); +void +bt_mesh_comp_unprovision(void); -u16_t bt_mesh_primary_addr(void); +u16_t +bt_mesh_primary_addr(void); -const struct bt_mesh_comp *bt_mesh_comp_get(void); +const struct bt_mesh_comp * +bt_mesh_comp_get(void); -void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf); +void +bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf); -int bt_mesh_comp_register(const struct bt_mesh_comp *comp); +int +bt_mesh_comp_register(const struct bt_mesh_comp *comp); +#endif diff --git a/nimble/host/mesh/src/adv.c b/nimble/host/mesh/src/adv.c index 3964b8226..28d019d82 100644 --- a/nimble/host/mesh/src/adv.c +++ b/nimble/host/mesh/src/adv.c @@ -6,20 +6,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include +#include "mesh/mesh.h" -#include -#include -#include -#include -#include - -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_MESH_DEBUG_ADV) -#include "common/log.h" - -#include "../hci_core.h" +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_ADV)) +#include "host/ble_hs_log.h" +#include "host/ble_hs_adv.h" +#include "host/ble_gap.h" +#include "nimble/hci_common.h" #include "adv.h" #include "foundation.h" @@ -44,26 +37,27 @@ /* TinyCrypt PRNG consumes a lot of stack space, so we need to have * an increased call stack whenever it's used. */ -#if defined(CONFIG_BLUETOOTH_HOST_CRYPTO) #define ADV_STACK_SIZE 768 -#else -#define ADV_STACK_SIZE 512 -#endif -static K_FIFO_DEFINE(adv_queue); -static struct k_thread adv_thread_data; -static BT_STACK_NOINIT(adv_thread_stack, ADV_STACK_SIZE); +struct os_task adv_task; +static struct os_eventq adv_queue; +static uint8_t g_own_addr_type; + +static os_membuf_t adv_buf_mem[OS_MEMPOOL_SIZE( + MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT), + BT_MESH_ADV_DATA_SIZE + BT_MESH_ADV_USER_DATA_SIZE)]; + +struct os_mbuf_pool adv_os_mbuf_pool; +static struct os_mempool adv_buf_mempool; static const u8_t adv_type[] = { - [BT_MESH_ADV_PROV] = BT_DATA_MESH_PROV, - [BT_MESH_ADV_DATA] = BT_DATA_MESH_MESSAGE, - [BT_MESH_ADV_BEACON] = BT_DATA_MESH_BEACON, + [BT_MESH_ADV_PROV] = BLE_HS_ADV_TYPE_MESH_PROV, + [BT_MESH_ADV_DATA] = BLE_HS_ADV_TYPE_MESH_MESSAGE, + [BT_MESH_ADV_BEACON] = BLE_HS_ADV_TYPE_MESH_BEACON, }; -NET_BUF_POOL_DEFINE(adv_buf_pool, CONFIG_BLUETOOTH_MESH_ADV_BUF_COUNT, - BT_MESH_ADV_DATA_SIZE, sizeof(struct bt_mesh_adv), NULL); -static inline void adv_sent(struct net_buf *buf, int err) +static inline void adv_sent(struct os_mbuf *buf, int err) { if (BT_MESH_ADV(buf)->busy) { BT_MESH_ADV(buf)->busy = 0; @@ -76,140 +70,153 @@ static inline void adv_sent(struct net_buf *buf, int err) net_buf_unref(buf); } -static inline void adv_send(struct net_buf *buf) +static inline void adv_send(struct os_mbuf *buf) { - const s32_t adv_int_min = ((bt_dev.hci_version >= BT_HCI_VERSION_5_0) ? - ADV_INT_FAST : ADV_INT_DEFAULT); - struct bt_le_adv_param param; - u16_t duration, adv_int; - struct bt_data ad; - int err; + /* XXX: For BT5 we could have better adv interval */ + const s32_t adv_int_min = ADV_INT_DEFAULT; + struct ble_gap_adv_params param = { 0 }; + u16_t duration, adv_int; + struct bt_mesh_adv *adv = BT_MESH_ADV(buf); + struct bt_data ad; + int err; - adv_int = max(adv_int_min, BT_MESH_ADV(buf)->adv_int); - duration = (BT_MESH_ADV(buf)->count + 1) * (adv_int + 10); + adv_int = max(adv_int_min, adv->adv_int); + duration = (adv->count + 1) * (adv_int + 10); - BT_DBG("type %u len %u: %s", BT_MESH_ADV(buf)->type, - buf->len, bt_hex(buf->data, buf->len)); - BT_DBG("count %u interval %ums duration %ums", - BT_MESH_ADV(buf)->count + 1, adv_int, duration); + BT_DBG("buf %p, type %u len %u:", buf, adv->type, + buf->om_len); + BT_DBG("count %u interval %ums duration %ums", + adv->count + 1, adv_int, duration); - ad.type = adv_type[BT_MESH_ADV(buf)->type]; - ad.data_len = buf->len; - ad.data = buf->data; + ad.type = adv_type[BT_MESH_ADV(buf)->type]; + ad.data_len = buf->om_len; + ad.data = buf->om_data; - param.options = 0; - param.interval_min = ADV_INT(adv_int); - param.interval_max = param.interval_min; - param.own_addr = NULL; + param.itvl_min = ADV_INT(adv_int); + param.itvl_max = param.itvl_min; + param.conn_mode = BLE_GAP_CONN_MODE_NON; - err = bt_le_adv_start(¶m, &ad, 1, NULL, 0); - adv_sent(buf, err); - if (err) { - BT_ERR("Advertising failed: err %d", err); - return; - } + err = bt_le_adv_start(¶m, &ad, 1, NULL, 0); + adv_sent(buf, err); + if (err) { + BT_ERR("Advertising failed: err %d", err); + return; + } - BT_DBG("Advertising started. Sleeping %u ms", duration); + BT_DBG("Advertising started. Sleeping %u ms", duration); - k_sleep(duration); + os_time_delay(OS_TICKS_PER_SEC * duration / 1000); - err = bt_le_adv_stop(); - if (err) { - BT_ERR("Stopping advertising failed: err %d", err); - return; - } + err = bt_le_adv_stop(); + if (err) { + BT_ERR("Stopping advertising failed: err %d", err); + return; + } - BT_DBG("Advertising stopped"); + BT_DBG("Advertising stopped"); } -static void adv_thread(void *p1, void *p2, void *p3) +static void +adv_thread(void *args) { - BT_DBG("started"); + static struct os_event *ev; + struct os_mbuf *adv_data; + struct bt_mesh_adv *adv; +#if (MYNEWT_VAL(BLE_MESH_PROXY)) + s32_t timeout; + struct os_eventq *eventq_pool = &adv_queue; +#endif - while (1) { - struct net_buf *buf; + BT_DBG("started"); - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_PROXY)) { - buf = net_buf_get(&adv_queue, K_NO_WAIT); - while (!buf) { - s32_t timeout; + while (1) { +#if (MYNEWT_VAL(BLE_MESH_PROXY)) + ev = os_eventq_get_no_wait(&adv_queue); + while (!ev) { + timeout = bt_mesh_proxy_adv_start(); + BT_DBG("Proxy Advertising up to %d ms", timeout); - timeout = bt_mesh_proxy_adv_start(); - BT_DBG("Proxy Advertising up to %d ms", - timeout); - buf = net_buf_get(&adv_queue, timeout); - bt_mesh_proxy_adv_stop(); - } - } else { - buf = net_buf_get(&adv_queue, K_FOREVER); - } + // FIXME: should we redefine K_SECONDS macro instead in glue? + if (timeout != K_FOREVER) { + timeout = OS_TICKS_PER_SEC * timeout / 1000; + } - if (!buf) { - continue; - } + ev = os_eventq_poll(&eventq_pool, 1, timeout); + bt_mesh_proxy_adv_stop(); + } +#else + ev = os_eventq_get(&adv_queue); +#endif - /* busy == 0 means this was canceled */ - if (BT_MESH_ADV(buf)->busy) { - adv_send(buf); - } + if (!ev || !ev->ev_arg) { + continue; + } - STACK_ANALYZE("adv stack", adv_thread_stack); - k_call_stacks_analyze(); + adv_data = ev->ev_arg; + adv = BT_MESH_ADV(adv_data); - /* Give other threads a chance to run */ - k_yield(); - } + /* busy == 0 means this was canceled */ + if (adv->busy) { + adv_send(adv_data); + } + + os_sched(NULL); + } } void bt_mesh_adv_update(void) { + static struct os_event ev = { }; + BT_DBG(""); - k_fifo_cancel_wait(&adv_queue); + os_eventq_put(&adv_queue, &ev); } -struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit_count, +struct os_mbuf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit_count, u8_t xmit_int, s32_t timeout) { - struct bt_mesh_adv *adv; - struct net_buf *buf; + struct os_mbuf *adv_data; + struct bt_mesh_adv *adv; - buf = net_buf_alloc(&adv_buf_pool, timeout); - if (!buf) { - return NULL; - } + adv_data = os_mbuf_get_pkthdr(&adv_os_mbuf_pool, sizeof(struct bt_mesh_adv)); + if (!adv_data) { + return NULL; + } - adv = net_buf_user_data(buf); - memset(adv, 0, sizeof(*adv)); + adv = BT_MESH_ADV(adv_data); + memset(adv, 0, sizeof(*adv)); - adv->type = type; - adv->count = xmit_count; - adv->adv_int = xmit_int; - - return buf; + adv->type = type; + adv->count = xmit_count; + adv->adv_int = xmit_int; + adv->ref_cnt = 1; + adv->ev.ev_arg = adv_data; + return adv_data; } -void bt_mesh_adv_send(struct net_buf *buf, bt_mesh_adv_func_t sent) +void bt_mesh_adv_send(struct os_mbuf *buf, bt_mesh_adv_func_t sent) { - BT_DBG("type 0x%02x len %u: %s", BT_MESH_ADV(buf)->type, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("buf %p, type 0x%02x len %u: %s", buf, BT_MESH_ADV(buf)->type, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); BT_MESH_ADV(buf)->sent = sent; BT_MESH_ADV(buf)->busy = 1; + BT_MESH_ADV(buf)->ev.ev_cb = NULL; /* does not matter */ net_buf_put(&adv_queue, net_buf_ref(buf)); } static void bt_mesh_scan_cb(const bt_addr_le_t *addr, s8_t rssi, - u8_t adv_type, struct net_buf_simple *buf) + u8_t adv_type, struct os_mbuf *buf) { - if (adv_type != BT_LE_ADV_NONCONN_IND) { + if (adv_type != BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) { return; } - BT_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("len %u: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); - while (buf->len > 1) { + while (buf->om_len > 1) { struct net_buf_simple_state state; u8_t len, type; @@ -219,7 +226,7 @@ static void bt_mesh_scan_cb(const bt_addr_le_t *addr, s8_t rssi, return; } - if (len > buf->len || buf->len < 1) { + if (len > buf->om_len || buf->om_len < 1) { BT_WARN("AD malformed"); return; } @@ -228,18 +235,16 @@ static void bt_mesh_scan_cb(const bt_addr_le_t *addr, s8_t rssi, type = net_buf_simple_pull_u8(buf); - buf->len = len - 1; - switch (type) { - case BT_DATA_MESH_MESSAGE: + case BLE_HS_ADV_TYPE_MESH_MESSAGE: bt_mesh_net_recv(buf, rssi, BT_MESH_NET_IF_ADV); break; -#if defined(CONFIG_BLUETOOTH_MESH_PB_ADV) - case BT_DATA_MESH_PROV: +#if MYNEWT_VAL(BLE_MESH_PB_ADV) + case BLE_HS_ADV_TYPE_MESH_PROV: bt_mesh_pb_adv_recv(buf); break; #endif - case BT_DATA_MESH_BEACON: + case BLE_HS_ADV_TYPE_MESH_BEACON: bt_mesh_beacon_recv(buf); break; default: @@ -251,29 +256,93 @@ static void bt_mesh_scan_cb(const bt_addr_le_t *addr, s8_t rssi, } } -void bt_mesh_adv_init(void) +void bt_mesh_adv_init(uint8_t own_addr_type) { - k_thread_create(&adv_thread_data, adv_thread_stack, - sizeof(adv_thread_stack), adv_thread, - NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); + os_stack_t *pstack; + int rc; + + pstack = malloc(sizeof(os_stack_t) * ADV_STACK_SIZE); + assert(pstack); + + g_own_addr_type = own_addr_type; + + rc = os_mempool_init(&adv_buf_mempool, MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT), + BT_MESH_ADV_DATA_SIZE + BT_MESH_ADV_USER_DATA_SIZE, + adv_buf_mem, "adv_buf_pool"); + assert(rc == 0); + + rc = os_mbuf_pool_init(&adv_os_mbuf_pool, &adv_buf_mempool, + BT_MESH_ADV_DATA_SIZE + BT_MESH_ADV_USER_DATA_SIZE, + MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT)); + assert(rc == 0); + + os_eventq_init(&adv_queue); + + os_task_init(&adv_task, "mesh_adv", adv_thread, NULL, + MYNEWT_VAL(BLE_MESH_ADV_TASK_PRIO), OS_WAIT_FOREVER, pstack, + ADV_STACK_SIZE); +} + +int +ble_adv_gap_mesh_cb(struct ble_gap_event *event, void *arg) +{ +#if MYNEWT_VAL(BLE_EXT_ADV) + struct ble_gap_ext_disc_desc *ext_desc; +#endif + struct ble_gap_disc_desc *desc; + struct os_mbuf *buf = NULL; + + BT_DBG("event->type %d", event->type); + + switch (event->type) { +#if MYNEWT_VAL(BLE_EXT_ADV) + case BLE_GAP_EVENT_EXT_DISC: + ext_desc = &event->ext_disc; + buf = os_mbuf_get_pkthdr(&adv_os_mbuf_pool, 0); + if (!buf || os_mbuf_append(buf, ext_desc->data, ext_desc->length_data)) { + BT_ERR("Could not append data"); + goto done; + } + bt_mesh_scan_cb(&ext_desc->addr, ext_desc->rssi, + ext_desc->legacy_event_type, buf); + break; +#endif + case BLE_GAP_EVENT_DISC: + desc = &event->disc; + buf = os_mbuf_get_pkthdr(&adv_os_mbuf_pool, 0); + if (!buf || os_mbuf_append(buf, desc->data, desc->length_data)) { + BT_ERR("Could not append data"); + goto done; + } + + bt_mesh_scan_cb(&desc->addr, desc->rssi, desc->event_type, buf); + break; + default: + break; + } + +done: + if (buf) { + os_mbuf_free_chain(buf); + } + + return 0; } int bt_mesh_scan_enable(void) { - struct bt_le_scan_param scan_param = { - .type = BT_HCI_LE_SCAN_PASSIVE, - .filter_dup = BT_HCI_LE_SCAN_FILTER_DUP_DISABLE, - .interval = MESH_SCAN_INTERVAL, - .window = MESH_SCAN_WINDOW }; + struct ble_gap_disc_params scan_param = + { .passive = 1, .filter_duplicates = 0, .itvl = + MESH_SCAN_INTERVAL, .window = MESH_SCAN_WINDOW }; - BT_DBG(""); + BT_DBG(""); - return bt_le_scan_start(&scan_param, bt_mesh_scan_cb); + return ble_gap_disc(g_own_addr_type, BLE_HS_FOREVER, &scan_param, NULL, NULL); } int bt_mesh_scan_disable(void) { BT_DBG(""); - return bt_le_scan_stop(); + return ble_gap_disc_cancel(); } diff --git a/nimble/host/mesh/src/adv.h b/nimble/host/mesh/src/adv.h index f8fa4b3d1..eb44d6a1b 100644 --- a/nimble/host/mesh/src/adv.h +++ b/nimble/host/mesh/src/adv.h @@ -6,49 +6,62 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef __ADV_H__ +#define __ADV_H__ + /* Maximum advertising data payload for a single data type */ -#define BT_MESH_ADV_DATA_SIZE 29 +#include "mesh/mesh.h" -#define BT_MESH_ADV(buf) ((struct bt_mesh_adv *)net_buf_user_data(buf)) +#define BT_MESH_ADV_DATA_SIZE 31 +#define BT_MESH_ADV_USER_DATA_SIZE (sizeof(struct os_mbuf_pkthdr) + \ + sizeof(struct bt_mesh_adv)) + \ + sizeof(struct os_mbuf) -enum bt_mesh_adv_type { - BT_MESH_ADV_PROV, - BT_MESH_ADV_DATA, - BT_MESH_ADV_BEACON, +#define BT_MESH_ADV(om) ((struct bt_mesh_adv *) OS_MBUF_USRHDR(om)) + +enum bt_mesh_adv_type +{ + BT_MESH_ADV_PROV, BT_MESH_ADV_DATA, BT_MESH_ADV_BEACON, }; -typedef void (*bt_mesh_adv_func_t)(struct net_buf *buf, int err); +typedef void +(*bt_mesh_adv_func_t)(struct os_mbuf *adv_data, int err); -struct bt_mesh_adv { - bt_mesh_adv_func_t sent; - u8_t type:2, - busy:1; - u8_t count:3, - adv_int:5; - union { - /* Generic User Data */ - u8_t user_data[2]; +struct bt_mesh_adv +{ + bt_mesh_adv_func_t sent; + u8_t type :2, busy :1; + u8_t count :3, adv_int :5; + union + { + /* Generic User Data */ + u8_t user_data[2]; - /* For transport layer segment sending */ - struct { - u8_t tx_id; - u8_t attempts:6, - new_key:1, - friend_cred:1; - } seg; - }; + /* For transport layer segment sending */ + struct + { + u8_t tx_id; + u8_t attempts :6, new_key :1, friend_cred :1; + } seg; + }; + + int ref_cnt; + struct os_event ev; }; /* xmit_count: Number of retransmissions, i.e. 0 == 1 transmission */ -struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit_count, - u8_t xmit_int, s32_t timeout); +struct os_mbuf * bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit_count, + u8_t xmit_int, s32_t timeout); -void bt_mesh_adv_send(struct net_buf *buf, bt_mesh_adv_func_t sent); +void bt_mesh_adv_send(struct os_mbuf *buf, bt_mesh_adv_func_t sent); void bt_mesh_adv_update(void); -void bt_mesh_adv_init(void); +void bt_mesh_adv_init(uint8_t own_addr_type); int bt_mesh_scan_enable(void); int bt_mesh_scan_disable(void); + +int ble_adv_gap_mesh_cb(struct ble_gap_event *event, void *arg); +#endif diff --git a/nimble/host/mesh/src/beacon.c b/nimble/host/mesh/src/beacon.c index 921bc8078..e665306bf 100644 --- a/nimble/host/mesh/src/beacon.c +++ b/nimble/host/mesh/src/beacon.c @@ -6,28 +6,24 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include -#include +#include +#include "os/os_mbuf.h" +#include "mesh/mesh.h" -#include -#include -#include -#include - -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_MESH_DEBUG_BEACON) -#include "common/log.h" +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_BEACON)) +#include "host/ble_hs_log.h" #include "adv.h" -#include "mesh.h" +#include #include "net.h" #include "prov.h" #include "crypto.h" #include "beacon.h" #include "foundation.h" -#define UNPROVISIONED_INTERVAL K_SECONDS(5) -#define PROVISIONED_INTERVAL K_SECONDS(10) +#define UNPROVISIONED_INTERVAL (K_SECONDS(5)) +#define PROVISIONED_INTERVAL (K_SECONDS(10)) #define BEACON_TYPE_UNPROVISIONED 0x00 #define BEACON_TYPE_SECURE 0x01 @@ -45,7 +41,7 @@ static struct k_delayed_work beacon_timer; static struct { u16_t net_idx; u8_t data[21]; -} beacon_cache[CONFIG_BLUETOOTH_MESH_SUBNET_COUNT]; +} beacon_cache[MYNEWT_VAL(BLE_MESH_SUBNET_COUNT)]; static struct bt_mesh_subnet *cache_check(u8_t data[21]) { @@ -72,7 +68,7 @@ static void cache_add(u8_t data[21], u16_t net_idx) memcpy(beacon_cache[net_idx].data, data, 21); } -static void beacon_complete(struct net_buf *buf, int err) +static void beacon_complete(struct os_mbuf *buf, int err) { struct bt_mesh_subnet *sub; @@ -85,7 +81,7 @@ static void beacon_complete(struct net_buf *buf, int err) #define BEACON_INTERVAL(sub) K_SECONDS(10 * ((sub)->beacons_last + 1)) void bt_mesh_beacon_create(struct bt_mesh_subnet *sub, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_subnet_keys *keys; u8_t flags; @@ -134,7 +130,7 @@ static int secure_beacon_send(void) for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; - struct net_buf *buf; + struct os_mbuf *buf; if (sub->net_idx == BT_MESH_KEY_UNUSED) { continue; @@ -153,7 +149,7 @@ static int secure_beacon_send(void) BT_MESH_ADV(buf)->user_data[0] = i; - bt_mesh_beacon_create(sub, &buf->b); + bt_mesh_beacon_create(sub, buf); bt_mesh_adv_send(buf, beacon_complete); net_buf_unref(buf); @@ -164,10 +160,10 @@ static int secure_beacon_send(void) static int unprovisioned_beacon_send(void) { -#if defined(CONFIG_BLUETOOTH_MESH_PB_ADV) - struct net_buf *buf; +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) + struct os_mbuf *buf; - BT_DBG(""); + BT_DBG("unprovisioned_beacon_send"); buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, UNPROV_XMIT_COUNT, UNPROV_XMIT_INT, K_NO_WAIT); @@ -180,12 +176,12 @@ static int unprovisioned_beacon_send(void) net_buf_add_mem(buf, bt_mesh_prov_get_uuid(), 16); /* OOB Info (2 bytes) + URI Hash (4 bytes) */ - memset(net_buf_add(buf, 2 + 4), 0, 2 + 4); + net_buf_add_zeros(buf, 2 + 4); bt_mesh_adv_send(buf, NULL); net_buf_unref(buf); -#endif /* CONFIG_BLUETOOTH_MESH_PB_ADV */ +#endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */ return 0; } @@ -215,10 +211,10 @@ static void update_beacon_observation(void) } } -static void beacon_send(struct k_work *work) +static void beacon_send(struct os_event *work) { /* Don't send anything if we have an active provisioning link */ - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_PROV) && bt_prov_active()) { + if ((MYNEWT_VAL(BLE_MESH_PROV)) && bt_prov_active()) { k_delayed_work_submit(&beacon_timer, UNPROVISIONED_INTERVAL); return; } @@ -242,7 +238,7 @@ static void beacon_send(struct k_work *work) } -static void secure_beacon_recv(struct net_buf_simple *buf) +static void secure_beacon_recv(struct os_mbuf *buf) { u8_t *data, *net_id, *auth; struct bt_mesh_subnet *sub; @@ -250,25 +246,25 @@ static void secure_beacon_recv(struct net_buf_simple *buf) u8_t flags; bool new_key; - if (buf->len < 21) { - BT_ERR("Too short secure beacon (len %u)", buf->len); + if (buf->om_len < 21) { + BT_ERR("Too short secure beacon (len %u)", buf->om_len); return; } - sub = cache_check(buf->data); + sub = cache_check(buf->om_data); if (sub) { /* We've seen this beacon before - just update the stats */ goto update_stats; } /* So we can add to the cache if auth matches */ - data = buf->data; + data = buf->om_data; flags = net_buf_simple_pull_u8(buf); - net_id = buf->data; + net_id = buf->om_data; net_buf_simple_pull(buf, 8); iv_index = net_buf_simple_pull_be32(buf); - auth = buf->data; + auth = buf->om_data; BT_DBG("flags 0x%02x id %s iv_index 0x%08x", flags, bt_hex(net_id, 8), iv_index); @@ -314,13 +310,13 @@ update_stats: } } -void bt_mesh_beacon_recv(struct net_buf_simple *buf) +void bt_mesh_beacon_recv(struct os_mbuf *buf) { u8_t type; - BT_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (buf->len < 1) { + if (buf->om_len < 1) { BT_ERR("Too short beacon"); return; } diff --git a/nimble/host/mesh/src/beacon.h b/nimble/host/mesh/src/beacon.h index afa08fdcb..35e47989e 100644 --- a/nimble/host/mesh/src/beacon.h +++ b/nimble/host/mesh/src/beacon.h @@ -6,14 +6,26 @@ * SPDX-License-Identifier: Apache-2.0 */ -void bt_mesh_beacon_enable(void); -void bt_mesh_beacon_disable(void); +#ifndef __BEACON_H__ +#define __BEACON_H__ -void bt_mesh_beacon_ivu_initiator(bool enable); +#include "os/os_mbuf.h" -void bt_mesh_beacon_recv(struct net_buf_simple *buf); +void +bt_mesh_beacon_enable(void); +void +bt_mesh_beacon_disable(void); -void bt_mesh_beacon_create(struct bt_mesh_subnet *sub, - struct net_buf_simple *buf); +void +bt_mesh_beacon_ivu_initiator(bool enable); -void bt_mesh_beacon_init(void); +void +bt_mesh_beacon_recv(struct os_mbuf *buf); + +void +bt_mesh_beacon_create(struct bt_mesh_subnet *sub, struct os_mbuf *buf); + +void +bt_mesh_beacon_init(void); + +#endif diff --git a/nimble/host/mesh/src/cfg.c b/nimble/host/mesh/src/cfg.c index 78ceaddf0..da55de975 100644 --- a/nimble/host/mesh/src/cfg.c +++ b/nimble/host/mesh/src/cfg.c @@ -6,22 +6,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include #include -#include -#include -#include -#include -#include -#include +#include "mesh/mesh.h" -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_MESH_DEBUG_MODEL) -#include "common/log.h" +#define BT_DBG_ENABLED MYNEWT_VAL(BLE_MESH_DEBUG_MODEL) +#include "host/ble_hs_log.h" -#include "mesh.h" +#include "mesh_priv.h" #include "adv.h" #include "net.h" #include "lpn.h" @@ -39,17 +33,17 @@ static struct bt_mesh_cfg *conf; static struct label { u16_t addr; u8_t uuid[16]; -} labels[CONFIG_BLUETOOTH_MESH_LABEL_COUNT]; +} labels[MYNEWT_VAL(BLE_MESH_LABEL_COUNT)]; -static inline void key_idx_unpack(struct net_buf_simple *buf, +static inline void key_idx_unpack(struct os_mbuf *buf, u16_t *idx1, u16_t *idx2) { - *idx1 = sys_get_le16(&buf->data[0]) & 0xfff; - *idx2 = sys_get_le16(&buf->data[1]) >> 4; + *idx1 = sys_get_le16(&buf->om_data[0]) & 0xfff; + *idx2 = sys_get_le16(&buf->om_data[1]) >> 4; net_buf_simple_pull(buf, 3); } -static inline void key_idx_pack(struct net_buf_simple *buf, +static inline void key_idx_pack(struct os_mbuf *buf, u16_t idx1, u16_t idx2) { net_buf_simple_add_le16(buf, idx1 | ((idx2 & 0x00f) << 12)); @@ -87,7 +81,7 @@ static void hb_send(struct bt_mesh_model *model) feat |= BT_MESH_FEAT_FRIEND; } -#if defined(CONFIG_BLUETOOTH_MESH_LOW_POWER) +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) if (bt_mesh.lpn.state != BT_MESH_LPN_DISABLED) { feat |= BT_MESH_FEAT_LOW_POWER; } @@ -100,7 +94,7 @@ static void hb_send(struct bt_mesh_model *model) bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb), NULL); } -static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem, +static int comp_add_elem(struct os_mbuf *buf, struct bt_mesh_elem *elem, bool primary) { struct bt_mesh_model *mod; @@ -131,7 +125,7 @@ static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem, return 0; } -static int comp_get_page_0(struct net_buf_simple *buf) +static int comp_get_page_0(struct os_mbuf *buf) { u16_t feat = 0; const struct bt_mesh_comp *comp; @@ -139,18 +133,18 @@ static int comp_get_page_0(struct net_buf_simple *buf) comp = bt_mesh_comp_get(); - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_RELAY)) { + if ((MYNEWT_VAL(BLE_MESH_RELAY))) { feat |= BT_MESH_FEAT_RELAY; } - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER)) { + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { feat |= BT_MESH_FEAT_LOW_POWER; } net_buf_simple_add_le16(buf, comp->cid); net_buf_simple_add_le16(buf, comp->pid); net_buf_simple_add_le16(buf, comp->vid); - net_buf_simple_add_le16(buf, CONFIG_BLUETOOTH_MESH_CRPL); + net_buf_simple_add_le16(buf, MYNEWT_VAL(BLE_MESH_CRPL)); net_buf_simple_add_le16(buf, feat); for (i = 0; i < comp->elem_count; i++) { @@ -167,14 +161,14 @@ static int comp_get_page_0(struct net_buf_simple *buf) static void dev_comp_data_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct net_buf_simple *sdu = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); + struct os_mbuf *sdu = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); u8_t page; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); page = net_buf_simple_pull_u8(buf); if (page != 0) { @@ -187,18 +181,21 @@ static void dev_comp_data_get(struct bt_mesh_model *model, net_buf_simple_add_u8(sdu, page); if (comp_get_page_0(sdu) < 0) { BT_ERR("Unable to get composition page 0"); - return; + goto done; } if (bt_mesh_model_send(model, ctx, sdu, NULL, NULL)) { BT_ERR("Unable to send Device Composition Status response"); } + +done: + os_mbuf_free_chain(sdu); } static struct bt_mesh_model *get_model(struct bt_mesh_elem *elem, - struct net_buf_simple *buf, bool *vnd) + struct os_mbuf *buf, bool *vnd) { - if (buf->len < 4) { + if (buf->om_len < 4) { u16_t id; id = net_buf_simple_pull_le16(buf); @@ -247,7 +244,7 @@ static u8_t _mod_pub_set(struct bt_mesh_model *model, u16_t pub_addr, return STATUS_NVAL_PUB_PARAM; } - if (!IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER) && cred_flag) { + if (!(MYNEWT_VAL(BLE_MESH_LOW_POWER)) && cred_flag) { return STATUS_FEAT_NOT_SUPP; } @@ -453,9 +450,9 @@ static u8_t app_key_set(u16_t net_idx, u16_t app_idx, const u8_t val[16], static void app_key_add(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 4 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); u16_t key_net_idx, key_app_idx; u8_t status; @@ -465,7 +462,7 @@ static void app_key_add(struct bt_mesh_model *model, bt_mesh_model_msg_init(msg, OP_APP_KEY_STATUS); - status = app_key_set(key_net_idx, key_app_idx, buf->data, false); + status = app_key_set(key_net_idx, key_app_idx, buf->om_data, false); BT_DBG("status 0x%02x", status); net_buf_simple_add_u8(msg, status); @@ -474,13 +471,15 @@ static void app_key_add(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send App Key Status response"); } + + os_mbuf_free_chain(msg); } static void app_key_update(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 4 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); u16_t key_net_idx, key_app_idx; u8_t status; @@ -490,7 +489,7 @@ static void app_key_update(struct bt_mesh_model *model, bt_mesh_model_msg_init(msg, OP_APP_KEY_STATUS); - status = app_key_set(key_net_idx, key_app_idx, buf->data, true); + status = app_key_set(key_net_idx, key_app_idx, buf->om_data, true); BT_DBG("status 0x%02x", status); net_buf_simple_add_u8(msg, status); @@ -499,6 +498,8 @@ static void app_key_update(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send App Key Status response"); } + + os_mbuf_free_chain(msg); } static void _mod_unbind(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, @@ -519,9 +520,9 @@ static void _app_key_del(struct bt_mesh_app_key *key) static void app_key_del(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 4 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); u16_t key_net_idx, key_app_idx; struct bt_mesh_app_key *key; u8_t status; @@ -562,6 +563,8 @@ send_status: if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send App Key Status response"); } + + os_mbuf_free_chain(msg); } /* Index list length: 3 bytes for every pair and 2 bytes for an odd idx */ @@ -569,18 +572,18 @@ send_status: static void app_key_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct net_buf_simple *msg = + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 3 + 4 + - IDX_LEN(CONFIG_BLUETOOTH_MESH_APP_KEY_COUNT)); + IDX_LEN(MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT))); u16_t get_idx, i, prev; u8_t status; get_idx = net_buf_simple_pull_le16(buf); if (get_idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", get_idx); - return; + goto done; } BT_DBG("idx 0x%04x", get_idx); @@ -625,18 +628,21 @@ send_status: if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send AppKey List"); } + +done: + os_mbuf_free_chain(msg); } static void beacon_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); bt_mesh_model_msg_init(msg, OP_BEACON_STATUS); net_buf_simple_add_u8(msg, bt_mesh_beacon_get()); @@ -644,25 +650,26 @@ static void beacon_get(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Config Beacon Status response"); } + os_mbuf_free_chain(msg); } static void beacon_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); struct bt_mesh_cfg *cfg = model->user_data; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); if (!cfg) { BT_WARN("No Configuration Server context available"); - } else if (buf->data[0] == 0x00 || buf->data[0] == 0x01) { - if (buf->data[0] != cfg->beacon) { - cfg->beacon = buf->data[0]; + } else if (buf->om_data[0] == 0x00 || buf->om_data[0] == 0x01) { + if (buf->om_data[0] != cfg->beacon) { + cfg->beacon = buf->om_data[0]; if (cfg->beacon) { bt_mesh_beacon_enable(); @@ -671,7 +678,7 @@ static void beacon_set(struct bt_mesh_model *model, } } } else { - BT_WARN("Invalid Config Beacon value 0x%02x", buf->data[0]); + BT_WARN("Invalid Config Beacon value 0x%02x", buf->om_data[0]); return; } @@ -681,18 +688,21 @@ static void beacon_set(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Config Beacon Status response"); } + + os_mbuf_free_chain(msg); + } static void default_ttl_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); bt_mesh_model_msg_init(msg, OP_DEFAULT_TTL_STATUS); net_buf_simple_add_u8(msg, bt_mesh_default_ttl_get()); @@ -700,27 +710,30 @@ static void default_ttl_get(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Default TTL Status response"); } + + os_mbuf_free_chain(msg); + } static void default_ttl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); struct bt_mesh_cfg *cfg = model->user_data; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); if (!cfg) { BT_WARN("No Configuration Server context available"); - } else if (buf->data[0] <= 0x7f && buf->data[0] != 0x01) { - cfg->default_ttl = buf->data[0]; + } else if (buf->om_data[0] <= 0x7f && buf->om_data[0] != 0x01) { + cfg->default_ttl = buf->om_data[0]; } else { - BT_WARN("Prohibited Default TTL value 0x%02x", buf->data[0]); - return; + BT_WARN("Prohibited Default TTL value 0x%02x", buf->om_data[0]); + goto done; } bt_mesh_model_msg_init(msg, OP_DEFAULT_TTL_STATUS); @@ -729,13 +742,16 @@ static void default_ttl_set(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Default TTL Status response"); } + +done: + os_mbuf_free_chain(msg); } static void send_gatt_proxy_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); bt_mesh_model_msg_init(msg, OP_GATT_PROXY_STATUS); net_buf_simple_add_u8(msg, bt_mesh_gatt_proxy_get()); @@ -743,36 +759,39 @@ static void send_gatt_proxy_status(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send GATT Proxy Status"); } + + os_mbuf_free_chain(msg); + } static void gatt_proxy_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); send_gatt_proxy_status(model, ctx); } static void gatt_proxy_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_cfg *cfg = model->user_data; struct bt_mesh_subnet *sub; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); - if (buf->data[0] != 0x00 && buf->data[0] != 0x01) { - BT_WARN("Invalid GATT Proxy value 0x%02x", buf->data[0]); + if (buf->om_data[0] != 0x00 && buf->om_data[0] != 0x01) { + BT_WARN("Invalid GATT Proxy value 0x%02x", buf->om_data[0]); return; } - if (!IS_ENABLED(CONFIG_BLUETOOTH_MESH_GATT_PROXY) || + if (!(MYNEWT_VAL(BLE_MESH_GATT_PROXY)) || bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_NOT_SUPPORTED) { goto send_status; } @@ -782,13 +801,13 @@ static void gatt_proxy_set(struct bt_mesh_model *model, goto send_status; } - BT_DBG("GATT Proxy 0x%02x -> 0x%02x", cfg->gatt_proxy, buf->data[0]); + BT_DBG("GATT Proxy 0x%02x -> 0x%02x", cfg->gatt_proxy, buf->om_data[0]); - if (cfg->gatt_proxy == buf->data[0]) { + if (cfg->gatt_proxy == buf->om_data[0]) { goto send_status; } - cfg->gatt_proxy = buf->data[0]; + cfg->gatt_proxy = buf->om_data[0]; sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx); if ((cfg->hb_pub.feat & BT_MESH_FEAT_PROXY) && sub) { @@ -801,14 +820,14 @@ send_status: static void net_transmit_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); bt_mesh_model_msg_init(msg, OP_NET_TRANSMIT_STATUS); net_buf_simple_add_u8(msg, bt_mesh_net_transmit_get()); @@ -816,27 +835,30 @@ static void net_transmit_get(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Config Network Transmit Status"); } + + os_mbuf_free_chain(msg); + } static void net_transmit_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); struct bt_mesh_cfg *cfg = model->user_data; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); - BT_DBG("Transmit 0x%02x (count %u interval %ums)", buf->data[0], - TRANSMIT_COUNT(buf->data[0]), TRANSMIT_INT(buf->data[0])); + BT_DBG("Transmit 0x%02x (count %u interval %ums)", buf->om_data[0], + TRANSMIT_COUNT(buf->om_data[0]), TRANSMIT_INT(buf->om_data[0])); if (!cfg) { BT_WARN("No Configuration Server context available"); } else { - cfg->net_transmit = buf->data[0]; + cfg->net_transmit = buf->om_data[0]; } bt_mesh_model_msg_init(msg, OP_NET_TRANSMIT_STATUS); @@ -845,18 +867,20 @@ static void net_transmit_set(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Network Transmit Status"); } + + os_mbuf_free_chain(msg); } static void relay_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 2 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4); BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); bt_mesh_model_msg_init(msg, OP_RELAY_STATUS); net_buf_simple_add_u8(msg, bt_mesh_relay_get()); @@ -865,40 +889,43 @@ static void relay_get(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Config Relay Status response"); } + + os_mbuf_free_chain(msg); + } static void relay_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 2 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4); struct bt_mesh_cfg *cfg = model->user_data; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); if (!cfg) { BT_WARN("No Configuration Server context available"); - } else if (buf->data[0] == 0x00 || buf->data[0] == 0x01) { + } else if (buf->om_data[0] == 0x00 || buf->om_data[0] == 0x01) { struct bt_mesh_subnet *sub; - cfg->relay = buf->data[0]; - cfg->relay_retransmit = buf->data[1]; + cfg->relay = buf->om_data[0]; + cfg->relay_retransmit = buf->om_data[1]; BT_DBG("Relay 0x%02x Retransmit 0x%02x (count %u interval %u)", cfg->relay, cfg->relay_retransmit, TRANSMIT_COUNT(cfg->relay_retransmit), - TRANSMIT_INT(cfg->relay_retransmit)) + TRANSMIT_INT(cfg->relay_retransmit)); sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx); if ((cfg->hb_pub.feat & BT_MESH_FEAT_RELAY) && sub) { hb_send(model); } } else { - BT_WARN("Invalid Relay value 0x%02x", buf->data[0]); - return; + BT_WARN("Invalid Relay value 0x%02x", buf->om_data[0]); + goto done; } bt_mesh_model_msg_init(msg, OP_RELAY_STATUS); @@ -908,6 +935,10 @@ static void relay_set(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Relay Status response"); } + +done: + os_mbuf_free_chain(msg); + } static void send_mod_pub_status(struct bt_mesh_model *cfg_mod, @@ -917,7 +948,7 @@ static void send_mod_pub_status(struct bt_mesh_model *cfg_mod, u8_t status, u8_t *mod_id) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 14 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 14 + 4); bt_mesh_model_msg_init(msg, OP_MOD_PUB_STATUS); @@ -945,11 +976,13 @@ static void send_mod_pub_status(struct bt_mesh_model *cfg_mod, } bt_mesh_model_send(cfg_mod, ctx, msg, NULL, NULL); + + os_mbuf_free_chain(msg); } static void mod_pub_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { u16_t elem_addr, pub_addr = 0; struct bt_mesh_model *mod; @@ -958,14 +991,14 @@ static void mod_pub_get(struct bt_mesh_model *model, bool vnd; elem_addr = net_buf_simple_pull_le16(buf); - mod_id = buf->data; + mod_id = buf->om_data; BT_DBG("elem_addr 0x%04x", elem_addr); elem = bt_mesh_elem_find(elem_addr); if (!elem) { mod = NULL; - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -991,7 +1024,7 @@ send_status: static void mod_pub_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { u8_t retransmit, status, pub_ttl, pub_period, cred_flag; u16_t elem_addr, pub_addr, pub_app_idx; @@ -1014,7 +1047,7 @@ static void mod_pub_set(struct bt_mesh_model *model, pub_period = net_buf_simple_pull_u8(buf); retransmit = net_buf_simple_pull_u8(buf); - mod_id = buf->data; + mod_id = buf->om_data; BT_DBG("elem_addr 0x%04x pub_addr 0x%04x cred_flag %u", elem_addr, pub_addr, cred_flag); @@ -1026,7 +1059,7 @@ static void mod_pub_set(struct bt_mesh_model *model, elem = bt_mesh_elem_find(elem_addr); if (!elem) { mod = NULL; - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -1045,7 +1078,7 @@ send_status: status, mod_id); } -#if CONFIG_BLUETOOTH_MESH_LABEL_COUNT > 0 +#if MYNEWT_VAL(BLE_MESH_LABEL_COUNT) > 0 static u16_t va_find(u8_t *label_uuid, struct label **free_slot) { int i; @@ -1095,7 +1128,7 @@ static u8_t va_add(u8_t *label_uuid, u16_t *addr) static void mod_pub_va_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { u8_t retransmit, status, pub_ttl, pub_period, cred_flag; u16_t elem_addr, pub_addr, pub_app_idx; @@ -1106,7 +1139,7 @@ static void mod_pub_va_set(struct bt_mesh_model *model, bool vnd; elem_addr = net_buf_simple_pull_le16(buf); - label_uuid = buf->data; + label_uuid = buf->om_data; net_buf_simple_pull(buf, 16); pub_app_idx = net_buf_simple_pull_le16(buf); @@ -1120,7 +1153,7 @@ static void mod_pub_va_set(struct bt_mesh_model *model, pub_period = net_buf_simple_pull_u8(buf); retransmit = net_buf_simple_pull_u8(buf); - mod_id = buf->data; + mod_id = buf->om_data; BT_DBG("elem_addr 0x%04x pub_addr 0x%04x cred_flag %u", elem_addr, pub_addr, cred_flag); @@ -1132,7 +1165,7 @@ static void mod_pub_va_set(struct bt_mesh_model *model, elem = bt_mesh_elem_find(elem_addr); if (!elem) { mod = NULL; - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); pub_addr = 0; status = STATUS_INVALID_ADDRESS; goto send_status; @@ -1158,7 +1191,7 @@ send_status: #else static void mod_pub_va_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { u8_t *mod_id, status; struct bt_mesh_model *mod; @@ -1175,7 +1208,7 @@ static void mod_pub_va_set(struct bt_mesh_model *model, elem = bt_mesh_elem_find(elem_addr); if (!elem) { mod = NULL; - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -1198,7 +1231,7 @@ send_status: send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, status, mod_id); } -#endif /* CONFIG_BLUETOOTH_MESH_LABEL_COUNT > 0 */ +#endif /* MYNEWT_VAL(BLE_MESH_LABEL_COUNT) > 0 */ static void send_mod_sub_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, u8_t status, @@ -1206,7 +1239,7 @@ static void send_mod_sub_status(struct bt_mesh_model *model, bool vnd) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 9 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4); bt_mesh_model_msg_init(msg, OP_MOD_SUB_STATUS); @@ -1225,11 +1258,12 @@ static void send_mod_sub_status(struct bt_mesh_model *model, } bt_mesh_model_send(model, ctx, msg, NULL, NULL); + os_mbuf_free_chain(msg); } static void mod_sub_add(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { u16_t elem_addr, sub_addr; struct bt_mesh_model *mod; @@ -1244,12 +1278,12 @@ static void mod_sub_add(struct bt_mesh_model *model, BT_DBG("elem_addr 0x%04x, sub_addr 0x%04x", elem_addr, sub_addr); - mod_id = buf->data; + mod_id = buf->om_data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { mod = NULL; - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -1283,7 +1317,7 @@ static void mod_sub_add(struct bt_mesh_model *model, } else { status = STATUS_SUCCESS; - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER)) { + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { bt_mesh_lpn_group_add(sub_addr); } } @@ -1295,7 +1329,7 @@ send_status: static void mod_sub_del(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { u16_t elem_addr, sub_addr; struct bt_mesh_model *mod; @@ -1310,12 +1344,12 @@ static void mod_sub_del(struct bt_mesh_model *model, BT_DBG("elem_addr 0x%04x sub_addr 0x%04x", elem_addr, sub_addr); - mod_id = buf->data; + mod_id = buf->om_data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { mod = NULL; - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -1336,7 +1370,7 @@ static void mod_sub_del(struct bt_mesh_model *model, */ status = STATUS_SUCCESS; - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER)) { + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { bt_mesh_lpn_group_del(&sub_addr, 1); } @@ -1352,7 +1386,7 @@ send_status: static void mod_sub_overwrite(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { u16_t elem_addr, sub_addr; struct bt_mesh_model *mod; @@ -1366,12 +1400,12 @@ static void mod_sub_overwrite(struct bt_mesh_model *model, BT_DBG("elem_addr 0x%04x sub_addr 0x%04x", elem_addr, sub_addr); - mod_id = buf->data; + mod_id = buf->om_data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { mod = NULL; - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -1387,7 +1421,7 @@ static void mod_sub_overwrite(struct bt_mesh_model *model, goto send_status; } - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER)) { + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { bt_mesh_lpn_group_del(mod->groups, ARRAY_SIZE(mod->groups)); } @@ -1398,7 +1432,7 @@ static void mod_sub_overwrite(struct bt_mesh_model *model, mod->groups[0] = sub_addr; status = STATUS_SUCCESS; - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER)) { + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { bt_mesh_lpn_group_add(sub_addr); } } else { @@ -1413,7 +1447,7 @@ send_status: static void mod_sub_del_all(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_model *mod; struct bt_mesh_elem *elem; @@ -1426,12 +1460,12 @@ static void mod_sub_del_all(struct bt_mesh_model *model, BT_DBG("elem_addr 0x%04x", elem_addr); - mod_id = buf->data; + mod_id = buf->om_data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { mod = NULL; - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -1442,7 +1476,7 @@ static void mod_sub_del_all(struct bt_mesh_model *model, goto send_status; } - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER)) { + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { bt_mesh_lpn_group_del(mod->groups, ARRAY_SIZE(mod->groups)); } @@ -1458,11 +1492,11 @@ send_status: static void mod_sub_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct net_buf_simple *msg = + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 5 + 4 + - CONFIG_BLUETOOTH_MESH_MODEL_GROUP_COUNT * 2); + MYNEWT_VAL(BLE_MESH_MODEL_GROUP_COUNT) * 2); struct bt_mesh_model *mod; struct bt_mesh_elem *elem; u16_t addr, id; @@ -1506,15 +1540,18 @@ send_list: if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Model Subscription List"); } + + os_mbuf_free_chain(msg); + } static void mod_sub_get_vnd(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct net_buf_simple *msg = + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 7 + 4 + - CONFIG_BLUETOOTH_MESH_MODEL_GROUP_COUNT * 2); + MYNEWT_VAL(BLE_MESH_MODEL_GROUP_COUNT) * 2); struct bt_mesh_model *mod; struct bt_mesh_elem *elem; u16_t company, addr, id; @@ -1562,12 +1599,15 @@ send_list: if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Vendor Model Subscription List"); } + + os_mbuf_free_chain(msg); + } -#if CONFIG_BLUETOOTH_MESH_LABEL_COUNT > 0 +#if MYNEWT_VAL(BLE_MESH_LABEL_COUNT) > 0 static void mod_sub_va_add(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { u16_t elem_addr, sub_addr; struct bt_mesh_model *mod; @@ -1579,16 +1619,16 @@ static void mod_sub_va_add(struct bt_mesh_model *model, int i; elem_addr = net_buf_simple_pull_le16(buf); - label_uuid = buf->data; + label_uuid = buf->om_data; net_buf_simple_pull(buf, 16); BT_DBG("elem_addr 0x%04x", elem_addr); - mod_id = buf->data; + mod_id = buf->om_data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { mod = NULL; - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); sub_addr = BT_MESH_ADDR_UNASSIGNED; status = STATUS_INVALID_ADDRESS; goto send_status; @@ -1622,7 +1662,7 @@ static void mod_sub_va_add(struct bt_mesh_model *model, if (i == ARRAY_SIZE(mod->groups)) { status = STATUS_INSUFF_RESOURCES; } else { - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER)) { + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { bt_mesh_lpn_group_add(sub_addr); } @@ -1636,7 +1676,7 @@ send_status: static void mod_sub_va_del(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { u16_t elem_addr, sub_addr; struct bt_mesh_model *mod; @@ -1648,17 +1688,17 @@ static void mod_sub_va_del(struct bt_mesh_model *model, bool vnd; elem_addr = net_buf_simple_pull_le16(buf); - label_uuid = buf->data; + label_uuid = buf->om_data; net_buf_simple_pull(buf, 16); BT_DBG("elem_addr 0x%04x", elem_addr); - mod_id = buf->data; + mod_id = buf->om_data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { mod = NULL; - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); sub_addr = BT_MESH_ADDR_UNASSIGNED; status = STATUS_INVALID_ADDRESS; goto send_status; @@ -1692,7 +1732,7 @@ send_status: static void mod_sub_va_overwrite(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { u16_t elem_addr, sub_addr; struct bt_mesh_model *mod; @@ -1703,17 +1743,17 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, bool vnd; elem_addr = net_buf_simple_pull_le16(buf); - label_uuid = buf->data; + label_uuid = buf->om_data; net_buf_simple_pull(buf, 16); BT_DBG("elem_addr 0x%04x", elem_addr); - mod_id = buf->data; + mod_id = buf->om_data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { mod = NULL; - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -1724,7 +1764,7 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, goto send_status; } - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER)) { + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { bt_mesh_lpn_group_del(mod->groups, ARRAY_SIZE(mod->groups)); } @@ -1736,7 +1776,7 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, if (status == STATUS_SUCCESS) { mod->groups[0] = sub_addr; - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER)) { + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { bt_mesh_lpn_group_add(sub_addr); } } @@ -1751,7 +1791,7 @@ send_status: #else static void mod_sub_va_add(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_model *mod; struct bt_mesh_elem *elem; @@ -1763,12 +1803,12 @@ static void mod_sub_va_add(struct bt_mesh_model *model, elem_addr = net_buf_simple_pull_le16(buf); net_buf_simple_pull(buf, 16); - mod_id = buf->data; + mod_id = buf->om_data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { mod = NULL; - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -1788,7 +1828,7 @@ send_status: static void mod_sub_va_del(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_elem *elem; u16_t elem_addr; @@ -1799,11 +1839,11 @@ static void mod_sub_va_del(struct bt_mesh_model *model, elem_addr = net_buf_simple_pull_le16(buf); net_buf_simple_pull(buf, 16); - mod_id = buf->data; + mod_id = buf->om_data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -1822,7 +1862,7 @@ send_status: static void mod_sub_va_overwrite(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_elem *elem; u16_t elem_addr; @@ -1833,11 +1873,11 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, elem_addr = net_buf_simple_pull_le16(buf); net_buf_simple_pull(buf, 18); - mod_id = buf->data; + mod_id = buf->om_data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -1853,14 +1893,14 @@ send_status: send_mod_sub_status(model, ctx, status, elem_addr, BT_MESH_ADDR_UNASSIGNED, mod_id, vnd); } -#endif /* CONFIG_BLUETOOTH_MESH_LABEL_COUNT > 0 */ +#endif /* MYNEWT_VAL(BLE_MESH_LABEL_COUNT) > 0 */ static void send_net_key_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, u16_t idx, u8_t status) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 3 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 3 + 4); bt_mesh_model_msg_init(msg, OP_NET_KEY_STATUS); @@ -1868,11 +1908,14 @@ static void send_net_key_status(struct bt_mesh_model *model, net_buf_simple_add_le16(msg, idx); bt_mesh_model_send(model, ctx, msg, NULL, NULL); + + os_mbuf_free_chain(msg); + } static void net_key_add(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_subnet *sub; u16_t idx; @@ -1908,7 +1951,7 @@ static void net_key_add(struct bt_mesh_model *model, if (sub->net_idx == idx) { u8_t status; - if (memcmp(buf->data, sub->keys[0].net, 16)) { + if (memcmp(buf->om_data, sub->keys[0].net, 16)) { status = STATUS_IDX_ALREADY_STORED; } else { status = STATUS_SUCCESS; @@ -1918,7 +1961,7 @@ static void net_key_add(struct bt_mesh_model *model, return; } - err = bt_mesh_net_keys_create(&sub->keys[0], buf->data); + err = bt_mesh_net_keys_create(&sub->keys[0], buf->om_data); if (err) { send_net_key_status(model, ctx, idx, STATUS_UNSPECIFIED); return; @@ -1926,7 +1969,7 @@ static void net_key_add(struct bt_mesh_model *model, sub->net_idx = idx; - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_GATT_PROXY)) { + if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY))) { sub->node_id = BT_MESH_NODE_IDENTITY_STOPPED; bt_mesh_proxy_beacon_send(sub); bt_mesh_adv_update(); @@ -1939,7 +1982,7 @@ static void net_key_add(struct bt_mesh_model *model, static void net_key_update(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_subnet *sub; u16_t idx; @@ -1967,12 +2010,12 @@ static void net_key_update(struct bt_mesh_model *model, */ switch (sub->kr_phase) { case BT_MESH_KR_NORMAL: - if (!memcmp(buf->data, sub->keys[0].net, 16)) { + if (!memcmp(buf->om_data, sub->keys[0].net, 16)) { return; } break; case BT_MESH_KR_PHASE_1: - if (!memcmp(buf->data, sub->keys[1].net, 16)) { + if (!memcmp(buf->om_data, sub->keys[1].net, 16)) { send_net_key_status(model, ctx, idx, STATUS_SUCCESS); return; } @@ -1983,10 +2026,10 @@ static void net_key_update(struct bt_mesh_model *model, return; } - err = bt_mesh_net_keys_create(&sub->keys[1], buf->data); - if (!err && (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER) || - IS_ENABLED(CONFIG_BLUETOOTH_MESH_FRIEND))) { - err = bt_mesh_friend_cred_update(ctx->net_idx, 1, buf->data); + err = bt_mesh_net_keys_create(&sub->keys[1], buf->om_data); + if (!err && ((MYNEWT_VAL(BLE_MESH_LOW_POWER)) || + (MYNEWT_VAL(BLE_MESH_FRIEND)))) { + err = bt_mesh_friend_cred_update(ctx->net_idx, 1, buf->om_data); } if (err) { @@ -2015,7 +2058,7 @@ static void hb_pub_disable(struct bt_mesh_cfg *cfg) static void net_key_del(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_cfg *cfg = model->user_data; struct bt_mesh_subnet *sub; @@ -2071,11 +2114,11 @@ send_status: static void net_key_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct net_buf_simple *msg = + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + - IDX_LEN(CONFIG_BLUETOOTH_MESH_SUBNET_COUNT)); + IDX_LEN(MYNEWT_VAL(BLE_MESH_SUBNET_COUNT))); u16_t prev, i; bt_mesh_model_msg_init(msg, OP_NET_KEY_LIST); @@ -2104,26 +2147,28 @@ static void net_key_get(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send NetKey List"); } + + os_mbuf_free_chain(msg); } static void node_identity_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 4 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); struct bt_mesh_subnet *sub; u8_t node_id; u16_t idx; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); idx = net_buf_simple_pull_le16(buf); if (idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", idx); - return; + goto done; } bt_mesh_model_msg_init(msg, OP_NODE_IDENTITY_STATUS); @@ -2143,32 +2188,35 @@ static void node_identity_get(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Node Identity Status"); } + +done: + os_mbuf_free_chain(msg); } static void node_identity_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 4 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); struct bt_mesh_subnet *sub; u8_t node_id; u16_t idx; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); idx = net_buf_simple_pull_le16(buf); if (idx > 0xfff) { BT_WARN("Invalid NetKeyIndex 0x%04x", idx); - return; + goto done; } node_id = net_buf_simple_pull_u8(buf); if (node_id != 0x00 && node_id != 0x01) { BT_WARN("Invalid Node ID value 0x%02x", node_id); - return; + goto done; } bt_mesh_model_msg_init(msg, OP_NODE_IDENTITY_STATUS); @@ -2182,7 +2230,7 @@ static void node_identity_set(struct bt_mesh_model *model, net_buf_simple_add_u8(msg, STATUS_SUCCESS); net_buf_simple_add_le16(msg, idx); - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_GATT_PROXY)) { + if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY))) { sub->node_id = node_id; bt_mesh_adv_update(); } @@ -2193,9 +2241,13 @@ static void node_identity_set(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Node Identity Status"); } + +done: + os_mbuf_free_chain(msg); + } -static void create_mod_app_status(struct net_buf_simple *msg, +static void create_mod_app_status(struct os_mbuf *msg, struct bt_mesh_model *mod, bool vnd, u16_t elem_addr, u16_t app_idx, u8_t status, u8_t *mod_id) @@ -2215,9 +2267,9 @@ static void create_mod_app_status(struct net_buf_simple *msg, static void mod_app_bind(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 9 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4); u16_t elem_addr, key_app_idx; struct bt_mesh_model *mod; struct bt_mesh_elem *elem; @@ -2226,12 +2278,12 @@ static void mod_app_bind(struct bt_mesh_model *model, elem_addr = net_buf_simple_pull_le16(buf); key_app_idx = net_buf_simple_pull_le16(buf); - mod_id = buf->data; + mod_id = buf->om_data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { mod = NULL; - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -2259,13 +2311,16 @@ send_status: if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Model App Bind Status response"); } + + os_mbuf_free_chain(msg); + } static void mod_app_unbind(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 9 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4); u16_t elem_addr, key_app_idx; struct bt_mesh_model *mod; struct bt_mesh_elem *elem; @@ -2274,12 +2329,12 @@ static void mod_app_unbind(struct bt_mesh_model *model, elem_addr = net_buf_simple_pull_le16(buf); key_app_idx = net_buf_simple_pull_le16(buf); - mod_id = buf->data; + mod_id = buf->om_data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { mod = NULL; - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -2300,15 +2355,17 @@ send_status: if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Model App Unbind Status response"); } + + os_mbuf_free_chain(msg); } -#define KEY_LIST_LEN (CONFIG_BLUETOOTH_MESH_MODEL_KEY_COUNT * 2) +#define KEY_LIST_LEN (MYNEWT_VAL(BLE_MESH_MODEL_KEY_COUNT) * 2) static void mod_app_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 9 + KEY_LIST_LEN + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + KEY_LIST_LEN + 4); struct bt_mesh_model *mod; struct bt_mesh_elem *elem; u8_t *mod_id, status; @@ -2316,14 +2373,14 @@ static void mod_app_get(struct bt_mesh_model *model, bool vnd; elem_addr = net_buf_simple_pull_le16(buf); - mod_id = buf->data; + mod_id = buf->om_data; BT_DBG("elem_addr 0x%04x", elem_addr); elem = bt_mesh_elem_find(elem_addr); if (!elem) { mod = NULL; - vnd = (buf->len == 4); + vnd = (buf->om_len == 4); status = STATUS_INVALID_ADDRESS; goto send_list; } @@ -2363,20 +2420,21 @@ send_list: } bt_mesh_model_send(model, ctx, msg, NULL, NULL); + os_mbuf_free_chain(msg); } static void node_reset(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); struct bt_mesh_cfg *cfg = model->user_data; int i; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); bt_mesh_model_msg_init(msg, OP_NODE_RESET_STATUS); @@ -2411,13 +2469,14 @@ static void node_reset(struct bt_mesh_model *model, memset(labels, 0, sizeof(labels)); bt_mesh_reset(); + os_mbuf_free_chain(msg); } static void send_friend_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); struct bt_mesh_cfg *cfg = model->user_data; bt_mesh_model_msg_init(msg, OP_FRIEND_STATUS); @@ -2426,32 +2485,33 @@ static void send_friend_status(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Friend Status"); } + os_mbuf_free_chain(msg); } static void friend_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); send_friend_status(model, ctx); } static void friend_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_cfg *cfg = model->user_data; struct bt_mesh_subnet *sub; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); - if (buf->data[0] != 0x00 && buf->data[0] != 0x01) { - BT_WARN("Invalid Friend value 0x%02x", buf->data[0]); + if (buf->om_data[0] != 0x00 && buf->om_data[0] != 0x01) { + BT_WARN("Invalid Friend value 0x%02x", buf->om_data[0]); return; } @@ -2460,13 +2520,13 @@ static void friend_set(struct bt_mesh_model *model, goto send_status; } - BT_DBG("Friend 0x%02x -> 0x%02x", cfg->frnd, buf->data[0]); + BT_DBG("Friend 0x%02x -> 0x%02x", cfg->frnd, buf->om_data[0]); - if (cfg->frnd == buf->data[0]) { + if (cfg->frnd == buf->om_data[0]) { goto send_status; } - cfg->frnd = buf->data[0]; + cfg->frnd = buf->om_data[0]; sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx); if ((cfg->hb_pub.feat & BT_MESH_FEAT_FRIEND) && sub) { @@ -2479,10 +2539,10 @@ send_status: static void lpn_timeout_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 5 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 5 + 4); u16_t lpn_addr; lpn_addr = net_buf_simple_pull_le16(buf); @@ -2497,6 +2557,7 @@ static void lpn_timeout_get(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Friend Status"); } + os_mbuf_free_chain(msg); } static void send_krp_status(struct bt_mesh_model *model, @@ -2504,7 +2565,7 @@ static void send_krp_status(struct bt_mesh_model *model, u16_t idx, u8_t phase, u8_t status) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 4 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); bt_mesh_model_msg_init(msg, OP_KRP_STATUS); @@ -2513,10 +2574,11 @@ static void send_krp_status(struct bt_mesh_model *model, net_buf_simple_add_u8(msg, phase); bt_mesh_model_send(model, ctx, msg, NULL, NULL); + os_mbuf_free_chain(msg); } static void krp_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_subnet *sub; u16_t idx; @@ -2539,7 +2601,7 @@ static void krp_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, } static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_subnet *sub; u8_t phase; @@ -2579,8 +2641,8 @@ static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, sub->kr_phase == BT_MESH_KR_PHASE_2) && phase == BT_MESH_KR_PHASE_3) { memcpy(&sub->keys[0], &sub->keys[1], sizeof(sub->keys[0])); - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER) || - IS_ENABLED(CONFIG_BLUETOOTH_MESH_FRIEND)) { + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER)) || + (MYNEWT_VAL(BLE_MESH_FRIEND))) { bt_mesh_friend_cred_refresh(ctx->net_idx); } sub->kr_phase = BT_MESH_KR_NORMAL; @@ -2627,7 +2689,7 @@ static void hb_pub_send_status(struct bt_mesh_model *model, struct hb_pub_param *orig_msg) { /* Needed size: opcode (1 byte) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(1 + 10 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(1 + 10 + 4); struct bt_mesh_cfg *cfg = model->user_data; BT_DBG("src 0x%04x status 0x%02x", ctx->addr, status); @@ -2651,11 +2713,12 @@ static void hb_pub_send_status(struct bt_mesh_model *model, send: bt_mesh_model_send(model, ctx, msg, NULL, NULL); + os_mbuf_free_chain(msg); } static void hearbeat_pub_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { BT_DBG("src 0x%04x", ctx->addr); @@ -2664,9 +2727,9 @@ static void hearbeat_pub_get(struct bt_mesh_model *model, static void hearbeat_pub_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct hb_pub_param *param = (void *)buf->data; + struct hb_pub_param *param = (void *)buf->om_data; struct bt_mesh_cfg *cfg = model->user_data; u16_t dst, feat, idx; u8_t status; @@ -2745,7 +2808,7 @@ static void hb_sub_send_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, u8_t status) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 9 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4); struct bt_mesh_cfg *cfg = model->user_data; u16_t period; s64_t uptime; @@ -2771,11 +2834,12 @@ static void hb_sub_send_status(struct bt_mesh_model *model, net_buf_simple_add_u8(msg, cfg->hb_sub.max_hops); bt_mesh_model_send(model, ctx, msg, NULL, NULL); + os_mbuf_free_chain(msg); } static void hearbeat_sub_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { BT_DBG("src 0x%04x", ctx->addr); @@ -2784,7 +2848,7 @@ static void hearbeat_sub_get(struct bt_mesh_model *model, static void hearbeat_sub_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_cfg *cfg = model->user_data; u16_t sub_src, sub_dst; @@ -2841,7 +2905,7 @@ static void hearbeat_sub_set(struct bt_mesh_model *model, hb_sub_send_status(model, ctx, STATUS_SUCCESS); } -const struct bt_mesh_model_op const bt_mesh_cfg_op[] = { +const struct bt_mesh_model_op bt_mesh_cfg_op[] = { { OP_DEV_COMP_DATA_GET, 1, dev_comp_data_get }, { OP_APP_KEY_ADD, 19, app_key_add }, { OP_APP_KEY_UPDATE, 19, app_key_update }, @@ -2892,10 +2956,9 @@ const struct bt_mesh_model_op const bt_mesh_cfg_op[] = { BT_MESH_MODEL_OP_END, }; -static void hb_publish(struct k_work *work) +static void hb_publish(struct os_event *work) { - struct bt_mesh_cfg *cfg = CONTAINER_OF(work, struct bt_mesh_cfg, - hb_pub.timer.work); + struct bt_mesh_cfg *cfg = work->ev_arg; struct bt_mesh_model *model = cfg->model; struct bt_mesh_subnet *sub; u16_t period_ms; @@ -2956,15 +3019,15 @@ int bt_mesh_conf_init(struct bt_mesh_model *model, bool primary) /* Configuration Model security is device-key based */ model->keys[0] = BT_MESH_KEY_DEV; - if (!IS_ENABLED(CONFIG_BLUETOOTH_MESH_RELAY)) { + if (!(MYNEWT_VAL(BLE_MESH_RELAY))) { cfg->relay = BT_MESH_RELAY_NOT_SUPPORTED; } - if (!IS_ENABLED(CONFIG_BLUETOOTH_MESH_FRIEND)) { + if (!(MYNEWT_VAL(BLE_MESH_FRIEND))) { cfg->frnd = BT_MESH_RELAY_NOT_SUPPORTED; } - if (!IS_ENABLED(CONFIG_BLUETOOTH_MESH_GATT_PROXY)) { + if (!(MYNEWT_VAL(BLE_MESH_GATT_PROXY))) { cfg->gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED; } diff --git a/nimble/host/mesh/src/crypto.c b/nimble/host/mesh/src/crypto.c index 57a0d431f..150d75553 100644 --- a/nimble/host/mesh/src/crypto.c +++ b/nimble/host/mesh/src/crypto.c @@ -9,10 +9,6 @@ #include #include #include -#include -#include -#include -#include #include #include @@ -20,13 +16,9 @@ #include #include -#include -#include +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_CRYPTO)) +#include "host/ble_hs_log.h" -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_MESH_DEBUG_CRYPTO) -#include "common/log.h" - -#include "mesh.h" #include "crypto.h" #define NET_MIC_LEN(pdu) (((pdu)[1] & 0x80) ? 8 : 4) @@ -56,7 +48,7 @@ int bt_mesh_aes_cmac(const u8_t key[16], struct bt_mesh_sg *sg, } int bt_mesh_k1(const u8_t *ikm, size_t ikm_len, const u8_t salt[16], - const u8_t *info, size_t info_len, u8_t okm[16]) + const char *info, u8_t okm[16]) { int err; @@ -65,7 +57,7 @@ int bt_mesh_k1(const u8_t *ikm, size_t ikm_len, const u8_t salt[16], return err; } - return bt_mesh_aes_cmac_one(okm, info, info_len, okm); + return bt_mesh_aes_cmac_one(okm, info, strlen(info), okm); } int bt_mesh_k2(const u8_t n[16], const u8_t *p, size_t p_len, @@ -189,7 +181,7 @@ int bt_mesh_k4(const u8_t n[16], u8_t out[1]) int bt_mesh_id128(const u8_t n[16], const char *s, u8_t out[16]) { - u8_t id128[] = { 'i', 'd', '1', '2', '8', 0x01 }; + const char *id128 = "id128\x01"; u8_t salt[16]; int err; @@ -198,7 +190,7 @@ int bt_mesh_id128(const u8_t n[16], const char *s, u8_t out[16]) return err; } - return bt_mesh_k1(n, 16, salt, id128, sizeof(id128), out); + return bt_mesh_k1(n, 16, salt, id128, out); } static int bt_mesh_ccm_decrypt(const u8_t key[16], u8_t nonce[13], @@ -519,7 +511,7 @@ static int bt_mesh_ccm_encrypt(const u8_t key[16], u8_t nonce[13], return 0; } -#if defined(CONFIG_BLUETOOTH_MESH_PROXY) +#if (MYNEWT_VAL(BLE_MESH_PROXY)) static void create_proxy_nonce(u8_t nonce[13], const u8_t *pdu, u32_t iv_index) { @@ -599,31 +591,31 @@ int bt_mesh_net_obfuscate(u8_t *pdu, u32_t iv_index, return 0; } -int bt_mesh_net_encrypt(const u8_t key[16], struct net_buf_simple *buf, +int bt_mesh_net_encrypt(const u8_t key[16], struct os_mbuf *buf, u32_t iv_index, bool proxy) { - u8_t mic_len = NET_MIC_LEN(buf->data); + u8_t mic_len = NET_MIC_LEN(buf->om_data); u8_t nonce[13]; int err; BT_DBG("IVIndex %u EncKey %s mic_len %u", iv_index, bt_hex(key, 16), mic_len); - BT_DBG("PDU (len %u) %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("PDU (len %u) %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); -#if defined(CONFIG_BLUETOOTH_MESH_PROXY) +#if (MYNEWT_VAL(BLE_MESH_PROXY)) if (proxy) { - create_proxy_nonce(nonce, buf->data, iv_index); + create_proxy_nonce(nonce, buf->om_data, iv_index); } else { - create_net_nonce(nonce, buf->data, iv_index); + create_net_nonce(nonce, buf->om_data, iv_index); } #else - create_net_nonce(nonce, buf->data, iv_index); + create_net_nonce(nonce, buf->om_data, iv_index); #endif BT_DBG("Nonce %s", bt_hex(nonce, 13)); - err = bt_mesh_ccm_encrypt(key, nonce, &buf->data[7], buf->len - 7, - NULL, 0, &buf->data[7], mic_len); + err = bt_mesh_ccm_encrypt(key, nonce, &buf->om_data[7], buf->om_len - 7, + NULL, 0, &buf->om_data[7], mic_len); if (!err) { net_buf_simple_add(buf, mic_len); } @@ -631,32 +623,32 @@ int bt_mesh_net_encrypt(const u8_t key[16], struct net_buf_simple *buf, return err; } -int bt_mesh_net_decrypt(const u8_t key[16], struct net_buf_simple *buf, +int bt_mesh_net_decrypt(const u8_t key[16], struct os_mbuf *buf, u32_t iv_index, bool proxy) { - u8_t mic_len = NET_MIC_LEN(buf->data); + u8_t mic_len = NET_MIC_LEN(buf->om_data); u8_t nonce[13]; - BT_DBG("PDU (%u bytes) %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("PDU (%u bytes) %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); BT_DBG("iv_index %u, key %s mic_len %u", iv_index, bt_hex(key, 16), mic_len); -#if defined(CONFIG_BLUETOOTH_MESH_PROXY) +#if (MYNEWT_VAL(BLE_MESH_PROXY)) if (proxy) { - create_proxy_nonce(nonce, buf->data, iv_index); + create_proxy_nonce(nonce, buf->om_data, iv_index); } else { - create_net_nonce(nonce, buf->data, iv_index); + create_net_nonce(nonce, buf->om_data, iv_index); } #else - create_net_nonce(nonce, buf->data, iv_index); + create_net_nonce(nonce, buf->om_data, iv_index); #endif BT_DBG("Nonce %s", bt_hex(nonce, 13)); - buf->len -= mic_len; + buf->om_len -= mic_len; - return bt_mesh_ccm_decrypt(key, nonce, &buf->data[7], buf->len - 7, - NULL, 0, &buf->data[7], mic_len); + return bt_mesh_ccm_decrypt(key, nonce, &buf->om_data[7], buf->om_len - 7, + NULL, 0, &buf->om_data[7], mic_len); } static void create_app_nonce(u8_t nonce[13], bool dev_key, u8_t aszmic, @@ -678,7 +670,7 @@ static void create_app_nonce(u8_t nonce[13], bool dev_key, u8_t aszmic, } int bt_mesh_app_encrypt(const u8_t key[16], bool dev_key, u8_t aszmic, - struct net_buf_simple *buf, const u8_t *ad, + struct os_mbuf *buf, const u8_t *ad, u8_t mic_len, u16_t src, u16_t dst, u32_t seq_num, u32_t iv_index) { @@ -689,42 +681,42 @@ int bt_mesh_app_encrypt(const u8_t key[16], bool dev_key, u8_t aszmic, BT_DBG("dev_key %u mic_len %u src 0x%04x dst 0x%04x", dev_key, mic_len, src, dst); BT_DBG("seq_num 0x%08x iv_index 0x%08x", seq_num, iv_index); - BT_DBG("Clear: %s", bt_hex(buf->data, buf->len)); + BT_DBG("Clear: %s", bt_hex(buf->om_data, buf->om_len)); create_app_nonce(nonce, dev_key, aszmic, src, dst, seq_num, iv_index); BT_DBG("Nonce %s", bt_hex(nonce, 13)); - err = bt_mesh_ccm_encrypt(key, nonce, buf->data, buf->len, ad, - ad ? 16 : 0, buf->data, mic_len); + err = bt_mesh_ccm_encrypt(key, nonce, buf->om_data, buf->om_len, ad, + ad ? 16 : 0, buf->om_data, mic_len); if (!err) { net_buf_simple_add(buf, mic_len); - BT_DBG("Encr: %s", bt_hex(buf->data, buf->len)); + BT_DBG("Encr: %s", bt_hex(buf->om_data, buf->om_len)); } return err; } int bt_mesh_app_decrypt(const u8_t key[16], bool dev_key, u8_t aszmic, - struct net_buf_simple *buf, u8_t mic_len, - struct net_buf_simple *out, const u8_t *ad, + struct os_mbuf *buf, u8_t mic_len, + struct os_mbuf *out, const u8_t *ad, u16_t src, u16_t dst, u32_t seq_num, u32_t iv_index) { u8_t nonce[13]; int err; - BT_DBG("EncData (len %u) %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("EncData (len %u) %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); create_app_nonce(nonce, dev_key, aszmic, src, dst, seq_num, iv_index); BT_DBG("AppKey %s", bt_hex(key, 16)); BT_DBG("Nonce %s", bt_hex(nonce, 13)); - err = bt_mesh_ccm_decrypt(key, nonce, buf->data, buf->len, ad, - ad ? 16 : 0, out->data, mic_len); + err = bt_mesh_ccm_decrypt(key, nonce, buf->om_data, buf->om_len, ad, + ad ? 16 : 0, out->om_data, mic_len); if (!err) { - net_buf_simple_add(out, buf->len); + net_buf_simple_add(out, buf->om_len); } return err; @@ -786,10 +778,10 @@ u8_t bt_mesh_fcs_calc(const u8_t *data, u8_t data_len) return 0xff - fcs; } -bool bt_mesh_fcs_check(struct net_buf_simple *buf, u8_t received_fcs) +bool bt_mesh_fcs_check(struct os_mbuf *buf, u8_t received_fcs) { - const u8_t *data = buf->data; - u16_t data_len = buf->len; + const u8_t *data = buf->om_data; + u16_t data_len = buf->om_len; u8_t fcs = 0xff; while (data_len--) { @@ -830,7 +822,7 @@ int bt_mesh_prov_conf_salt(const u8_t conf_inputs[145], u8_t salt[16]) int bt_mesh_prov_conf_key(const u8_t dhkey[32], const u8_t conf_salt[16], u8_t conf_key[16]) { - return bt_mesh_k1(dhkey, 32, conf_salt, "prck", 4, conf_key); + return bt_mesh_k1(dhkey, 32, conf_salt, "prck", conf_key); } int bt_mesh_prov_conf(const u8_t conf_key[16], const u8_t rand[16], diff --git a/nimble/host/mesh/src/crypto.h b/nimble/host/mesh/src/crypto.h index 27694aa22..d37b7edab 100644 --- a/nimble/host/mesh/src/crypto.h +++ b/nimble/host/mesh/src/crypto.h @@ -5,6 +5,10 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#ifndef __CRYPTO_H__ +#define __CRYPTO_H__ + +#include "mesh/mesh.h" struct bt_mesh_sg { const void *data; @@ -30,12 +34,12 @@ static inline bool bt_mesh_s1(const char *m, u8_t salt[16]) } int bt_mesh_k1(const u8_t *ikm, size_t ikm_len, const u8_t salt[16], - const u8_t *info, size_t info_len, u8_t okm[16]); + const char *info, u8_t okm[16]); #define bt_mesh_k1_str(ikm, ikm_len, salt_str, info, okm) \ ({ \ const u8_t salt[16] = salt_str; \ - bt_mesh_k1(ikm, ikm_len, salt, info, strlen(info), okm); \ + bt_mesh_k1(ikm, ikm_len, salt, info, okm); \ }) int bt_mesh_k2(const u8_t n[16], const u8_t *p, size_t p_len, @@ -78,7 +82,7 @@ static inline int bt_mesh_session_key(const u8_t dhkey[32], const u8_t prov_salt[16], u8_t session_key[16]) { - return bt_mesh_k1(dhkey, 32, prov_salt, "prsk", 4, session_key); + return bt_mesh_k1(dhkey, 32, prov_salt, "prsk", session_key); } static inline int bt_mesh_prov_nonce(const u8_t dhkey[32], @@ -88,7 +92,7 @@ static inline int bt_mesh_prov_nonce(const u8_t dhkey[32], u8_t tmp[16]; int err; - err = bt_mesh_k1(dhkey, 32, prov_salt, "prsn", 4, tmp); + err = bt_mesh_k1(dhkey, 32, prov_salt, "prsn", tmp); if (!err) { memcpy(nonce, tmp + 3, 13); } @@ -100,7 +104,7 @@ static inline int bt_mesh_dev_key(const u8_t dhkey[32], const u8_t prov_salt[16], u8_t dev_key[16]) { - return bt_mesh_k1(dhkey, 32, prov_salt, "prdk", 4, dev_key); + return bt_mesh_k1(dhkey, 32, prov_salt, "prdk", dev_key); } static inline int bt_mesh_prov_salt(const u8_t conf_salt[16], @@ -121,26 +125,26 @@ static inline int bt_mesh_prov_salt(const u8_t conf_salt[16], int bt_mesh_net_obfuscate(u8_t *pdu, u32_t iv_index, const u8_t privacy_key[16]); -int bt_mesh_net_encrypt(const u8_t key[16], struct net_buf_simple *buf, +int bt_mesh_net_encrypt(const u8_t key[16], struct os_mbuf *buf, u32_t iv_index, bool proxy); -int bt_mesh_net_decrypt(const u8_t key[16], struct net_buf_simple *buf, +int bt_mesh_net_decrypt(const u8_t key[16], struct os_mbuf *buf, u32_t iv_index, bool proxy); int bt_mesh_app_encrypt(const u8_t key[16], bool dev_key, u8_t aszmic, - struct net_buf_simple *buf, const u8_t *ad, + struct os_mbuf *buf, const u8_t *ad, u8_t mic_len, u16_t src, u16_t dst, u32_t seq_num, u32_t iv_index); int bt_mesh_app_decrypt(const u8_t key[16], bool dev_key, u8_t aszmic, - struct net_buf_simple *buf, u8_t mic_len, - struct net_buf_simple *out, const u8_t *ad, + struct os_mbuf *buf, u8_t mic_len, + struct os_mbuf *out, const u8_t *ad, u16_t src, u16_t dst, u32_t seq_num, u32_t iv_index); u8_t bt_mesh_fcs_calc(const u8_t *data, u8_t data_len); -bool bt_mesh_fcs_check(struct net_buf_simple *buf, u8_t received_fcs); +bool bt_mesh_fcs_check(struct os_mbuf *buf, u8_t received_fcs); int bt_mesh_virtual_addr(const u8_t virtual_label[16], u16_t *addr); @@ -154,3 +158,5 @@ int bt_mesh_prov_conf(const u8_t conf_key[16], const u8_t rand[16], int bt_mesh_prov_decrypt(const u8_t key[16], u8_t nonce[13], const u8_t data[25 + 8], u8_t out[25]); + +#endif diff --git a/nimble/host/mesh/src/foundation.h b/nimble/host/mesh/src/foundation.h index 31cc056f2..decb2dc6a 100644 --- a/nimble/host/mesh/src/foundation.h +++ b/nimble/host/mesh/src/foundation.h @@ -6,6 +6,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef __FUNDATION_H__ +#define __FUNDATION_H__ + #define OP_APP_KEY_ADD BT_MESH_MODEL_OP_1(0x00) #define OP_APP_KEY_UPDATE BT_MESH_MODEL_OP_1(0x01) #define OP_DEV_COMP_DATA_STATUS BT_MESH_MODEL_OP_1(0x02) @@ -112,24 +115,38 @@ #define STATUS_UNSPECIFIED 0x10 #define STATUS_INVALID_BINDING 0x11 -int bt_mesh_conf_init(struct bt_mesh_model *model, bool primary); -int bt_mesh_health_init(struct bt_mesh_model *model, bool primary); +int +bt_mesh_conf_init(struct bt_mesh_model *model, bool primary); +int +bt_mesh_health_init(struct bt_mesh_model *model, bool primary); -void bt_mesh_heartbeat(u16_t src, u16_t dst, u8_t hops, u16_t feat); +void +bt_mesh_heartbeat(u16_t src, u16_t dst, u8_t hops, u16_t feat); -void bt_mesh_attention(struct bt_mesh_model *model, u8_t time); +void +bt_mesh_attention(struct bt_mesh_model *model, u8_t time); -u8_t *bt_mesh_label_uuid_get(u16_t addr); +u8_t * +bt_mesh_label_uuid_get(u16_t addr); /* Transmission count (N + 1) */ #define TRANSMIT_COUNT(transmit) (((transmit) & (u8_t)BIT_MASK(3))) /* Returns transmission interval in milliseconds */ #define TRANSMIT_INT(transmit) ((((transmit) >> 3) + 1) * 10) -u8_t bt_mesh_net_transmit_get(void); -u8_t bt_mesh_relay_get(void); -u8_t bt_mesh_friend_get(void); -u8_t bt_mesh_relay_retransmit_get(void); -u8_t bt_mesh_beacon_get(void); -u8_t bt_mesh_gatt_proxy_get(void); -u8_t bt_mesh_default_ttl_get(void); +u8_t +bt_mesh_net_transmit_get(void); +u8_t +bt_mesh_relay_get(void); +u8_t +bt_mesh_friend_get(void); +u8_t +bt_mesh_relay_retransmit_get(void); +u8_t +bt_mesh_beacon_get(void); +u8_t +bt_mesh_gatt_proxy_get(void); +u8_t +bt_mesh_default_ttl_get(void); + +#endif diff --git a/nimble/host/mesh/src/friend.c b/nimble/host/mesh/src/friend.c index c25f1b9b6..7baa43594 100644 --- a/nimble/host/mesh/src/friend.c +++ b/nimble/host/mesh/src/friend.c @@ -6,20 +6,21 @@ * SPDX-License-Identifier: Apache-2.0 */ + +#include "syscfg/syscfg.h" +#if MYNEWT_VAL(BLE_MESH_FRIEND) == 1 + #include -#include -#include +#include +#include -#include -#include -#include - -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_MESH_DEBUG_FRIEND) -#include "common/log.h" +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_FRIEND)) +#include "host/ble_hs_log.h" +#include "mesh/mesh.h" +#include "mesh_priv.h" #include "crypto.h" #include "adv.h" -#include "mesh.h" #include "net.h" #include "transport.h" #include "access.h" @@ -51,12 +52,12 @@ static int send_friend_update(void) sizeof(upd), NULL); } -int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) +int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) { - struct bt_mesh_ctl_friend_poll *msg = (void *)buf->data; + struct bt_mesh_ctl_friend_poll *msg = (void *)buf->om_data; struct bt_mesh_friend *frnd = &bt_mesh.frnd; - if (buf->len < sizeof(*msg)) { + if (buf->om_len < sizeof(*msg)) { BT_WARN("Too short Friend Update"); return -EINVAL; } @@ -89,8 +90,8 @@ static int send_friend_offer(s8_t rssi) .src = bt_mesh_primary_addr(), }; struct bt_mesh_ctl_friend_offer off = { - .recv_win = CONFIG_BLUETOOTH_MESH_FRIEND_RECV_WIN, - .queue_size = CONFIG_BLUETOOTH_MESH_FRIEND_QUEUE_SIZE, + .recv_win = MYNEWT_VAL(BLE_MESH_FRIEND_RECV_WIN), + .queue_size = MYNEWT_VAL(BLE_MESH_FRIEND_QUEUE_SIZE), .rssi = rssi, .frnd_counter = bt_mesh.frnd.counter++, }; @@ -101,13 +102,13 @@ static int send_friend_offer(s8_t rssi) sizeof(off), NULL); } -int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) +int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) { - struct bt_mesh_ctl_friend_req *msg = (void *)buf->data; + struct bt_mesh_ctl_friend_req *msg = (void *)buf->om_data; struct bt_mesh_friend *frnd = &bt_mesh.frnd; struct bt_mesh_subnet *sub = rx->sub; - if (buf->len < sizeof(*msg)) { + if (buf->om_len < sizeof(*msg)) { BT_WARN("Too short Friend Request"); return -EINVAL; } @@ -134,7 +135,7 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) return 0; } -static void friend_timeout(struct k_work *work) +static void friend_timeout(struct os_event *work) { struct bt_mesh_friend *frnd = &bt_mesh.frnd; @@ -186,7 +187,7 @@ int bt_mesh_friend_init(void) return 0; } -bool bt_mesh_friend_enqueue(struct net_buf *buf, u16_t dst) +bool bt_mesh_friend_enqueue(struct os_mbuf *buf, u16_t dst) { /* FIXME: Add support for multiple LPNs and group addresses */ if (!bt_mesh_friend_dst_is_lpn(dst)) { @@ -196,7 +197,7 @@ bool bt_mesh_friend_enqueue(struct net_buf *buf, u16_t dst) if (BT_MESH_ADDR_IS_UNICAST(dst)) { net_buf_put(&bt_mesh.frnd.queue, net_buf_ref(buf)); } else { - struct net_buf *clone = net_buf_clone(buf, K_NO_WAIT); + struct os_mbuf *clone = net_buf_clone(buf, K_NO_WAIT); if (clone) { net_buf_put(&bt_mesh.frnd.queue, clone); @@ -210,3 +211,5 @@ bool bt_mesh_friend_enqueue(struct net_buf *buf, u16_t dst) return true; } + +#endif //MYNEWT_VAL(BLE_MESH_FRIEND) diff --git a/nimble/host/mesh/src/friend.h b/nimble/host/mesh/src/friend.h index c57f06b76..e3b423866 100644 --- a/nimble/host/mesh/src/friend.h +++ b/nimble/host/mesh/src/friend.h @@ -6,18 +6,30 @@ * SPDX-License-Identifier: Apache-2.0 */ -static inline bool bt_mesh_friend_dst_is_lpn(u16_t dst) +#ifndef __FRIEND_H__ +#define __FRIEND_H__ + +#include "mesh/mesh.h" + +static inline bool +bt_mesh_friend_dst_is_lpn(u16_t dst) { -#if defined(CONFIG_BLUETOOTH_MESH_FRIEND) - return (dst == bt_mesh.frnd.lpn); +#if (MYNEWT_VAL(BLE_MESH_FRIEND)) + return (dst == bt_mesh.frnd.lpn); #else - return false; + return false; #endif } -bool bt_mesh_friend_enqueue(struct net_buf *buf, u16_t dst); +bool +bt_mesh_friend_enqueue(struct os_mbuf *buf, u16_t dst); -int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf); -int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf); +int +bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct os_mbuf *buf); +int +bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct os_mbuf *buf); -int bt_mesh_friend_init(void); +int +bt_mesh_friend_init(void); + +#endif diff --git a/nimble/host/mesh/src/glue.c b/nimble/host/mesh/src/glue.c new file mode 100644 index 000000000..05aacccc1 --- /dev/null +++ b/nimble/host/mesh/src/glue.c @@ -0,0 +1,486 @@ +/* + * 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 "mesh/glue.h" +#include "adv.h" + +const char * +bt_hex(const void *buf, size_t len) +{ + static const char hex[] = "0123456789abcdef"; + static char hexbufs[4][137]; + static u8_t curbuf; + const u8_t *b = buf; + char *str; + int i; + + str = hexbufs[curbuf++]; + curbuf %= ARRAY_SIZE(hexbufs); + + len = min(len, (sizeof(hexbufs[0]) - 1) / 2); + + for (i = 0; i < len; i++) { + str[i * 2] = hex[b[i] >> 4]; + str[i * 2 + 1] = hex[b[i] & 0xf]; + } + + str[i * 2] = '\0'; + + return str; +} + +void +net_buf_put(struct os_eventq *fifo, struct os_mbuf *om) +{ + struct os_event *ev; + + assert(OS_MBUF_IS_PKTHDR(om)); + ev = &BT_MESH_ADV(om)->ev; + assert(ev); + assert(ev->ev_arg); + + os_eventq_put(fifo, ev); +} + +void * +net_buf_ref(struct os_mbuf *om) +{ + struct bt_mesh_adv *adv; + + /* For bufs with header we count refs*/ + if (OS_MBUF_USRHDR_LEN(om) == 0) { + return NULL; + } + + adv = BT_MESH_ADV(om); + adv->ref_cnt++; + + return om; +} + +void +net_buf_unref(struct os_mbuf *om) +{ + struct bt_mesh_adv *adv; + + /* For bufs with header we count refs*/ + if (OS_MBUF_USRHDR_LEN(om) == 0) { + goto free; + } + + adv = BT_MESH_ADV(om); + if (--adv->ref_cnt > 0) { + return; + } + +free: + os_mbuf_free_chain(om); +} + +int +bt_encrypt_be(const uint8_t *key, const uint8_t *plaintext, uint8_t *enc_data) +{ + struct tc_aes_key_sched_struct s; + + if (tc_aes128_set_encrypt_key(&s, key) == TC_CRYPTO_FAIL) { + return BLE_HS_EUNKNOWN; + } + + if (tc_aes_encrypt(enc_data, plaintext, &s) == TC_CRYPTO_FAIL) { + return BLE_HS_EUNKNOWN; + } + + return 0; +} + +uint16_t +net_buf_simple_pull_le16(struct os_mbuf *om) +{ + uint16_t val; + struct os_mbuf *old = om; + + om = os_mbuf_pullup(om, sizeof(val)); + assert(om == old); + val = get_le16(om->om_data); + os_mbuf_adj(om, sizeof(val)); + + return val; +} + +uint16_t +net_buf_simple_pull_be16(struct os_mbuf *om) +{ + uint16_t val; + struct os_mbuf *old = om; + + om = os_mbuf_pullup(om, sizeof(val)); + assert(om == old); + val = get_be16(om->om_data); + os_mbuf_adj(om, sizeof(val)); + + return val; +} + +uint32_t +net_buf_simple_pull_be32(struct os_mbuf *om) +{ + uint32_t val; + struct os_mbuf *old = om; + + om = os_mbuf_pullup(om, sizeof(val)); + assert(om == old); + val = get_be32(om->om_data); + os_mbuf_adj(om, sizeof(val)); + + return val; +} + +uint8_t +net_buf_simple_pull_u8(struct os_mbuf *om) +{ + uint8_t val; + struct os_mbuf *old = om; + + om = os_mbuf_pullup(om, sizeof(val)); + assert(om == old); + val = om->om_data[0]; + os_mbuf_adj(om, 1); + + return val; +} + +void +net_buf_simple_add_le16(struct os_mbuf *om, uint16_t val) +{ + val = htole16(val); + os_mbuf_append(om, &val, sizeof(val)); +} + +void +net_buf_simple_add_be16(struct os_mbuf *om, uint16_t val) +{ + val = htobe16(val); + os_mbuf_append(om, &val, sizeof(val)); +} + +void +net_buf_simple_add_be32(struct os_mbuf *om, uint32_t val) +{ + val = htobe32(val); + os_mbuf_append(om, &val, sizeof(val)); +} + +void +net_buf_simple_add_u8(struct os_mbuf *om, uint8_t val) +{ + os_mbuf_append(om, &val, 1); +} + +void +net_buf_simple_push_le16(struct os_mbuf *om, uint16_t val) +{ + uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len]; + + assert(headroom >= 2); + om->om_data -= 2; + put_le16(om->om_data, val); + om->om_len += 2; + + if (om->om_pkthdr_len) { + OS_MBUF_PKTHDR(om)->omp_len += 2; + } +} + +void +net_buf_simple_push_be16(struct os_mbuf *om, uint16_t val) +{ + uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len]; + + assert(headroom >= 2); + om->om_data -= 2; + put_be16(om->om_data, val); + om->om_len += 2; + + if (om->om_pkthdr_len) { + OS_MBUF_PKTHDR(om)->omp_len += 2; + } +} + +void +net_buf_simple_push_u8(struct os_mbuf *om, uint8_t val) +{ + uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len]; + + assert(headroom >= 1); + om->om_data -= 1; + om->om_data[0] = val; + om->om_len += 1; + + if (om->om_pkthdr_len) { + OS_MBUF_PKTHDR(om)->omp_len += 1; + } +} + +void +net_buf_add_zeros(struct os_mbuf *om, uint8_t len) +{ + uint8_t z[len]; + int rc; + + memset(z, 0, len); + + rc = os_mbuf_append(om, z, len); + if(rc) { + assert(0); + } +} + +void * +net_buf_simple_pull(struct os_mbuf *om, uint8_t len) +{ + os_mbuf_adj(om, len); + return om->om_data; +} + +void* +net_buf_simple_add(struct os_mbuf *om, uint8_t len) +{ + return os_mbuf_extend(om, len); +} + +bool +k_fifo_is_empty(struct os_eventq *q) +{ + return STAILQ_EMPTY(&q->evq_list); +} + +void * net_buf_get(struct os_eventq *fifo,s32_t t) +{ + struct os_event *ev = os_eventq_get_no_wait(fifo); + + return ev->ev_arg; +} + +uint8_t * +net_buf_simple_push(struct os_mbuf *om, uint8_t len) +{ + uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len]; + + assert(headroom >= len); + om->om_data -= len; + om->om_len += len; + + return om->om_data; +} + +void +net_buf_reserve(struct os_mbuf *om, size_t reserve) +{ + /* We need reserve to be done on fresh buf */ + assert(om->om_len == 0); + om->om_data += reserve; +} + +void +k_work_init(struct os_callout *work, os_event_fn handler) +{ + os_callout_init(work, os_eventq_dflt_get(), handler, NULL); +} + +void +k_delayed_work_init(struct k_delayed_work *w, os_event_fn *f) +{ + os_callout_init(&w->work, os_eventq_dflt_get(), f, NULL); +} + +void +k_delayed_work_cancel(struct k_delayed_work *w) +{ + os_callout_stop(&w->work); +} + +void +k_delayed_work_submit(struct k_delayed_work *w, uint32_t ms) +{ + uint32_t ticks; + + os_time_ms_to_ticks(ms, &ticks); + os_callout_reset(&w->work, ticks); +} + +void +k_work_submit(struct os_callout *w) +{ + os_callout_reset(w, 0); +} + +void +k_work_add_arg(struct os_callout *w, void *arg) +{ + w->c_ev.ev_arg = arg; +} + +void +k_delayed_work_add_arg(struct k_delayed_work *w, void *arg) +{ + w->work.c_ev.ev_arg = arg; +} + +uint32_t +k_delayed_work_remaining_get (struct k_delayed_work *w) +{ + int sr; + os_time_t t; + + OS_ENTER_CRITICAL(sr); + + t = os_callout_remaining_ticks(&w->work, os_cputime_get32()); + + OS_EXIT_CRITICAL(sr); + + /* We should return ms */ + return os_cputime_ticks_to_usecs(t) / 1000; +} + +int64_t k_uptime_get(void) +{ + /* We should return ms */ + return os_get_uptime_usec() / 1000; +} + +u32_t k_uptime_get_32(void) +{ + return k_uptime_get(); +} + +static uint8_t pub[64]; +static uint32_t priv[8]; +static bool has_pub = false; + +int +bt_dh_key_gen(const u8_t remote_pk[64], bt_dh_key_cb_t cb) +{ + uint8_t dh[32]; + + if (ble_sm_alg_gen_dhkey((uint8_t *)&remote_pk[0], (uint8_t *)&remote_pk[32], + priv, dh)) { + return -1; + } + + cb(dh); + return 0; +} + +int +bt_rand(void *buf, size_t len) +{ + int rc; + rc = ble_hs_hci_util_rand(buf, len); + if (rc != 0) { + return -1; + } + + return 0; +} + +int +bt_pub_key_gen(struct bt_pub_key_cb *new_cb) +{ + + if (ble_sm_alg_gen_key_pair(pub, priv)) { + assert(0); + return -1; + } + + new_cb->func(pub); + has_pub = true; + + return 0; +} + +uint8_t * +bt_pub_key_get(void) +{ + if (!has_pub) { + return NULL; + } + + return pub; +} + +static int +set_ad(const struct bt_data *ad, size_t ad_len, u8_t *buf, u8_t *buf_len) +{ + int i; + + for (i = 0; i < ad_len; i++) { + buf[(*buf_len)++] = ad[i].data_len + 1; + buf[(*buf_len)++] = ad[i].type; + + memcpy(&buf[*buf_len], ad[i].data, + ad[i].data_len); + *buf_len += ad[i].data_len; + } + + return 0; +} + +int +bt_le_adv_start(const struct ble_gap_adv_params *param, + const struct bt_data *ad, size_t ad_len, + const struct bt_data *sd, size_t sd_len) +{ +#if MYNEWT_VAL(BLE_EXT_ADV) + uint8_t buf[MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)]; +#else + uint8_t buf[BLE_HS_ADV_MAX_SZ]; +#endif + uint8_t buf_len = 0; + int err; + + err = set_ad(ad, ad_len, buf, &buf_len); + if (err) { + return err; + } + + err = ble_gap_adv_set_data(buf, buf_len); + if (err != 0) { + return err; + } + + err = ble_gap_adv_start(0x00, NULL, BLE_HS_FOREVER, param, NULL, NULL); + if (err) { + BT_ERR("Advertising failed: err %d", err); + return err; + } + + return 0; +} + +#if MYNEWT_VAL(BLE_MESH_PROXY) +int bt_mesh_proxy_svcs_register(void); +#endif + +void +bt_mesh_register_gatt(void) +{ +#if MYNEWT_VAL(BLE_MESH_PROXY) + bt_mesh_proxy_svcs_register(); +#endif +} diff --git a/nimble/host/mesh/src/health.c b/nimble/host/mesh/src/health.c index 6c5e8e400..124a8d177 100644 --- a/nimble/host/mesh/src/health.c +++ b/nimble/host/mesh/src/health.c @@ -6,21 +6,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include #include -#include -#include -#include -#include -#include -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_MESH_DEBUG_MODEL) -#include "common/log.h" +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_MODEL)) +#include "host/ble_hs_log.h" -#include "mesh.h" +#include "mesh/mesh.h" +#include "mesh_priv.h" #include "adv.h" #include "net.h" #include "transport.h" @@ -44,7 +39,7 @@ struct bt_mesh_health *health_srv; static void health_get_registered(struct bt_mesh_model *mod, u16_t company_id, - struct net_buf_simple *msg) + struct os_mbuf *msg) { struct bt_mesh_health *srv = mod->user_data; u8_t fault_count; @@ -76,7 +71,7 @@ static void health_get_registered(struct bt_mesh_model *mod, } static size_t health_get_current(struct bt_mesh_model *mod, - struct net_buf_simple *msg) + struct os_mbuf *msg) { struct bt_mesh_health *srv = mod->user_data; u8_t *test_id, *company_ptr; @@ -86,7 +81,7 @@ static size_t health_get_current(struct bt_mesh_model *mod, bt_mesh_model_msg_init(msg, OP_HEALTH_CURRENT_STATUS); - test_id = net_buf_simple_add(msg, sizeof(test_id)); + test_id = net_buf_simple_add(msg, 1); company_ptr = net_buf_simple_add(msg, sizeof(company_id)); fault_count = net_buf_simple_tailroom(msg) - 4; @@ -115,9 +110,9 @@ static size_t health_get_current(struct bt_mesh_model *mod, static void health_fault_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct net_buf_simple *msg = NET_BUF_SIMPLE(HEALTH_STATUS_SIZE); + struct os_mbuf *msg = NET_BUF_SIMPLE(HEALTH_STATUS_SIZE); u16_t company_id; company_id = net_buf_simple_pull_le16(buf); @@ -129,11 +124,13 @@ static void health_fault_get(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Health Current Status response"); } + + os_mbuf_free_chain(msg); } static void health_fault_clear_unrel(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_health *srv = model->user_data; u16_t company_id; @@ -149,9 +146,9 @@ static void health_fault_clear_unrel(struct bt_mesh_model *model, static void health_fault_clear(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct net_buf_simple *msg = NET_BUF_SIMPLE(HEALTH_STATUS_SIZE); + struct os_mbuf *msg = NET_BUF_SIMPLE(HEALTH_STATUS_SIZE); struct bt_mesh_health *srv = model->user_data; u16_t company_id; @@ -168,11 +165,13 @@ static void health_fault_clear(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Health Current Status response"); } + + os_mbuf_free_chain(msg); } static void health_fault_test_unrel(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_health *srv = model->user_data; const struct bt_mesh_comp *comp; @@ -198,9 +197,9 @@ static void health_fault_test_unrel(struct bt_mesh_model *model, static void health_fault_test(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct net_buf_simple *msg = NET_BUF_SIMPLE(HEALTH_STATUS_SIZE); + struct os_mbuf *msg = NET_BUF_SIMPLE(HEALTH_STATUS_SIZE); struct bt_mesh_health *srv = model->user_data; u16_t company_id; u8_t test_id; @@ -221,13 +220,15 @@ static void health_fault_test(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Health Current Status response"); } + + os_mbuf_free_chain(msg); } static void send_attention_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); struct bt_mesh_health *srv = model->user_data; u8_t time; @@ -239,11 +240,12 @@ static void send_attention_status(struct bt_mesh_model *model, net_buf_simple_add_u8(msg, time); bt_mesh_model_send(model, ctx, msg, NULL, NULL); + os_mbuf_free_chain(msg); } static void attention_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { BT_DBG(""); @@ -252,7 +254,7 @@ static void attention_get(struct bt_mesh_model *model, static void attention_set_unrel(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { u8_t time; @@ -265,7 +267,7 @@ static void attention_set_unrel(struct bt_mesh_model *model, static void attention_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { BT_DBG(""); @@ -278,7 +280,7 @@ static void send_health_period_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { /* Needed size: opcode (2 bytes) + msg + MIC */ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); struct bt_mesh_health *srv = model->user_data; bt_mesh_model_msg_init(msg, OP_HEALTH_PERIOD_STATUS); @@ -286,11 +288,12 @@ static void send_health_period_status(struct bt_mesh_model *model, net_buf_simple_add_u8(msg, srv->period); bt_mesh_model_send(model, ctx, msg, NULL, NULL); + os_mbuf_free_chain(msg); } static void health_period_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { BT_DBG(""); @@ -299,7 +302,7 @@ static void health_period_get(struct bt_mesh_model *model, static void health_period_set_unrel(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_health *srv = model->user_data; u8_t period; @@ -317,7 +320,7 @@ static void health_period_set_unrel(struct bt_mesh_model *model, static void health_period_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { BT_DBG(""); @@ -326,7 +329,7 @@ static void health_period_set(struct bt_mesh_model *model, send_health_period_status(model, ctx); } -const struct bt_mesh_model_op const bt_mesh_health_op[] = { +const struct bt_mesh_model_op bt_mesh_health_op[] = { { OP_HEALTH_FAULT_GET, 2, health_fault_get }, { OP_HEALTH_FAULT_CLEAR, 2, health_fault_clear }, { OP_HEALTH_FAULT_CLEAR_UNREL, 2, health_fault_clear_unrel }, @@ -343,7 +346,7 @@ const struct bt_mesh_model_op const bt_mesh_health_op[] = { static void health_pub(struct bt_mesh_model *mod) { - struct net_buf_simple *msg = NET_BUF_SIMPLE(HEALTH_STATUS_SIZE); + struct os_mbuf *msg = NET_BUF_SIMPLE(HEALTH_STATUS_SIZE); struct bt_mesh_health *srv = mod->user_data; size_t count; int err; @@ -361,6 +364,7 @@ static void health_pub(struct bt_mesh_model *mod) if (err) { BT_ERR("Publishing failed (err %d)", err); } + os_mbuf_free_chain(msg); } struct bt_mesh_model_pub bt_mesh_health_pub = { @@ -380,10 +384,9 @@ int bt_mesh_fault_update(struct bt_mesh_elem *elem) return 0; } -static void attention_off(struct k_work *work) +static void attention_off(struct os_event *work) { - struct bt_mesh_health *srv = CONTAINER_OF(work, struct bt_mesh_health, - attention.timer.work); + struct bt_mesh_health *srv = work->ev_arg; BT_DBG(""); if (srv->attention.off) { @@ -419,6 +422,7 @@ void bt_mesh_attention(struct bt_mesh_model *model, u8_t time) { struct bt_mesh_health *srv; + BT_DBG("bt_mesh_attention"); if (!model) { srv = health_srv; if (!srv) { diff --git a/nimble/host/mesh/src/lpn.c b/nimble/host/mesh/src/lpn.c index 029967873..2cfd9eb0a 100644 --- a/nimble/host/mesh/src/lpn.c +++ b/nimble/host/mesh/src/lpn.c @@ -6,28 +6,27 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(BLE_MESH_LOW_POWER) == 1 + #include -#include -#include -#include -#include -#include - -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_MESH_DEBUG_LOW_POWER) -#include "common/log.h" +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_LOW_POWER)) +#include "host/ble_hs_log.h" +#include "mesh/mesh.h" +#include "mesh_priv.h" #include "crypto.h" #include "adv.h" -#include "mesh.h" #include "net.h" #include "transport.h" #include "access.h" #include "beacon.h" #include "lpn.h" -#define LPN_RECV_DELAY CONFIG_BLUETOOTH_MESH_LPN_RECV_DELAY -#define SCAN_LATENCY min(CONFIG_BLUETOOTH_MESH_LPN_SCAN_LATENCY, \ +#define LPN_RECV_DELAY MYNEWT_VAL(BLE_MESH_LPN_RECV_DELAY) +#define SCAN_LATENCY min(MYNEWT_VAL(BLE_MESH_LPN_SCAN_LATENCY), \ LPN_RECV_DELAY) #define FRIEND_REQ_RETRY_TIMEOUT K_SECONDS(5) @@ -41,17 +40,17 @@ (LPN_RECV_DELAY + (lpn)->recv_win + \ POLL_RETRY_TIMEOUT)) -#define POLL_TIMEOUT(lpn) ((CONFIG_BLUETOOTH_MESH_LPN_POLL_TIMEOUT * 100) - \ +#define POLL_TIMEOUT(lpn) ((MYNEWT_VAL(BLE_MESH_LPN_POLL_TIMEOUT) * 100) - \ REQ_RETRY_DURATION(lpn)) -#define LPN_CRITERIA ((CONFIG_BLUETOOTH_MESH_LPN_MIN_QUEUE_SIZE) | \ - (CONFIG_BLUETOOTH_MESH_LPN_RSSI_FACTOR << 3) | \ - (CONFIG_BLUETOOTH_MESH_LPN_RECV_WIN_FACTOR << 5)) +#define LPN_CRITERIA ((MYNEWT_VAL(BLE_MESH_LPN_MIN_QUEUE_SIZE)) | \ + (MYNEWT_VAL(BLE_MESH_LPN_RSSI_FACTOR) << 3) | \ + (MYNEWT_VAL(BLE_MESH_LPN_RECV_WIN_FACTOR) << 5)) #define POLL_TO(to) { (u8_t)((to) >> 16), (u8_t)((to) >> 8), (u8_t)(to) } -#define LPN_POLL_TO POLL_TO(CONFIG_BLUETOOTH_MESH_LPN_POLL_TIMEOUT) +#define LPN_POLL_TO POLL_TO(MYNEWT_VAL(BLE_MESH_LPN_POLL_TIMEOUT)) -#if defined(CONFIG_BLUETOOTH_MESH_DEBUG_LOW_POWER) +#if (MYNEWT_VAL(BLE_MESH_DEBUG_LOW_POWER)) static const char *state2str(int state) { switch (state) { @@ -79,7 +78,7 @@ static const char *state2str(int state) static inline void lpn_set_state(int state) { -#if defined(CONFIG_BLUETOOTH_MESH_DEBUG_LOW_POWER) +#if (MYNEWT_VAL(BLE_MESH_DEBUG_LOW_POWER)) BT_DBG("%s -> %s", state2str(bt_mesh.lpn.state), state2str(state)); #endif bt_mesh.lpn.state = state; @@ -87,7 +86,7 @@ static inline void lpn_set_state(int state) static void clear_friendship(bool disable); -static void friend_clear_sent(struct net_buf *buf, int err) +static void friend_clear_sent(struct os_mbuf *buf, int err) { /* We're switching away from Low Power behavior, so permanently * enable scanning. @@ -168,7 +167,7 @@ static void clear_friendship(bool disable) k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT); } -static void friend_req_sent(struct net_buf *buf, int err) +static void friend_req_sent(struct os_mbuf *buf, int err) { if (err) { BT_ERR("Sending Friend Request failed (err %d)", err); @@ -247,7 +246,7 @@ static inline void group_clear(atomic_t *target, atomic_t *source) #endif } -static void req_sent(struct net_buf *buf, int err) +static void req_sent(struct os_mbuf *buf, int err) { struct bt_mesh_lpn *lpn = &bt_mesh.lpn; @@ -383,16 +382,16 @@ void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx) } int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct bt_mesh_ctl_friend_offer *msg = (void *)buf->data; + struct bt_mesh_ctl_friend_offer *msg = (void *)buf->om_data; struct bt_mesh_lpn *lpn = &bt_mesh.lpn; struct bt_mesh_subnet *sub = rx->sub; struct bt_mesh_friend_cred *cred; u16_t frnd_counter; int err; - if (buf->len < sizeof(*msg)) { + if (buf->om_len < sizeof(*msg)) { BT_WARN("Too short Friend Offer"); return -EINVAL; } @@ -449,13 +448,13 @@ int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx, } int bt_mesh_lpn_friend_clear_cfm(struct bt_mesh_net_rx *rx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct bt_mesh_ctl_friend_clear_confirm *msg = (void *)buf->data; + struct bt_mesh_ctl_friend_clear_confirm *msg = (void *)buf->om_data; struct bt_mesh_lpn *lpn = &bt_mesh.lpn; u16_t addr, counter; - if (buf->len < sizeof(*msg)) { + if (buf->om_len < sizeof(*msg)) { BT_WARN("Too short Friend Clear Confirm"); return -EINVAL; } @@ -605,11 +604,11 @@ static bool sub_update(u8_t op) return true; } -static void lpn_timeout(struct k_work *work) +static void lpn_timeout(struct os_event *work) { struct bt_mesh_lpn *lpn = &bt_mesh.lpn; -#if defined(CONFIG_BLUETOOTH_MESH_DEBUG_LOW_POWER) +#if (MYNEWT_VAL(BLE_MESH_DEBUG_LOW_POWER)) BT_DBG("state: %s", state2str(lpn->state)); #endif @@ -718,12 +717,12 @@ static s32_t poll_timeout(struct bt_mesh_lpn *lpn) } int bt_mesh_lpn_friend_sub_cfm(struct bt_mesh_net_rx *rx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct bt_mesh_ctl_friend_sub_confirm *msg = (void *)buf->data; + struct bt_mesh_ctl_friend_sub_confirm *msg = (void *)buf->om_data; struct bt_mesh_lpn *lpn = &bt_mesh.lpn; - if (buf->len < sizeof(*msg)) { + if (buf->om_len < sizeof(*msg)) { BT_WARN("Too short Friend Subscription Confirm"); return -EINVAL; } @@ -783,14 +782,14 @@ int bt_mesh_lpn_friend_sub_cfm(struct bt_mesh_net_rx *rx, } int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { - struct bt_mesh_ctl_friend_update *msg = (void *)buf->data; + struct bt_mesh_ctl_friend_update *msg = (void *)buf->om_data; struct bt_mesh_lpn *lpn = &bt_mesh.lpn; struct bt_mesh_subnet *sub = rx->sub; u32_t iv_index; - if (buf->len < sizeof(*msg)) { + if (buf->om_len < sizeof(*msg)) { BT_WARN("Too short Friend Update"); return -EINVAL; } @@ -880,3 +879,5 @@ int bt_mesh_lpn_init(void) return 0; } + +#endif //MYNEWT_VAL(BLE_MESH_LOW_POWER) == 1 diff --git a/nimble/host/mesh/src/lpn.h b/nimble/host/mesh/src/lpn.h index dd5a957b8..b1df8b315 100644 --- a/nimble/host/mesh/src/lpn.h +++ b/nimble/host/mesh/src/lpn.h @@ -5,41 +5,55 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#ifndef __LPN_H__ +#define __LPN_H__ -int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx, - struct net_buf_simple *buf); -int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx, - struct net_buf_simple *buf); -int bt_mesh_lpn_friend_clear_cfm(struct bt_mesh_net_rx *rx, - struct net_buf_simple *buf); -int bt_mesh_lpn_friend_sub_cfm(struct bt_mesh_net_rx *rx, - struct net_buf_simple *buf); +#include "mesh/mesh.h" -static inline bool bt_mesh_lpn_established(void) +int +bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx, struct os_mbuf *buf); +int +bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx, struct os_mbuf *buf); +int +bt_mesh_lpn_friend_clear_cfm(struct bt_mesh_net_rx *rx, struct os_mbuf *buf); +int +bt_mesh_lpn_friend_sub_cfm(struct bt_mesh_net_rx *rx, struct os_mbuf *buf); + +static inline bool +bt_mesh_lpn_established(void) { -#if defined(CONFIG_BLUETOOTH_MESH_LOW_POWER) - return (bt_mesh.lpn.state >= BT_MESH_LPN_ESTABLISHED); +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) + return (bt_mesh.lpn.state >= BT_MESH_LPN_ESTABLISHED); #else - return false; + return false; #endif } -static inline bool bt_mesh_lpn_waiting_update(void) +static inline bool +bt_mesh_lpn_waiting_update(void) { -#if defined(CONFIG_BLUETOOTH_MESH_LOW_POWER) - return (bt_mesh.lpn.state == BT_MESH_LPN_WAIT_UPDATE); +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) + return (bt_mesh.lpn.state == BT_MESH_LPN_WAIT_UPDATE); #else - return false; + return false; #endif } -void bt_mesh_lpn_friend_poll(void); +void +bt_mesh_lpn_friend_poll(void); -void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx); +void +bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx); -void bt_mesh_lpn_group_add(u16_t group); -void bt_mesh_lpn_group_del(u16_t *groups, size_t group_count); +void +bt_mesh_lpn_group_add(u16_t group); +void +bt_mesh_lpn_group_del(u16_t *groups, size_t group_count); -void bt_mesh_lpn_disable(void); +void +bt_mesh_lpn_disable(void); -int bt_mesh_lpn_init(void); +int +bt_mesh_lpn_init(void); + +#endif diff --git a/nimble/host/mesh/src/main.c b/nimble/host/mesh/src/main.c deleted file mode 100644 index e4c78bf60..000000000 --- a/nimble/host/mesh/src/main.c +++ /dev/null @@ -1,185 +0,0 @@ -/* Bluetooth Mesh */ - -/* - * Copyright (c) 2017 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -#include -#include -#include -#include - -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_MESH_DEBUG) -#include "common/log.h" - -#include "test.h" -#include "adv.h" -#include "prov.h" -#include "net.h" -#include "beacon.h" -#include "lpn.h" -#include "friend.h" -#include "transport.h" -#include "access.h" -#include "foundation.h" -#include "proxy.h" -#include "mesh.h" - -static bool provisioned; - -int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx, - u8_t flags, u32_t iv_index, u32_t seq, - u16_t addr, const u8_t dev_key[16]) -{ - int err; - - BT_INFO("Primary Element: 0x%04x", addr); - - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_PB_GATT)) { - bt_mesh_proxy_prov_disable(); - } - - err = bt_mesh_net_create(net_idx, flags, net_key, iv_index); - if (err) { - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_PB_GATT)) { - bt_mesh_proxy_prov_enable(); - } - - return err; - } - - bt_mesh.seq = seq; - - bt_mesh_comp_provision(addr); - - memcpy(bt_mesh.dev_key, dev_key, 16); - - provisioned = true; - - if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) { - bt_mesh_beacon_enable(); - } else { - bt_mesh_beacon_disable(); - } - - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_GATT_PROXY) && - bt_mesh_gatt_proxy_get() != BT_MESH_GATT_PROXY_NOT_SUPPORTED) { - bt_mesh_proxy_gatt_enable(); - bt_mesh_adv_update(); - } - - /* If PB-ADV is disabled then scanning will have been disabled */ - if (!IS_ENABLED(CONFIG_BLUETOOTH_MESH_PB_ADV)) { - bt_mesh_scan_enable(); - } - - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER)) { - bt_mesh_lpn_init(); - } - - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_FRIEND)) { - bt_mesh_friend_init(); - } - - return 0; -} - -void bt_mesh_reset(void) -{ - if (!provisioned) { - goto enable_beacon; - } - - bt_mesh_comp_unprovision(); - - bt_mesh.iv_index = 0; - bt_mesh.seq = 0; - bt_mesh.iv_update = 0; - bt_mesh.valid = 0; - bt_mesh.last_update = 0; - bt_mesh.ivu_initiator = 0; - - k_delayed_work_cancel(&bt_mesh.ivu_complete); - - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER)) { - bt_mesh_lpn_disable(); - } - - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_GATT_PROXY)) { - bt_mesh_proxy_gatt_disable(); - } - - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_PB_GATT)) { - bt_mesh_proxy_prov_enable(); - } - - memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key)); - - memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl)); - - provisioned = false; - -enable_beacon: - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_PB_ADV)) { - /* Make sure we're scanning for provisioning inviations */ - bt_mesh_scan_enable(); - /* Enable unprovisioned beacon sending */ - bt_mesh_beacon_enable(); - } else { - bt_mesh_scan_disable(); - bt_mesh_beacon_disable(); - } -} - -bool bt_mesh_is_provisioned(void) -{ - return provisioned; -} - -int bt_mesh_init(const struct bt_mesh_prov *prov, - const struct bt_mesh_comp *comp) -{ - int err; - - err = bt_mesh_test(); - if (err) { - return err; - } - - err = bt_mesh_comp_register(comp); - if (err) { - return err; - } - - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_PROV)) { - bt_mesh_prov_init(prov); - } - - bt_mesh_net_init(); - bt_mesh_trans_init(); - bt_mesh_beacon_init(); - bt_mesh_adv_init(); - - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_PROXY)) { - bt_mesh_proxy_init(); - } - - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_PB_ADV)) { - /* Make sure we're scanning for provisioning inviations */ - bt_mesh_scan_enable(); - /* Enable unprovisioned beacon sending */ - bt_mesh_beacon_enable(); - } - - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_PB_GATT)) { - bt_mesh_proxy_prov_enable(); - } - - return 0; -} diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c new file mode 100644 index 000000000..9ab61321c --- /dev/null +++ b/nimble/host/mesh/src/mesh.c @@ -0,0 +1,202 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "syscfg/syscfg.h" +#include "os/os_mbuf.h" +#include "mesh/mesh.h" + +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG)) +#include "host/ble_hs_log.h" + +#include "adv.h" +#include "prov.h" +#include "net.h" +#include "beacon.h" +#include "lpn.h" +#include "friend.h" +#include "transport.h" +#include "access.h" +#include "foundation.h" +#include "proxy.h" +#include "mesh_priv.h" + +static bool provisioned; + +int +bt_mesh_provision(const u8_t net_key[16], u16_t net_idx, u8_t flags, + u32_t iv_index, u32_t seq, u16_t addr, const u8_t dev_key[16]) +{ + int err; + + BLE_HS_LOG(INFO, "Primary Element: 0x%04x", addr); + + if ((MYNEWT_VAL(BLE_MESH_PB_GATT))) { + bt_mesh_proxy_prov_disable(); + } + + err = bt_mesh_net_create(net_idx, flags, net_key, iv_index); + if (err) { + if ((MYNEWT_VAL(BLE_MESH_PB_GATT))) { + bt_mesh_proxy_prov_enable(); + } + + return err; + } + + bt_mesh.seq = seq; + + bt_mesh_comp_provision(addr); + + memcpy(bt_mesh.dev_key, dev_key, 16); + + provisioned = true; + + if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) { + bt_mesh_beacon_enable(); + } + else { + bt_mesh_beacon_disable(); + } + + if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + && bt_mesh_gatt_proxy_get() != BT_MESH_GATT_PROXY_NOT_SUPPORTED) { + bt_mesh_proxy_gatt_enable(); + bt_mesh_adv_update(); + } + + /* If PB-ADV is disabled then scanning will have been disabled */ + if (!(MYNEWT_VAL(BLE_MESH_PB_ADV))) { + bt_mesh_scan_enable(); + } + + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { + bt_mesh_lpn_init(); + } + + if ((MYNEWT_VAL(BLE_MESH_FRIEND))) { + bt_mesh_friend_init(); + } + + return 0; +} + +void +bt_mesh_reset(void) +{ + if (!provisioned) { + goto enable_beacon; + } + + bt_mesh_comp_unprovision(); + + bt_mesh.iv_index = 0; + bt_mesh.seq = 0; + bt_mesh.iv_update = 0; + bt_mesh.valid = 0; + bt_mesh.last_update = 0; + bt_mesh.ivu_initiator = 0; + + k_delayed_work_cancel(&bt_mesh.ivu_complete); + + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { + bt_mesh_lpn_disable(); + } + + if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY))) { + bt_mesh_proxy_gatt_disable(); + } + + if ((MYNEWT_VAL(BLE_MESH_PB_GATT))) { + bt_mesh_proxy_prov_enable(); + } + + memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key)); + + memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl)); + + provisioned = false; + +enable_beacon: + if ((MYNEWT_VAL(BLE_MESH_PB_ADV))) { + /* Make sure we're scanning for provisioning inviations */ + bt_mesh_scan_enable(); + /* Enable unprovisioned beacon sending */ + bt_mesh_beacon_enable(); + } + else { + bt_mesh_scan_disable(); + bt_mesh_beacon_disable(); + } +} + +bool +bt_mesh_is_provisioned(void) +{ + return provisioned; +} + +static int +bt_mesh_gap_event(struct ble_gap_event *event, void *arg) +{ + ble_adv_gap_mesh_cb(event, arg); + +#if (MYNEWT_VAL(BLE_MESH_PROXY)) + ble_mesh_proxy_gap_event(event, arg); +#endif + + return 0; +} + +int +bt_mesh_init(uint8_t own_addr_type, const struct bt_mesh_prov *prov, + const struct bt_mesh_comp *comp) +{ + int err; + + err = bt_mesh_comp_register(comp); + if (err) { + return err; + } + + if (MYNEWT_VAL(BLE_MESH_PROV)) { + bt_mesh_prov_init(prov); + } + +#if (MYNEWT_VAL(BLE_MESH_PROXY)) + bt_mesh_proxy_init(); + /* Need this to proper link.rx.buf allocation */ + bt_mesh_prov_reset_link(); +#endif + + bt_mesh_net_init(); + + bt_mesh_trans_init(); + + bt_mesh_beacon_init(); + + bt_mesh_adv_init(own_addr_type); + +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) + /* Make sure we're scanning for provisioning inviations */ + bt_mesh_scan_enable(); + /* Enable unprovisioned beacon sending */ + + bt_mesh_beacon_enable(); +#endif + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + bt_mesh_proxy_prov_enable(); +#endif + + ble_gap_mesh_cb_register(bt_mesh_gap_event, NULL); + + return 0; +} diff --git a/nimble/host/mesh/src/mesh.h b/nimble/host/mesh/src/mesh_priv.h similarity index 82% rename from nimble/host/mesh/src/mesh.h rename to nimble/host/mesh/src/mesh_priv.h index 7022f7aca..697b406a6 100644 --- a/nimble/host/mesh/src/mesh.h +++ b/nimble/host/mesh/src/mesh_priv.h @@ -5,6 +5,8 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#ifndef __MESH_PRIV_H +#define __MESH_PRIV_H #define BT_MESH_KEY_PRIMARY 0x0000 #define BT_MESH_KEY_ANY 0xffff @@ -13,6 +15,7 @@ #define BT_MESH_ADDR_IS_GROUP(addr) ((addr) >= 0xc000 && (addr) <= 0xff00) #define BT_MESH_ADDR_IS_VIRTUAL(addr) ((addr) >= 0x8000 && (addr) < 0xc000) -struct bt_mesh_net; +bool +bt_mesh_is_provisioned(void); -bool bt_mesh_is_provisioned(void); +#endif diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index 703242cc0..e6abc7e26 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -6,25 +6,19 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include "os/os_mbuf.h" +#include "mesh/mesh.h" -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_MESH_DEBUG_NET) -#include "common/log.h" +#define BT_DBG_ENABLED MYNEWT_VAL(BLE_MESH_MSG_DEBUG_NET) +#include "host/ble_hs_log.h" #include "crypto.h" #include "adv.h" -#include "mesh.h" +#include "mesh_priv.h" #include "net.h" #include "lpn.h" #include "friend.h" @@ -37,13 +31,13 @@ /* Seq limit after IV Update is triggered */ #define IV_UPDATE_SEQ_LIMIT 8000000 -#if defined(CONFIG_BLUETOOTH_MESH_IV_UPDATE_TEST) +#if MYNEWT_VAL(BLE_MESH_IV_UPDATE_TEST) /* Small test timeout for IV Update Procedure testing */ #define IV_UPDATE_TIMEOUT K_SECONDS(120) #else /* Maximum time to stay in IV Update mode (96 < time < 144) */ #define IV_UPDATE_TIMEOUT K_HOURS(120) -#endif /* CONFIG_BLUETOOTH_MESH_IV_UPDATE_TEST */ +#endif /* MYNEWT_VAL(BLE_MESH_IV_UPDATE_TEST) */ #define IVI(pdu) ((pdu)[0] >> 7) #define NID(pdu) ((pdu)[0] & 0x7f) @@ -51,10 +45,10 @@ #define TTL(pdu) ((pdu)[1] & 0x7f) /* Determine how many friendship credentials we need */ -#if defined(CONFIG_BLUETOOTH_MESH_FRIEND) -#define FRIEND_CRED_COUNT CONFIG_BLUETOOTH_MESH_FRIEND_LPN_COUNT -#elif defined(CONFIG_BLUETOOTH_MESH_LOW_POWER) -#define FRIEND_CRED_COUNT CONFIG_BLUETOOTH_MESH_SUBNET_COUNT +#if (MYNEWT_VAL(BLE_MESH_FRIEND)) +#define FRIEND_CRED_COUNT MYNEWT_VAL(BLE_MESH_FRIEND_LPN_COUNT) +#elif (MYNEWT_VAL(BLE_MESH_LOW_POWER)) +#define FRIEND_CRED_COUNT MYNEWT_VAL(BLE_MESH_SUBNET_COUNT) #else #define FRIEND_CRED_COUNT 0 #endif @@ -63,18 +57,18 @@ static struct bt_mesh_friend_cred friend_cred[FRIEND_CRED_COUNT]; #endif -static u64_t msg_cache[CONFIG_BLUETOOTH_MESH_MSG_CACHE_SIZE]; +static u64_t msg_cache[MYNEWT_VAL(BLE_MESH_MSG_CACHE_SIZE)]; static u16_t msg_cache_next; /* Singleton network context (the implementation only supports one) */ struct bt_mesh_net bt_mesh = { .sub = { - [0 ... (CONFIG_BLUETOOTH_MESH_SUBNET_COUNT - 1)] = { + [0 ... (MYNEWT_VAL(BLE_MESH_SUBNET_COUNT) - 1)] = { .net_idx = BT_MESH_KEY_UNUSED, } }, .app_keys = { - [0 ... (CONFIG_BLUETOOTH_MESH_APP_KEY_COUNT - 1)] = { + [0 ... (MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT) - 1)] = { .net_idx = BT_MESH_KEY_UNUSED, } }, @@ -83,7 +77,7 @@ struct bt_mesh_net bt_mesh = { static u32_t dup_cache[4]; static int dup_cache_next; -static bool check_dup(struct net_buf_simple *data) +static bool check_dup(struct os_mbuf *data) { const u8_t *tail = net_buf_simple_tail(data); u32_t val; @@ -103,18 +97,18 @@ static bool check_dup(struct net_buf_simple *data) return false; } -static u64_t msg_hash(struct net_buf_simple *pdu) +static u64_t msg_hash(struct os_mbuf *pdu) { u8_t *tpdu_last; u64_t hash; /* Last byte of TransportPDU */ - tpdu_last = net_buf_simple_tail(pdu) - (CTL(pdu->data) ? 8 : 4) - 1; + tpdu_last = net_buf_simple_tail(pdu) - (CTL(pdu->om_data) ? 8 : 4) - 1; - ((u8_t *)(&hash))[0] = pdu->data[0]; - ((u8_t *)(&hash))[1] = (pdu->data[1] & 0xc0); + ((u8_t *)(&hash))[0] = pdu->om_data[0]; + ((u8_t *)(&hash))[1] = (pdu->om_data[1] & 0xc0); ((u8_t *)(&hash))[2] = *tpdu_last; - memcpy(&((u8_t *)&hash)[3], &pdu->data[2], 5); + memcpy(&((u8_t *)&hash)[3], &pdu->om_data[2], 5); return hash; } @@ -138,7 +132,7 @@ static bool msg_is_known(u64_t hash) return false; } -static inline u32_t net_seq(struct net_buf_simple *buf) +static inline u32_t net_seq(struct os_mbuf *buf) { return ((net_buf_simple_pull_u8(buf) << 16) & 0xff0000) | ((net_buf_simple_pull_u8(buf) << 8) & 0xff00) | @@ -190,7 +184,7 @@ int bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys, BT_DBG("NetID %s", bt_hex(keys->net_id, 8)); -#if defined(CONFIG_BLUETOOTH_MESH_GATT_PROXY) +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) err = bt_mesh_identity_key(key, keys->identity); if (err) { BT_ERR("Unable to generate IdentityKey"); @@ -211,8 +205,8 @@ int bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys, return 0; } -#if (defined(CONFIG_BLUETOOTH_MESH_LOW_POWER) || \ - defined(CONFIG_BLUETOOTH_MESH_FRIEND)) +#if ((MYNEWT_VAL(BLE_MESH_LOW_POWER)) || \ + (MYNEWT_VAL(BLE_MESH_FRIEND))) int bt_mesh_friend_cred_set(struct bt_mesh_friend_cred *cred, u8_t idx, const u8_t net_key[16]) { @@ -220,7 +214,7 @@ int bt_mesh_friend_cred_set(struct bt_mesh_friend_cred *cred, u8_t idx, int err; u8_t p[9]; -#if defined(CONFIG_BLUETOOTH_MESH_LOW_POWER) +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) if (cred->addr == bt_mesh.lpn.frnd) { lpn_addr = bt_mesh_primary_addr(); frnd_addr = cred->addr; @@ -449,7 +443,7 @@ int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16], bt_mesh.valid = 1; sub->net_idx = idx; - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_GATT_PROXY)) { + if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY))) { sub->node_id = BT_MESH_NODE_IDENTITY_RUNNING; } else { sub->node_id = BT_MESH_NODE_IDENTITY_NOT_SUPPORTED; @@ -503,8 +497,8 @@ bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key) BT_DBG("KR Phase 0x%02x -> Normal", sub->kr_phase); memcpy(&sub->keys[0], &sub->keys[1], sizeof(sub->keys[0])); - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER) || - IS_ENABLED(CONFIG_BLUETOOTH_MESH_FRIEND)) { + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER)) || + (MYNEWT_VAL(BLE_MESH_FRIEND))) { bt_mesh_friend_cred_refresh(sub->net_idx); } sub->kr_phase = BT_MESH_KR_NORMAL; @@ -575,7 +569,7 @@ void bt_mesh_iv_update(u32_t iv_index, bool iv_update) } } - if (!IS_ENABLED(CONFIG_BLUETOOTH_MESH_IV_UPDATE_TEST)) { + if (!(MYNEWT_VAL(BLE_MESH_IV_UPDATE_TEST))) { s64_t delta = k_uptime_get() - bt_mesh.last_update; if (delta < K_HOURS(96)) { @@ -619,13 +613,13 @@ do_update: } } -int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf, +int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct os_mbuf *buf, bool new_key, bool friend_cred, bt_mesh_adv_func_t cb) { const u8_t *enc, *priv; int err; - BT_DBG("net_idx 0x%04x, len %u", sub->net_idx, buf->len); + BT_DBG("net_idx 0x%04x, len %u", sub->net_idx, buf->om_len); if (friend_cred) { err = friend_cred_get(sub->net_idx, BT_MESH_ADDR_UNASSIGNED, @@ -638,30 +632,30 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf, priv = sub->keys[new_key].privacy; } - err = bt_mesh_net_obfuscate(buf->data, BT_MESH_NET_IVI_TX, priv); + err = bt_mesh_net_obfuscate(buf->om_data, BT_MESH_NET_IVI_TX, priv); if (err) { BT_ERR("deobfuscate failed (err %d)", err); return err; } - err = bt_mesh_net_decrypt(enc, &buf->b, BT_MESH_NET_IVI_TX, false); + err = bt_mesh_net_decrypt(enc, buf, BT_MESH_NET_IVI_TX, false); if (err) { BT_ERR("decrypt failed (err %d)", err); return err; } /* Update with a new sequence number */ - buf->data[2] = (bt_mesh.seq >> 16); - buf->data[3] = (bt_mesh.seq >> 8); - buf->data[4] = bt_mesh.seq++; + buf->om_data[2] = (bt_mesh.seq >> 16); + buf->om_data[3] = (bt_mesh.seq >> 8); + buf->om_data[4] = bt_mesh.seq++; - err = bt_mesh_net_encrypt(enc, &buf->b, BT_MESH_NET_IVI_TX, false); + err = bt_mesh_net_encrypt(enc, buf, BT_MESH_NET_IVI_TX, false); if (err) { BT_ERR("encrypt failed (err %d)", err); return err; } - err = bt_mesh_net_obfuscate(buf->data, BT_MESH_NET_IVI_TX, priv); + err = bt_mesh_net_obfuscate(buf->om_data, BT_MESH_NET_IVI_TX, priv); if (err) { BT_ERR("obfuscate failed (err %d)", err); return err; @@ -677,20 +671,20 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf, return 0; } -#if defined(CONFIG_BLUETOOTH_MESH_LOCAL_INTERFACE) -static void bt_mesh_net_local(struct k_work *work) +#if (MYNEWT_VAL(BLE_MESH_LOCAL_INTERFACE)) +static void bt_mesh_net_local(struct os_event *work) { - struct net_buf *buf; + struct os_mbuf *buf; while ((buf = net_buf_get(&bt_mesh.local_queue, K_NO_WAIT))) { - BT_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len)); - bt_mesh_net_recv(&buf->b, 0, BT_MESH_NET_IF_LOCAL); + BT_DBG("len %u: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + bt_mesh_net_recv(buf, 0, BT_MESH_NET_IF_LOCAL); net_buf_unref(buf); } } #endif -int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf, +int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct os_mbuf *buf, bool proxy) { const bool ctl = (tx->ctx->app_idx == BT_MESH_KEY_UNUSED); @@ -759,21 +753,21 @@ int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf, return err; } - return bt_mesh_net_obfuscate(buf->data, BT_MESH_NET_IVI_TX, priv); + return bt_mesh_net_obfuscate(buf->om_data, BT_MESH_NET_IVI_TX, priv); } -int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, +int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct os_mbuf *buf, bt_mesh_adv_func_t cb) { int err; BT_DBG("src 0x%04x dst 0x%04x len %u headroom %zu tailroom %zu", - tx->src, tx->ctx->addr, buf->len, net_buf_headroom(buf), + tx->src, tx->ctx->addr, buf->om_len, net_buf_headroom(buf), net_buf_tailroom(buf)); - BT_DBG("Payload len %u: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("Payload len %u: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); BT_DBG("Seq 0x%06x", bt_mesh.seq); -#if defined(CONFIG_BLUETOOTH_MESH_LOW_POWER) +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) /* Communication between LPN & Friend should always be using * the Friendship Credentials. Any other destination should * use the Master Credentials. @@ -787,21 +781,21 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, tx->ctx->send_ttl = bt_mesh_default_ttl_get(); } - err = bt_mesh_net_encode(tx, &buf->b, false); + err = bt_mesh_net_encode(tx, buf, false); if (err) { goto done; } /* Deliver to GATT Proxy Clients if necessary */ - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_GATT_PROXY)) { - if (bt_mesh_proxy_relay(&buf->b, tx->ctx->addr) && + if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY))) { + if (bt_mesh_proxy_relay(buf, tx->ctx->addr) && BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { err = 0; goto done; } } -#if defined(CONFIG_BLUETOOTH_MESH_LOCAL_INTERFACE) +#if (MYNEWT_VAL(BLE_MESH_LOCAL_INTERFACE)) /* Deliver to local network interface if necessary */ if (bt_mesh_fixed_group_match(tx->ctx->addr) || bt_mesh_elem_find(tx->ctx->addr)) { @@ -877,7 +871,7 @@ struct bt_mesh_subnet *bt_mesh_subnet_find(const u8_t net_id[8], u8_t flags, static int net_decrypt(struct bt_mesh_subnet *sub, u8_t idx, const u8_t *data, size_t data_len, struct bt_mesh_net_rx *rx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { const u8_t *enc, *priv; @@ -911,7 +905,7 @@ static int net_decrypt(struct bt_mesh_subnet *sub, u8_t idx, const u8_t *data, net_buf_simple_init(buf, 0); memcpy(net_buf_simple_add(buf, data_len), data, data_len); - if (bt_mesh_net_obfuscate(buf->data, BT_MESH_NET_IVI_RX(rx), priv)) { + if (bt_mesh_net_obfuscate(buf->om_data, BT_MESH_NET_IVI_RX(rx), priv)) { return -ENOENT; } @@ -919,7 +913,7 @@ static int net_decrypt(struct bt_mesh_subnet *sub, u8_t idx, const u8_t *data, return -EALREADY; } - rx->ctx.addr = sys_get_be16(&buf->data[5]); + rx->ctx.addr = sys_get_be16(&buf->om_data[5]); if (!BT_MESH_ADDR_IS_UNICAST(rx->ctx.addr)) { BT_WARN("Ignoring non-unicast src addr 0x%04x", rx->ctx.addr); return -EINVAL; @@ -927,7 +921,7 @@ static int net_decrypt(struct bt_mesh_subnet *sub, u8_t idx, const u8_t *data, BT_DBG("src 0x%04x", rx->ctx.addr); - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_PROXY) && + if ((MYNEWT_VAL(BLE_MESH_PROXY)) && rx->net_if == BT_MESH_NET_IF_PROXY_CFG) { return bt_mesh_net_decrypt(enc, buf, BT_MESH_NET_IVI_RX(rx), true); @@ -938,7 +932,7 @@ static int net_decrypt(struct bt_mesh_subnet *sub, u8_t idx, const u8_t *data, static int net_find_and_decrypt(const u8_t *data, size_t data_len, struct bt_mesh_net_rx *rx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { int i; @@ -975,17 +969,17 @@ static int net_find_and_decrypt(const u8_t *data, size_t data_len, return false; } -#if (defined(CONFIG_BLUETOOTH_MESH_RELAY) || \ - defined(CONFIG_BLUETOOTH_MESH_FRIEND) || \ - defined(CONFIG_BLUETOOTH_MESH_GATT_PROXY)) -static void bt_mesh_net_relay(struct net_buf_simple *sbuf, +#if ((MYNEWT_VAL(BLE_MESH_RELAY)) || \ + (MYNEWT_VAL(BLE_MESH_FRIEND)) || \ + (MYNEWT_VAL(BLE_MESH_GATT_PROXY))) +static void bt_mesh_net_relay(struct os_mbuf *sbuf, struct bt_mesh_net_rx *rx) { const u8_t *enc, *priv; - struct net_buf *buf; + struct os_mbuf *buf; u8_t nid, transmit; - BT_DBG("TTL %u CTL %u dst 0x%04x", rx->ctx.recv_ttl, CTL(sbuf->data), + BT_DBG("TTL %u CTL %u dst 0x%04x", rx->ctx.recv_ttl, CTL(sbuf->om_data), rx->dst); if (rx->ctx.recv_ttl <= 1) { @@ -1000,13 +994,13 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, return; } - net_buf_add_mem(buf, sbuf->data, sbuf->len); + net_buf_add_mem(buf, sbuf->om_data, sbuf->om_len); /* Only decrement TTL for non-locally originated packets */ if (rx->net_if != BT_MESH_NET_IF_LOCAL) { /* Leave CTL bit intact */ - buf->data[1] &= 0x80; - buf->data[1] |= rx->ctx.recv_ttl - 1; + buf->om_data[1] &= 0x80; + buf->om_data[1] |= rx->ctx.recv_ttl - 1; } if (rx->sub->kr_phase == BT_MESH_KR_PHASE_2) { @@ -1037,37 +1031,37 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, } } - BT_DBG("Relaying packet. TTL is now %u", TTL(buf->data)); + BT_DBG("Relaying packet. TTL is now %u", TTL(buf->om_data)); /* Update NID if RX or TX is with friend credentials */ if (rx->ctx.friend_cred || bt_mesh_friend_dst_is_lpn(rx->dst)) { - buf->data[0] &= 0x80; /* Clear everything except IVI */ - buf->data[0] |= nid; + buf->om_data[0] &= 0x80; /* Clear everything except IVI */ + buf->om_data[0] |= nid; } /* We re-encrypt and obfuscate using the received IVI rather than * the normal TX IVI (which may be different) since the transport * layer nonce includes the IVI. */ - if (bt_mesh_net_encrypt(enc, &buf->b, BT_MESH_NET_IVI_RX(rx), false)) { + if (bt_mesh_net_encrypt(enc, buf, BT_MESH_NET_IVI_RX(rx), false)) { BT_ERR("Re-encrypting failed"); goto done; } - if (bt_mesh_net_obfuscate(buf->data, BT_MESH_NET_IVI_RX(rx), priv)) { + if (bt_mesh_net_obfuscate(buf->om_data, BT_MESH_NET_IVI_RX(rx), priv)) { BT_ERR("Re-obfuscating failed"); goto done; } - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_FRIEND)) { + if ((MYNEWT_VAL(BLE_MESH_FRIEND))) { if (bt_mesh_friend_enqueue(buf, rx->dst) && BT_MESH_ADDR_IS_UNICAST(rx->dst)) { goto done; } } - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_GATT_PROXY)) { - if (bt_mesh_proxy_relay(&buf->b, rx->dst) && + if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY))) { + if (bt_mesh_proxy_relay(buf, rx->dst) && BT_MESH_ADDR_IS_UNICAST(rx->dst)) { goto done; } @@ -1083,13 +1077,13 @@ done: } #endif /* RELAY || FRIEND || GATT_PROXY */ -int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, - struct bt_mesh_net_rx *rx, struct net_buf_simple *buf, +int bt_mesh_net_decode(struct os_mbuf *data, enum bt_mesh_net_if net_if, + struct bt_mesh_net_rx *rx, struct os_mbuf *buf, struct net_buf_simple_state *state) { - if (data->len < 18) { - BT_WARN("Dropping too short mesh packet (len %u)", data->len); - BT_WARN("%s", bt_hex(data->data, data->len)); + if (data->om_len < 18) { + BT_WARN("Dropping too short mesh packet (len %u)", data->om_len); + BT_WARN("%s", bt_hex(data->om_data, data->om_len)); return -EINVAL; } @@ -1097,7 +1091,7 @@ int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, return -EINVAL; } - BT_DBG("%u bytes: %s", data->len, bt_hex(data->data, data->len)); + BT_DBG("%u bytes: %s", data->om_len, bt_hex(data->om_data, data->om_len)); rx->net_if = net_if; @@ -1105,7 +1099,7 @@ int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, rx->hash = msg_hash(data); } - if (!net_find_and_decrypt(data->data, data->len, rx, buf)) { + if (!net_find_and_decrypt(data->om_data, data->om_len, rx, buf)) { BT_DBG("Unable to find matching net for packet"); return -ENOENT; } @@ -1118,7 +1112,7 @@ int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, net_buf_simple_save(buf, state); } - rx->ctx.recv_ttl = TTL(buf->data); + rx->ctx.recv_ttl = TTL(buf->om_data); /* Default to responding with TTL 0 for non-routed messages */ if (rx->ctx.recv_ttl == 0) { @@ -1127,13 +1121,13 @@ int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, rx->ctx.send_ttl = BT_MESH_TTL_DEFAULT; } - rx->ctl = CTL(buf->data); + rx->ctl = CTL(buf->om_data); net_buf_simple_pull(buf, 2); /* SRC, already parsed by net_decrypt() */ rx->seq = net_seq(buf); net_buf_simple_pull(buf, 2); rx->dst = net_buf_simple_pull_be16(buf); - BT_DBG("Decryption successful. Payload len %u", buf->len); + BT_DBG("Decryption successful. Payload len %u", buf->om_len); if (net_if != BT_MESH_NET_IF_LOCAL && bt_mesh_elem_find(rx->ctx.addr)) { BT_DBG("Dropping locally originated packet"); @@ -1146,29 +1140,29 @@ int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, BT_DBG("src 0x%04x dst 0x%04x ttl %u", rx->ctx.addr, rx->dst, rx->ctx.recv_ttl); - BT_DBG("PDU: %s", bt_hex(buf->data, buf->len)); + BT_DBG("PDU: %s", bt_hex(buf->om_data, buf->om_len)); return 0; } -void bt_mesh_net_recv(struct net_buf_simple *data, s8_t rssi, +void bt_mesh_net_recv(struct os_mbuf *data, s8_t rssi, enum bt_mesh_net_if net_if) { - struct net_buf_simple *buf = NET_BUF_SIMPLE(29); + struct os_mbuf *buf = NET_BUF_SIMPLE(29); struct net_buf_simple_state state; struct bt_mesh_net_rx rx; BT_DBG("rssi %d net_if %u", rssi, net_if); if (!bt_mesh_is_provisioned()) { - return; + goto done; } if (bt_mesh_net_decode(data, net_if, &rx, buf, &state)) { - return; + goto done; } - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_GATT_PROXY) && + if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY)) && net_if == BT_MESH_NET_IF_PROXY) { bt_mesh_proxy_addr_add(data, rx.ctx.addr); } @@ -1177,19 +1171,22 @@ void bt_mesh_net_recv(struct net_buf_simple *data, s8_t rssi, bt_mesh_trans_recv(buf, &rx); if (BT_MESH_ADDR_IS_UNICAST(rx.dst)) { - return; + goto done; } } -#if (defined(CONFIG_BLUETOOTH_MESH_RELAY) || \ - defined(CONFIG_BLUETOOTH_MESH_FRIEND) || \ - defined(CONFIG_BLUETOOTH_MESH_GATT_PROXY)) +#if ((MYNEWT_VAL(BLE_MESH_RELAY)) || \ + (MYNEWT_VAL(BLE_MESH_FRIEND)) || \ + (MYNEWT_VAL(BLE_MESH_GATT_PROXY))) net_buf_simple_restore(buf, &state); bt_mesh_net_relay(buf, &rx); -#endif /* CONFIG_BLUETOOTH_MESH_RELAY || FRIEND || GATT_PROXY */ +#endif /* MYNEWT_VAL(BLE_MESH_RELAY) || FRIEND || GATT_PROXY */ + +done: + os_mbuf_free_chain(buf); } -static void ivu_complete(struct k_work *work) +static void ivu_complete(struct os_event *work) { BT_DBG(""); @@ -1201,7 +1198,7 @@ void bt_mesh_net_init(void) { k_delayed_work_init(&bt_mesh.ivu_complete, ivu_complete); -#if defined(CONFIG_BLUETOOTH_MESH_LOCAL_INTERFACE) +#if (MYNEWT_VAL(BLE_MESH_LOCAL_INTERFACE)) k_work_init(&bt_mesh.local_work, bt_mesh_net_local); #endif } diff --git a/nimble/host/mesh/src/net.h b/nimble/host/mesh/src/net.h index 68b9ce09a..b4e254b92 100644 --- a/nimble/host/mesh/src/net.h +++ b/nimble/host/mesh/src/net.h @@ -6,6 +6,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef __NET_H__ +#define __NET_H__ + #define BT_MESH_NET_FLAG_KR BIT(0) #define BT_MESH_NET_FLAG_IVU BIT(1) @@ -17,208 +20,220 @@ #define BT_MESH_IV_UPDATE(flags) ((flags >> 1) & 0x01) #define BT_MESH_KEY_REFRESH(flags) (flags & 0x01) -struct bt_mesh_app_key { - u16_t net_idx; - u16_t app_idx; - bool updated; - struct bt_mesh_app_keys { - u8_t id; - u8_t val[16]; - } keys[2]; +#include +#include "mesh/mesh.h" + +struct bt_mesh_app_key +{ + u16_t net_idx; + u16_t app_idx;bool updated; + struct bt_mesh_app_keys + { + u8_t id; + u8_t val[16]; + } keys[2]; }; /* Friendship Credentials */ -struct bt_mesh_friend_cred { - u16_t net_idx; - u16_t addr; +struct bt_mesh_friend_cred +{ + u16_t net_idx; + u16_t addr; - u16_t lpn_counter; - u16_t frnd_counter; + u16_t lpn_counter; + u16_t frnd_counter; - struct { - u8_t nid; /* NID */ - u8_t enc[16]; /* EncKey */ - u8_t privacy[16]; /* PrivacyKey */ - } cred[2]; + struct + { + u8_t nid; /* NID */ + u8_t enc[16]; /* EncKey */ + u8_t privacy[16]; /* PrivacyKey */ + } cred[2]; }; -struct bt_mesh_subnet { - s64_t beacon_sent; /* Time stamp of last sent beacon */ - u8_t beacons_last; /* Number of beacons during last - * observation window - */ - u8_t beacons_cur; /* Number of beaconds observed during - * currently ongoing window. - */ +struct bt_mesh_subnet +{ + s64_t beacon_sent; /* Time stamp of last sent beacon */ + u8_t beacons_last; /* Number of beacons during last + * observation window + */ + u8_t beacons_cur; /* Number of beaconds observed during + * currently ongoing window. + */ - u16_t net_idx; /* NetKeyIndex */ + u16_t net_idx; /* NetKeyIndex */ - bool kr_flag; /* Key Refresh Flag */ - u8_t kr_phase; /* Key Refresh Phase */ + bool kr_flag; /* Key Refresh Flag */ + u8_t kr_phase; /* Key Refresh Phase */ - u8_t node_id; /* Node Identity State */ + u8_t node_id; /* Node Identity State */ - u8_t auth[8]; /* Beacon Authentication Value */ + u8_t auth[8]; /* Beacon Authentication Value */ - struct bt_mesh_subnet_keys { - u8_t net[16]; /* NetKey */ - u8_t nid; /* NID */ - u8_t enc[16]; /* EncKey */ - u8_t net_id[8]; /* Network ID */ -#if defined(CONFIG_BLUETOOTH_MESH_GATT_PROXY) - u8_t identity[16]; /* IdentityKey */ + struct bt_mesh_subnet_keys + { + u8_t net[16]; /* NetKey */ + u8_t nid; /* NID */ + u8_t enc[16]; /* EncKey */ + u8_t net_id[8]; /* Network ID */ +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + u8_t identity[16]; /* IdentityKey */ #endif - u8_t privacy[16]; /* PrivacyKey */ - u8_t beacon[16]; /* BeaconKey */ - } keys[2]; + u8_t privacy[16]; /* PrivacyKey */ + u8_t beacon[16]; /* BeaconKey */ + } keys[2]; }; -struct bt_mesh_rpl { - u16_t src; - bool old_iv; - u32_t seq; +struct bt_mesh_rpl +{ + u16_t src;bool old_iv; + u32_t seq; }; -struct bt_mesh_friend { - u16_t lpn; - u8_t recv_delay; - u8_t fsn:1, - send_last:1, - send_offer:1, - send_update:1; - s32_t poll_to; - u16_t lpn_counter; - u16_t counter; - s8_t rssi; +struct bt_mesh_friend +{ + u16_t lpn; + u8_t recv_delay; + u8_t fsn :1, send_last :1, send_offer :1, send_update :1; + s32_t poll_to; + u16_t lpn_counter; + u16_t counter; + s8_t rssi; - struct k_delayed_work timer; + struct k_delayed_work timer; - struct net_buf *last; - struct k_fifo queue; + struct os_mbuf *last; + /* TU BYLO KFIFO*/ + struct os_eventq queue; }; -#if defined(CONFIG_BLUETOOTH_MESH_LOW_POWER) -#define LPN_GROUPS CONFIG_BLUETOOTH_MESH_LOW_POWER +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) +#define LPN_GROUPS MYNEWT_VAL(BLE_MESH_LOW_POWER) #else #define LPN_GROUPS 0 #endif /* Low Power Node state */ -struct bt_mesh_lpn { - enum __packed { - BT_MESH_LPN_DISABLED, /* LPN feature is disabled */ - BT_MESH_LPN_CLEAR, /* Clear in progress */ - BT_MESH_LPN_ENABLED, /* LPN enabled, but no Friend */ - BT_MESH_LPN_WAIT_OFFER, /* Friend Req sent */ - BT_MESH_LPN_ESTABLISHING, /* First Friend Poll sent */ - BT_MESH_LPN_ESTABLISHED, /* Friendship established */ - BT_MESH_LPN_RECV_DELAY, /* Poll sent, waiting ReceiveDelay */ - BT_MESH_LPN_WAIT_UPDATE, /* Waiting for Update or message */ - } state; +struct bt_mesh_lpn +{ + enum __packed + { + BT_MESH_LPN_DISABLED, /* LPN feature is disabled */ + BT_MESH_LPN_CLEAR, /* Clear in progress */ + BT_MESH_LPN_ENABLED, /* LPN enabled, but no Friend */ + BT_MESH_LPN_WAIT_OFFER, /* Friend Req sent */ + BT_MESH_LPN_ESTABLISHING, /* First Friend Poll sent */ + BT_MESH_LPN_ESTABLISHED, /* Friendship established */ + BT_MESH_LPN_RECV_DELAY, /* Poll sent, waiting ReceiveDelay */ + BT_MESH_LPN_WAIT_UPDATE, /* Waiting for Update or message */ + } state; - /* Transaction Number (used for subscription list) */ - u8_t xact_next; - u8_t xact_pending; - u8_t sent_req; + /* Transaction Number (used for subscription list) */ + u8_t xact_next; + u8_t xact_pending; + u8_t sent_req; - /* Address of our Friend when we're a LPN. Unassigned if we don't - * have a friend yet. - */ - u16_t frnd; + /* Address of our Friend when we're a LPN. Unassigned if we don't + * have a friend yet. + */ + u16_t frnd; - /* Value from the friend offer */ - u8_t recv_win; + /* Value from the friend offer */ + u8_t recv_win; - u8_t req_attempts; /* Number of Request attempts */ + u8_t req_attempts; /* Number of Request attempts */ - s32_t poll_timeout; + s32_t poll_timeout; - u8_t groups_changed:1, /* Friend Subscription List needs updating */ - pending_poll:1, /* Poll to be sent after subscription */ - disable:1, /* Disable LPN after clearing */ - fsn:1; /* Friend Sequence Number */ + u8_t groups_changed :1, /* Friend Subscription List needs updating */ + pending_poll :1, /* Poll to be sent after subscription */ + disable :1, /* Disable LPN after clearing */ + fsn :1; /* Friend Sequence Number */ - /* Friend Queue Size */ - u8_t queue_size; + /* Friend Queue Size */ + u8_t queue_size; - /* LPNCounter */ - u16_t counter; + /* LPNCounter */ + u16_t counter; - /* Next LPN related action timer */ - struct k_delayed_work timer; + /* Next LPN related action timer */ + struct k_delayed_work timer; - /* Subscribed groups */ - u16_t groups[LPN_GROUPS]; + /* Subscribed groups */ + u16_t groups[LPN_GROUPS]; - /* Bit fields for tracking which groups the Friend knows about */ - ATOMIC_DEFINE(added, LPN_GROUPS); - ATOMIC_DEFINE(pending, LPN_GROUPS); - ATOMIC_DEFINE(to_remove, LPN_GROUPS); + /* Bit fields for tracking which groups the Friend knows about */ + ATOMIC_DEFINE(added, LPN_GROUPS);ATOMIC_DEFINE(pending, LPN_GROUPS);ATOMIC_DEFINE(to_remove, LPN_GROUPS); }; -struct bt_mesh_net { - u32_t iv_index; /* Current IV Index */ - u32_t seq:24, /* Next outgoing sequence number */ - iv_update:1, /* 1 if IV Update in Progress */ - ivu_initiator:1, /* IV Update initiated by us */ - pending_update:1, /* Update blocked by SDU in progress */ - valid:1; /* 0 if unused */ +struct bt_mesh_net +{ + u32_t iv_index; /* Current IV Index */ + u32_t seq :24, /* Next outgoing sequence number */ + iv_update :1, /* 1 if IV Update in Progress */ + ivu_initiator :1, /* IV Update initiated by us */ + pending_update :1, /* Update blocked by SDU in progress */ + valid :1; /* 0 if unused */ - s64_t last_update; /* Time since last IV Update change */ + s64_t last_update; /* Time since last IV Update change */ -#if defined(CONFIG_BLUETOOTH_MESH_LOCAL_INTERFACE) - /* Local network interface */ - struct k_work local_work; - struct k_fifo local_queue; +#if MYNEWT_VAL(BLE_MESH_LOCAL_INTERFACE) + /* Local network interface */ + struct os_callout local_work; + struct os_eventq local_queue; + struct os_event local_ev; #endif -#if defined(CONFIG_BLUETOOTH_MESH_FRIEND) - struct bt_mesh_friend frnd; /* Friend state */ +#if MYNEWT_VAL(BLE_MESH_FRIEND) + struct bt_mesh_friend frnd; /* Friend state */ #endif -#if defined(CONFIG_BLUETOOTH_MESH_LOW_POWER) - struct bt_mesh_lpn lpn; /* Low Power Node state */ +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) + struct bt_mesh_lpn lpn; /* Low Power Node state */ #endif - /* Timer to transition IV Update in Progress state */ - struct k_delayed_work ivu_complete; + /* Timer to transition IV Update in Progress state */ + struct k_delayed_work ivu_complete; - u8_t dev_key[16]; + u8_t dev_key[16]; - struct bt_mesh_app_key app_keys[CONFIG_BLUETOOTH_MESH_APP_KEY_COUNT]; + struct bt_mesh_app_key app_keys[MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT)]; - struct bt_mesh_subnet sub[CONFIG_BLUETOOTH_MESH_SUBNET_COUNT]; + struct bt_mesh_subnet sub[MYNEWT_VAL(BLE_MESH_SUBNET_COUNT)]; - struct bt_mesh_rpl rpl[CONFIG_BLUETOOTH_MESH_CRPL]; + struct bt_mesh_rpl rpl[MYNEWT_VAL(BLE_MESH_CRPL)]; }; /* Network interface */ -enum bt_mesh_net_if { - BT_MESH_NET_IF_ADV, - BT_MESH_NET_IF_LOCAL, - BT_MESH_NET_IF_PROXY, - BT_MESH_NET_IF_PROXY_CFG, +enum bt_mesh_net_if +{ + BT_MESH_NET_IF_ADV, + BT_MESH_NET_IF_LOCAL, + BT_MESH_NET_IF_PROXY, + BT_MESH_NET_IF_PROXY_CFG, }; /* Decoding context for Network/Transport data */ -struct bt_mesh_net_rx { - struct bt_mesh_subnet *sub; - struct bt_mesh_msg_ctx ctx; - u64_t hash; /* Hash for the relay cache */ - u32_t seq; /* Sequence Number */ - u16_t dst; /* Destination address */ - u8_t old_iv:1, /* iv_index - 1 was used */ - new_key:1, /* Data was encrypted with updated key */ - ctl:1, /* Network Control */ - net_if:2; /* Network interface */ - s8_t rssi; +struct bt_mesh_net_rx +{ + struct bt_mesh_subnet *sub; + struct bt_mesh_msg_ctx ctx; + u64_t hash; /* Hash for the relay cache */ + u32_t seq; /* Sequence Number */ + u16_t dst; /* Destination address */ + u8_t old_iv :1, /* iv_index - 1 was used */ + new_key :1, /* Data was encrypted with updated key */ + ctl :1, /* Network Control */ + net_if :2; /* Network interface */ + s8_t rssi; }; /* Encoding context for Network/Transport data */ -struct bt_mesh_net_tx { - struct bt_mesh_subnet *sub; - struct bt_mesh_msg_ctx *ctx; - u16_t src; +struct bt_mesh_net_tx +{ + struct bt_mesh_subnet *sub; + struct bt_mesh_msg_ctx *ctx; + u16_t src; }; extern struct bt_mesh_net bt_mesh; @@ -226,53 +241,68 @@ extern struct bt_mesh_net bt_mesh; #define BT_MESH_NET_IVI_TX (bt_mesh.iv_index - bt_mesh.iv_update) #define BT_MESH_NET_IVI_RX(rx) (bt_mesh.iv_index - (rx)->old_iv) -int bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys, - const u8_t key[16]); +int +bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys, const u8_t key[16]); -int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16], - u32_t iv_index); +int +bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16], u32_t iv_index); -int bt_mesh_friend_cred_set(struct bt_mesh_friend_cred *cred, u8_t idx, - const u8_t net_key[16]); -void bt_mesh_friend_cred_refresh(u16_t net_idx); -int bt_mesh_friend_cred_update(u16_t net_idx, u8_t idx, - const u8_t net_key[16]); -struct bt_mesh_friend_cred *bt_mesh_friend_cred_add(u16_t net_idx, - const u8_t net_key[16], - u8_t idx, u16_t addr, - u16_t lpn_counter, - u16_t frnd_counter); -void bt_mesh_friend_cred_clear(struct bt_mesh_friend_cred *cred); -int bt_mesh_friend_cred_del(u16_t net_idx, u16_t addr); +int +bt_mesh_friend_cred_set(struct bt_mesh_friend_cred *cred, u8_t idx, + const u8_t net_key[16]); +void +bt_mesh_friend_cred_refresh(u16_t net_idx); +int +bt_mesh_friend_cred_update(u16_t net_idx, u8_t idx, const u8_t net_key[16]); +struct bt_mesh_friend_cred * +bt_mesh_friend_cred_add(u16_t net_idx, const u8_t net_key[16], u8_t idx, + u16_t addr, u16_t lpn_counter, u16_t frnd_counter); +void +bt_mesh_friend_cred_clear(struct bt_mesh_friend_cred *cred); +int +bt_mesh_friend_cred_del(u16_t net_idx, u16_t addr); -bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key); +bool +bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key); -int bt_mesh_net_beacon_update(struct bt_mesh_subnet *sub); +int +bt_mesh_net_beacon_update(struct bt_mesh_subnet *sub); -void bt_mesh_rpl_reset(void); +void +bt_mesh_rpl_reset(void); -void bt_mesh_iv_update(u32_t iv_index, bool iv_update); +void +bt_mesh_iv_update(u32_t iv_index, bool iv_update); -struct bt_mesh_subnet *bt_mesh_subnet_get(u16_t net_idx); +struct bt_mesh_subnet * +bt_mesh_subnet_get(u16_t net_idx); -struct bt_mesh_subnet *bt_mesh_subnet_find(const u8_t net_id[8], u8_t flags, - u32_t iv_index, const u8_t auth[8], - bool *new_key); +struct bt_mesh_subnet * +bt_mesh_subnet_find(const u8_t net_id[8], u8_t flags, u32_t iv_index, + const u8_t auth[8], bool *new_key); -int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf, - bool proxy); +int +bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct os_mbuf *buf, +bool proxy); -int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, - bt_mesh_adv_func_t cb); +int +bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct os_mbuf *buf, + bt_mesh_adv_func_t cb); -int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf, - bool new_key, bool friend_cred, bt_mesh_adv_func_t cb); +int +bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct os_mbuf *buf, +bool new_key, + bool friend_cred, bt_mesh_adv_func_t cb); -int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, - struct bt_mesh_net_rx *rx, struct net_buf_simple *buf, - struct net_buf_simple_state *state); +int +bt_mesh_net_decode(struct os_mbuf *data, enum bt_mesh_net_if net_if, + struct bt_mesh_net_rx *rx, struct os_mbuf *buf, + struct net_buf_simple_state *state); -void bt_mesh_net_recv(struct net_buf_simple *data, s8_t rssi, - enum bt_mesh_net_if net_if); +void +bt_mesh_net_recv(struct os_mbuf *data, s8_t rssi, enum bt_mesh_net_if net_if); -void bt_mesh_net_init(void); +void +bt_mesh_net_init(void); + +#endif diff --git a/nimble/host/mesh/src/prov.c b/nimble/host/mesh/src/prov.c index 9b39ae99b..f1bf8574f 100644 --- a/nimble/host/mesh/src/prov.c +++ b/nimble/host/mesh/src/prov.c @@ -5,27 +5,22 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include "syscfg/syscfg.h" +#if MYNEWT_VAL(BLE_MESH_PROV) == 1 -#include #include -#include -#include -#include +#include "mesh/atomic.h" -#include -#include -#include -#include -#include +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_PROV)) +#include "host/ble_hs_log.h" -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_MESH_DEBUG_PROV) -#include "common/log.h" +#include "mesh/mesh.h" +#include "mesh_priv.h" -#include "../ecc.h" +#include #include "crypto.h" #include "adv.h" -#include "mesh.h" #include "net.h" #include "access.h" #include "foundation.h" @@ -96,7 +91,7 @@ #define CLOSE_REASON_TIMEOUT 0x01 #define CLOSE_REASON_FAILED 0x02 -#define XACT_SEG_DATA(_seg) (&link.rx.buf->data[20 + ((_seg - 1) * 23)]) +#define XACT_SEG_DATA(_seg) (&link.rx.buf->om_data[20 + ((_seg - 1) * 23)]) #define XACT_SEG_RECV(_seg) (link.rx.seg &= ~(1 << (_seg))) #define XACT_NVAL 0xff @@ -115,8 +110,8 @@ enum { struct prov_link { ATOMIC_DEFINE(flags, NUM_FLAGS); -#if defined(CONFIG_BLUETOOTH_MESH_PB_GATT) - struct bt_conn *conn; /* GATT connection */ +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + uint16_t conn_handle; /* GATT connection */ #endif u8_t dhkey[32]; /* Calculated DHKey */ u8_t expect; /* Next expected PDU */ @@ -134,7 +129,6 @@ struct prov_link { u8_t conf_inputs[145]; /* ConfirmationInputs */ u8_t prov_salt[16]; /* Provisioning Salt */ -#if defined(CONFIG_BLUETOOTH_MESH_PB_ADV) u32_t id; /* Link ID */ struct { @@ -143,15 +137,16 @@ struct prov_link { u8_t seg; /* Bit-field of unreceived segments */ u8_t last_seg; /* Last segment (to check length) */ u8_t fcs; /* Expected FCS value */ - struct net_buf_simple *buf; + struct os_mbuf *buf; } rx; +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) struct { /* Start timestamp of the transaction */ s64_t start; /* Pending outgoing buffer(s) */ - struct net_buf *buf[3]; + struct os_mbuf *buf[3]; /* Retransmit timer */ struct k_delayed_work retransmit; @@ -169,11 +164,11 @@ struct prov_rx { #define BUF_TIMEOUT K_MSEC(400) #define TRANSACTION_TIMEOUT K_SECONDS(30) -#if defined(CONFIG_BLUETOOTH_MESH_PB_GATT) +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) #define PROV_BUF_HEADROOM 5 #else #define PROV_BUF_HEADROOM 0 -static struct net_buf_simple *rx_buf = NET_BUF_SIMPLE(65); +static struct os_mbuf *rx_buf; #endif #define PROV_BUF(len) NET_BUF_SIMPLE(PROV_BUF_HEADROOM + len) @@ -184,9 +179,11 @@ static const struct bt_mesh_prov *prov; static void close_link(u8_t err, u8_t reason); -#if defined(CONFIG_BLUETOOTH_MESH_PB_ADV) -static void buf_sent(struct net_buf *buf, int err) +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) +static void buf_sent(struct os_mbuf *buf, int err) { + BT_DBG("buf_sent"); + if (!link.tx.buf[0]) { return; } @@ -199,7 +196,7 @@ static void free_segments(void) int i; for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) { - struct net_buf *buf = link.tx.buf[i]; + struct os_mbuf *buf = link.tx.buf[i]; if (!buf) { break; @@ -223,6 +220,8 @@ static void prov_clear_tx(void) static void reset_link(void) { + atomic_clear_bit(link.flags, LINK_ACTIVE); + prov_clear_tx(); /* Clear everything except the retransmit delayed work config */ @@ -234,7 +233,7 @@ static void reset_link(void) atomic_set_bit(link.flags, LOCAL_PUB_KEY); } -#if defined(CONFIG_BLUETOOTH_MESH_PB_GATT) +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) link.rx.buf = bt_mesh_proxy_get_buf(); #else net_buf_simple_init(rx_buf, 0); @@ -247,9 +246,9 @@ static void reset_link(void) } } -static struct net_buf *adv_buf_create(void) +static struct os_mbuf *adv_buf_create(void) { - struct net_buf *buf; + struct os_mbuf *buf; buf = bt_mesh_adv_create(BT_MESH_ADV_PROV, PROV_XMIT_COUNT, PROV_XMIT_INT, BUF_TIMEOUT); @@ -263,7 +262,7 @@ static struct net_buf *adv_buf_create(void) static u8_t pending_ack = XACT_NVAL; -static void ack_complete(struct net_buf *buf, int err) +static void ack_complete(struct os_mbuf *buf, int err) { BT_DBG("xact %u complete", (u8_t)pending_ack); pending_ack = XACT_NVAL; @@ -272,7 +271,7 @@ static void ack_complete(struct net_buf *buf, int err) static void gen_prov_ack_send(u8_t xact_id) { bt_mesh_adv_func_t complete; - struct net_buf *buf; + struct os_mbuf *buf; BT_DBG("xact_id %u", xact_id); @@ -308,7 +307,7 @@ static void send_reliable(void) link.tx.start = k_uptime_get(); for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) { - struct net_buf *buf = link.tx.buf[i]; + struct os_mbuf *buf = link.tx.buf[i]; if (!buf) { break; @@ -324,7 +323,7 @@ static void send_reliable(void) static int bearer_ctl_send(u8_t op, void *data, u8_t data_len) { - struct net_buf *buf; + struct os_mbuf *buf; BT_DBG("op 0x%02x data_len %u", op, data_len); @@ -358,13 +357,13 @@ static u8_t last_seg(u8_t len) return 1 + (len / CONT_PAYLOAD_MAX); } -static int prov_send_adv(struct net_buf_simple *msg) +static int prov_send_adv(struct os_mbuf *msg) { static u8_t id = 0x80; - struct net_buf *start, *buf; + struct os_mbuf *start, *buf; u8_t seg_len, seg_id; - BT_DBG("len %u: %s", msg->len, bt_hex(msg->data, msg->len)); + BT_DBG("prov_send_adv len %u: %s", msg->om_len, bt_hex(msg->om_data, msg->om_len)); prov_clear_tx(); @@ -376,19 +375,19 @@ static int prov_send_adv(struct net_buf_simple *msg) net_buf_add_be32(start, link.id); net_buf_add_u8(start, id); - net_buf_add_u8(start, GPC_START(last_seg(msg->len))); - net_buf_add_be16(start, msg->len); - net_buf_add_u8(start, bt_mesh_fcs_calc(msg->data, msg->len)); + net_buf_add_u8(start, GPC_START(last_seg(msg->om_len))); + net_buf_add_be16(start, msg->om_len); + net_buf_add_u8(start, bt_mesh_fcs_calc(msg->om_data, msg->om_len)); link.tx.buf[0] = start; - seg_len = min(msg->len, START_PAYLOAD_MAX); - BT_DBG("seg 0 len %u: %s", seg_len, bt_hex(msg->data, seg_len)); - net_buf_add_mem(start, msg->data, seg_len); + seg_len = min(msg->om_len, START_PAYLOAD_MAX); + BT_DBG("seg 0 len %u: %s", seg_len, bt_hex(msg->om_data, seg_len)); + net_buf_add_mem(start, msg->om_data, seg_len); net_buf_simple_pull(msg, seg_len); buf = start; - for (seg_id = 1; msg->len > 0; seg_id++) { + for (seg_id = 1; msg->om_len > 0; seg_id++) { if (seg_id >= ARRAY_SIZE(link.tx.buf)) { BT_ERR("Too big message"); free_segments(); @@ -403,15 +402,15 @@ static int prov_send_adv(struct net_buf_simple *msg) link.tx.buf[seg_id] = buf; - seg_len = min(msg->len, CONT_PAYLOAD_MAX); + seg_len = min(msg->om_len, CONT_PAYLOAD_MAX); BT_DBG("seg_id %u len %u: %s", seg_id, seg_len, - bt_hex(msg->data, seg_len)); + bt_hex(msg->om_data, seg_len)); net_buf_add_be32(buf, link.id); net_buf_add_u8(buf, id); net_buf_add_u8(buf, GPC_CONT(seg_id)); - net_buf_add_mem(buf, msg->data, seg_len); + net_buf_add_mem(buf, msg->om_data, seg_len); net_buf_simple_pull(msg, seg_len); } @@ -422,34 +421,35 @@ static int prov_send_adv(struct net_buf_simple *msg) return 0; } -#endif /* CONFIG_BLUETOOTH_MESH_PB_ADV */ +#endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */ -#if defined(CONFIG_BLUETOOTH_MESH_PB_GATT) -static int prov_send_gatt(struct net_buf_simple *msg) +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) +static int prov_send_gatt(struct os_mbuf *msg) { - if (!link.conn) { + if (!link.conn_handle) { + BT_ERR("No connection handle!?"); return -ENOTCONN; } - return bt_mesh_proxy_send(link.conn, BT_MESH_PROXY_PROV, msg); + return bt_mesh_proxy_send(link.conn_handle, BT_MESH_PROXY_PROV, msg); } -#endif /* CONFIG_BLUETOOTH_MESH_PB_GATT */ +#endif /* MYNEWT_VAL(BLE_MESH_PB_GATT) */ -static inline int prov_send(struct net_buf_simple *buf) +static inline int prov_send(struct os_mbuf *buf) { -#if defined(CONFIG_BLUETOOTH_MESH_PB_GATT) - if (link.conn) { +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + if (link.conn_handle) { return prov_send_gatt(buf); } #endif -#if defined(CONFIG_BLUETOOTH_MESH_PB_ADV) +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) return prov_send_adv(buf); #else return 0; #endif } -static void prov_buf_init(struct net_buf_simple *buf, u8_t type) +static void prov_buf_init(struct os_mbuf *buf, u8_t type) { net_buf_simple_init(buf, PROV_BUF_HEADROOM); net_buf_simple_add_u8(buf, type); @@ -457,9 +457,9 @@ static void prov_buf_init(struct net_buf_simple *buf, u8_t type) static void prov_invite(const u8_t *data) { - struct net_buf_simple *buf = PROV_BUF(12); + struct os_mbuf *buf = PROV_BUF(12); - BT_DBG("Attention Duration: %u seconds", data[0]); + BT_INFO("Attention Duration: %u seconds", data[0]); if (data[0]) { bt_mesh_attention(NULL, data[0]); @@ -476,6 +476,7 @@ static void prov_invite(const u8_t *data) net_buf_simple_add_be16(buf, BIT(PROV_ALG_P256)); /* Public Key Type */ + /*PTS OOB*/ net_buf_simple_add_u8(buf, 0x00); /* Static OOB Type */ @@ -493,37 +494,40 @@ static void prov_invite(const u8_t *data) /* Input OOB Action */ net_buf_simple_add_be16(buf, prov->input_actions); - memcpy(&link.conf_inputs[1], &buf->data[1], 11); + memcpy(&link.conf_inputs[1], &buf->om_data[1], 11); if (prov_send(buf)) { BT_ERR("Failed to send capabilities"); close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED); - return; + goto done; } link.expect = PROV_START; + +done: + os_mbuf_free_chain(buf); } static void prov_capabilities(const u8_t *data) { u16_t algorithms, output_action, input_action; - BT_DBG("Elements: %u", data[0]); + BT_INFO("Elements: %u", data[0]); algorithms = sys_get_be16(&data[1]); - BT_DBG("Algorithms: %u", algorithms); + BT_INFO("Algorithms: %u", algorithms); - BT_DBG("Public Key Type: 0x%02x", data[3]); - BT_DBG("Static OOB Type: 0x%02x", data[4]); - BT_DBG("Output OOB Size: %u", data[5]); + BT_INFO("Public Key Type: 0x%02x", data[3]); + BT_INFO("Static OOB Type: 0x%02x", data[4]); + BT_INFO("Output OOB Size: %u", data[5]); output_action = sys_get_be16(&data[6]); - BT_DBG("Output OOB Action: 0x%04x", output_action); + BT_INFO("Output OOB Action: 0x%04x", output_action); - BT_DBG("Input OOB Size: %u", data[8]); + BT_INFO("Input OOB Size: %u", data[8]); input_action = sys_get_be16(&data[9]); - BT_DBG("Input OOB Action: 0x%04x", input_action); + BT_INFO("Input OOB Action: 0x%04x", input_action); } static bt_mesh_output_action output_action(u8_t action) @@ -613,7 +617,7 @@ static int prov_auth(u8_t method, u8_t action, u8_t size) memcpy(link.auth, str, size); - return prov->output_string(str); + return prov->output_string((char *)str); } else { u32_t div[8] = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; @@ -656,11 +660,11 @@ static int prov_auth(u8_t method, u8_t action, u8_t size) static void prov_start(const u8_t *data) { - BT_DBG("Algorithm: 0x%02x", data[0]); - BT_DBG("Public Key: 0x%02x", data[1]); - BT_DBG("Auth Method: 0x%02x", data[2]); - BT_DBG("Auth Action: 0x%02x", data[3]); - BT_DBG("Auth Size: 0x%02x", data[4]); + BT_INFO("Algorithm: 0x%02x", data[0]); + BT_INFO("Public Key: 0x%02x", data[1]); + BT_INFO("Auth Method: 0x%02x", data[2]); + BT_INFO("Auth Action: 0x%02x", data[3]); + BT_INFO("Auth Size: 0x%02x", data[4]); if (data[0] != PROV_ALG_P256) { BT_ERR("Unknown algorithm 0x%02x", data[0]); @@ -678,7 +682,7 @@ static void prov_start(const u8_t *data) static void send_confirm(void) { - struct net_buf_simple *cfm = PROV_BUF(17); + struct os_mbuf *cfm = PROV_BUF(17); BT_DBG("ConfInputs[0] %s", bt_hex(link.conf_inputs, 64)); BT_DBG("ConfInputs[64] %s", bt_hex(&link.conf_inputs[64], 64)); @@ -687,7 +691,7 @@ static void send_confirm(void) if (bt_mesh_prov_conf_salt(link.conf_inputs, link.conf_salt)) { BT_ERR("Unable to generate confirmation salt"); close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED); - return; + goto done; } BT_DBG("ConfirmationSalt: %s", bt_hex(link.conf_salt, 16)); @@ -695,7 +699,7 @@ static void send_confirm(void) if (bt_mesh_prov_conf_key(link.dhkey, link.conf_salt, link.conf_key)) { BT_ERR("Unable to generate confirmation key"); close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED); - return; + goto done; } BT_DBG("ConfirmationKey: %s", bt_hex(link.conf_key, 16)); @@ -703,7 +707,7 @@ static void send_confirm(void) if (bt_rand(link.rand, 16)) { BT_ERR("Unable to generate random number"); close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED); - return; + goto done; } BT_DBG("LocalRandom: %s", bt_hex(link.rand, 16)); @@ -714,16 +718,19 @@ static void send_confirm(void) net_buf_simple_add(cfm, 16))) { BT_ERR("Unable to generate confirmation value"); close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED); - return; + goto done; } if (prov_send(cfm)) { BT_ERR("Failed to send Provisioning Confirm"); close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED); - return; + goto done; } link.expect = PROV_RANDOM; + +done: + os_mbuf_free_chain(cfm); } int bt_mesh_input_number(u32_t num) @@ -755,7 +762,7 @@ int bt_mesh_input_string(const char *str) return 0; } - strncpy(link.auth, str, prov->output_size); + strncpy((char *)link.auth, str, prov->input_size); if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) { send_confirm(); @@ -792,25 +799,25 @@ static void prov_dh_key_cb(const u8_t key[32]) static void send_pub_key(void) { - struct net_buf_simple *buf = PROV_BUF(65); + struct os_mbuf *buf = PROV_BUF(65); const u8_t *key; key = bt_pub_key_get(); if (!key) { BT_ERR("No public key available"); close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED); - return; + goto done; } - BT_DBG("Local Public Key: %s", bt_hex(key, 64)); - prov_buf_init(buf, PROV_PUB_KEY); /* Swap X and Y halves independently to big-endian */ sys_memcpy_swap(net_buf_simple_add(buf, 32), key, 32); sys_memcpy_swap(net_buf_simple_add(buf, 32), &key[32], 32); - memcpy(&link.conf_inputs[81], &buf->data[1], 64); + memcpy(&link.conf_inputs[81], &buf->om_data[1], 64); + + BT_DBG("Local Public Key: %s", bt_hex(&buf->om_data[1], 64)); prov_send(buf); @@ -818,27 +825,30 @@ static void send_pub_key(void) * X and Y halves are swapped independently. */ net_buf_simple_init(buf, 0); - sys_memcpy_swap(buf->data, &link.conf_inputs[17], 32); - sys_memcpy_swap(&buf->data[32], &link.conf_inputs[49], 32); + sys_memcpy_swap(buf->om_data, &link.conf_inputs[17], 32); + sys_memcpy_swap(&buf->om_data[32], &link.conf_inputs[49], 32); - if (bt_dh_key_gen(buf->data, prov_dh_key_cb)) { + if (bt_dh_key_gen(buf->om_data, prov_dh_key_cb)) { BT_ERR("Failed to generate DHKey"); close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED); - return; + goto done; } link.expect = PROV_CONFIRM; + +done: + os_mbuf_free_chain(buf); } static void prov_pub_key(const u8_t *data) { - BT_DBG("Remote Public Key: %s", bt_hex(data, 64)); + BT_INFO("Remote Public Key: %s", bt_hex(data, 64)); memcpy(&link.conf_inputs[17], data, 64); if (!atomic_test_bit(link.flags, LOCAL_PUB_KEY)) { /* Clear retransmit timer */ -#if defined(CONFIG_BLUETOOTH_MESH_PB_ADV) +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) prov_clear_tx(); #endif atomic_set_bit(link.flags, REMOTE_PUB_KEY); @@ -872,12 +882,12 @@ static void prov_input_complete(const u8_t *data) static void prov_confirm(const u8_t *data) { - BT_DBG("Remote Confirm: %s", bt_hex(data, 16)); + BT_INFO("Remote Confirm: %s", bt_hex(data, 16)); memcpy(link.conf, data, 16); if (!atomic_test_bit(link.flags, HAVE_DHKEY)) { -#if defined(CONFIG_BLUETOOTH_MESH_PB_ADV) +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) prov_clear_tx(); #endif atomic_set_bit(link.flags, SEND_CONFIRM); @@ -888,15 +898,15 @@ static void prov_confirm(const u8_t *data) static void prov_random(const u8_t *data) { - struct net_buf_simple *rnd = PROV_BUF(16); + struct os_mbuf *rnd = PROV_BUF(16); u8_t conf_verify[16]; - BT_DBG("Remote Random: %s", bt_hex(data, 16)); + BT_INFO("Remote Random: %s", bt_hex(data, 16)); if (bt_mesh_prov_conf(link.conf_key, data, link.auth, conf_verify)) { BT_ERR("Unable to calculate confirmation verification"); close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED); - return; + goto done; } if (memcmp(conf_verify, link.conf, 16)) { @@ -904,7 +914,7 @@ static void prov_random(const u8_t *data) BT_DBG("Received: %s", bt_hex(link.conf, 16)); BT_DBG("Calculated: %s", bt_hex(conf_verify, 16)); close_link(PROV_ERR_CFM_FAILED, CLOSE_REASON_FAILED); - return; + goto done; } prov_buf_init(rnd, PROV_RANDOM); @@ -913,24 +923,27 @@ static void prov_random(const u8_t *data) if (prov_send(rnd)) { BT_ERR("Failed to send Provisioning Random"); close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED); - return; + goto done; } if (bt_mesh_prov_salt(link.conf_salt, data, link.rand, link.prov_salt)) { BT_ERR("Failed to generate provisioning salt"); close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED); - return; + goto done; } BT_DBG("ProvisioningSalt: %s", bt_hex(link.prov_salt, 16)); link.expect = PROV_DATA; + +done: + os_mbuf_free_chain(rnd); } static void prov_data(const u8_t *data) { - struct net_buf_simple *msg = PROV_BUF(1); + struct os_mbuf *msg = PROV_BUF(1); u8_t session_key[16]; u8_t nonce[13]; u8_t dev_key[16]; @@ -947,7 +960,7 @@ static void prov_data(const u8_t *data) if (err) { BT_ERR("Unable to generate session key"); close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED); - return; + goto done; } BT_DBG("SessionKey: %s", bt_hex(session_key, 16)); @@ -956,7 +969,7 @@ static void prov_data(const u8_t *data) if (err) { BT_ERR("Unable to generate session nonce"); close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED); - return; + goto done; } BT_DBG("Nonce: %s", bt_hex(nonce, 13)); @@ -965,14 +978,14 @@ static void prov_data(const u8_t *data) if (err) { BT_ERR("Unable to decrypt provisioning data"); close_link(PROV_ERR_DECRYPT, CLOSE_REASON_FAILED); - return; + goto done; } err = bt_mesh_dev_key(link.dhkey, link.prov_salt, dev_key); if (err) { BT_ERR("Unable to generate device key"); close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED); - return; + goto done; } BT_DBG("DevKey: %s", bt_hex(dev_key, 16)); @@ -996,16 +1009,19 @@ static void prov_data(const u8_t *data) if (prov->complete) { prov->complete(); } + +done: + os_mbuf_free_chain(msg); } static void prov_complete(const u8_t *data) { - BT_DBG(""); + BT_INFO(""); } static void prov_failed(const u8_t *data) { - BT_DBG("Error: 0x%02x", data[0]); + BT_WARN("Error: 0x%02x", data[0]); } static const struct { @@ -1026,20 +1042,21 @@ static const struct { static void close_link(u8_t err, u8_t reason) { -#if defined(CONFIG_BLUETOOTH_MESH_PB_GATT) - if (link.conn) { - bt_mesh_pb_gatt_close(link.conn); +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + if (link.conn_handle) { + bt_mesh_pb_gatt_close(link.conn_handle); return; } #endif -#if defined(CONFIG_BLUETOOTH_MESH_PB_ADV) +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) if (err) { - struct net_buf_simple *buf = PROV_BUF(2); + struct os_mbuf *buf = PROV_BUF(2); prov_buf_init(buf, PROV_FAILED); net_buf_simple_add_u8(buf, err); prov_send(buf); + os_mbuf_free_chain(buf); } link.rx.seg = 0; @@ -1054,12 +1071,12 @@ static void close_link(u8_t err, u8_t reason) } } -#if defined(CONFIG_BLUETOOTH_MESH_PB_ADV) -static void prov_retransmit(struct k_work *work) +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) +static void prov_retransmit(struct os_event *work) { int i; - BT_DBG(""); + BT_DBG("prov_retransmit"); if (!atomic_test_bit(link.flags, LINK_ACTIVE)) { BT_WARN("Link not active"); @@ -1073,7 +1090,7 @@ static void prov_retransmit(struct k_work *work) } for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) { - struct net_buf *buf = link.tx.buf[i]; + struct os_mbuf *buf = link.tx.buf[i]; if (!buf) { break; @@ -1083,7 +1100,7 @@ static void prov_retransmit(struct k_work *work) continue; } - BT_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); if (i + 1 < ARRAY_SIZE(link.tx.buf) && link.tx.buf[i + 1]) { bt_mesh_adv_send(buf, NULL); @@ -1094,12 +1111,12 @@ static void prov_retransmit(struct k_work *work) } } -static void link_open(struct prov_rx *rx, struct net_buf_simple *buf) +static void link_open(struct prov_rx *rx, struct os_mbuf *buf) { - BT_DBG("len %u", buf->len); + BT_INFO("link open: len %u", buf->om_len); - if (buf->len < 16) { - BT_ERR("Too short bearer open message (len %u)", buf->len); + if (buf->om_len < 16) { + BT_ERR("Too short bearer open message (len %u)", buf->om_len); return; } @@ -1108,7 +1125,7 @@ static void link_open(struct prov_rx *rx, struct net_buf_simple *buf) return; } - if (memcmp(buf->data, prov->uuid, 16)) { + if (memcmp(buf->om_data, prov->uuid, 16)) { BT_DBG("Bearer open message not for us"); return; } @@ -1122,21 +1139,21 @@ static void link_open(struct prov_rx *rx, struct net_buf_simple *buf) link.expect = PROV_INVITE; } -static void link_ack(struct prov_rx *rx, struct net_buf_simple *buf) +static void link_ack(struct prov_rx *rx, struct os_mbuf *buf) { - BT_DBG("len %u", buf->len); + BT_INFO("Link ack: len %u", buf->om_len); } -static void link_close(struct prov_rx *rx, struct net_buf_simple *buf) +static void link_close(struct prov_rx *rx, struct os_mbuf *buf) { - BT_DBG("len %u", buf->len); + BT_INFO("Link close: len %u", buf->om_len); reset_link(); } -static void gen_prov_ctl(struct prov_rx *rx, struct net_buf_simple *buf) +static void gen_prov_ctl(struct prov_rx *rx, struct os_mbuf *buf) { - BT_DBG("op 0x%02x len %u", BEARER_CTL(rx->gpc), buf->len); + BT_DBG("op 0x%02x len %u", BEARER_CTL(rx->gpc), buf->om_len); switch (BEARER_CTL(rx->gpc)) { case LINK_OPEN: @@ -1164,12 +1181,13 @@ static void gen_prov_ctl(struct prov_rx *rx, struct net_buf_simple *buf) static void prov_msg_recv(void) { - u8_t type = link.rx.buf->data[0]; + u8_t type = link.rx.buf->om_data[0]; - BT_DBG("type 0x%02x len %u", type, link.rx.buf->len); + BT_DBG("type 0x%02x len %u", type, link.rx.buf->om_len); - if (type != link.expect) { + if (type != PROV_FAILED && type != link.expect) { BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect); + close_link(PROV_ERR_UNEXP_PDU, CLOSE_REASON_FAILED); return; } @@ -1188,21 +1206,21 @@ static void prov_msg_recv(void) return; } - if (1 + prov_handlers[type].len != link.rx.buf->len) { + if (1 + prov_handlers[type].len != link.rx.buf->om_len) { BT_ERR("Invalid length %u for type 0x%02x", - link.rx.buf->len, type); + link.rx.buf->om_len, type); close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED); return; } - prov_handlers[type].func(&link.rx.buf->data[1]); + prov_handlers[type].func(&link.rx.buf->om_data[1]); } -static void gen_prov_cont(struct prov_rx *rx, struct net_buf_simple *buf) +static void gen_prov_cont(struct prov_rx *rx, struct os_mbuf *buf) { u8_t seg = CONT_SEG_INDEX(rx->gpc); - BT_DBG("len %u, seg_index %u", buf->len, seg); + BT_DBG("len %u, seg_index %u", buf->om_len, seg); if (!link.rx.seg && link.rx.prev_id == rx->xact_id) { BT_WARN("Resending ack"); @@ -1223,11 +1241,11 @@ static void gen_prov_cont(struct prov_rx *rx, struct net_buf_simple *buf) } else if (seg == link.rx.last_seg) { u8_t expect_len; - expect_len = (link.rx.buf->len - 20 - + expect_len = (link.rx.buf->om_len - 20 - (23 * (link.rx.last_seg - 1))); - if (expect_len != buf->len) { + if (expect_len != buf->om_len) { BT_ERR("Incorrect last seg len: %u != %u", - expect_len, buf->len); + expect_len, buf->om_len); close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED); return; } @@ -1238,7 +1256,7 @@ static void gen_prov_cont(struct prov_rx *rx, struct net_buf_simple *buf) return; } - memcpy(XACT_SEG_DATA(seg), buf->data, buf->len); + memcpy(XACT_SEG_DATA(seg), buf->om_data, buf->om_len); XACT_SEG_RECV(seg); if (!link.rx.seg) { @@ -1246,12 +1264,12 @@ static void gen_prov_cont(struct prov_rx *rx, struct net_buf_simple *buf) } } -static void gen_prov_ack(struct prov_rx *rx, struct net_buf_simple *buf) +static void gen_prov_ack(struct prov_rx *rx, struct os_mbuf *buf) { - BT_DBG("len %u", buf->len); + BT_DBG("len %u", buf->om_len); } -static void gen_prov_start(struct prov_rx *rx, struct net_buf_simple *buf) +static void gen_prov_start(struct prov_rx *rx, struct os_mbuf *buf) { if (link.rx.seg) { BT_WARN("Got Start while there are unreceived segments"); @@ -1264,27 +1282,27 @@ static void gen_prov_start(struct prov_rx *rx, struct net_buf_simple *buf) return; } - link.rx.buf->len = net_buf_simple_pull_be16(buf); + link.rx.buf->om_len = net_buf_simple_pull_be16(buf); link.rx.id = rx->xact_id; link.rx.fcs = net_buf_simple_pull_u8(buf); - BT_DBG("len %u last_seg %u total_len %u fcs 0x%02x", buf->len, - START_LAST_SEG(rx->gpc), link.rx.buf->len, link.rx.fcs); + BT_DBG("len %u last_seg %u total_len %u fcs 0x%02x", buf->om_len, + START_LAST_SEG(rx->gpc), link.rx.buf->om_len, link.rx.fcs); - if (link.rx.buf->len < 1) { + if (link.rx.buf->om_len < 1) { BT_ERR("Ignoring zero-length provisioning PDU"); close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED); return; } - if (link.rx.buf->len > link.rx.buf->size) { + if (link.rx.buf->om_len > OS_MBUF_TRAILINGSPACE(link.rx.buf)) { BT_ERR("Too large provisioning PDU (%u bytes)", - link.rx.buf->len); + link.rx.buf->om_len); close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED); return; } - if (START_LAST_SEG(rx->gpc) > 0 && link.rx.buf->len <= 20) { + if (START_LAST_SEG(rx->gpc) > 0 && link.rx.buf->om_len <= 20) { BT_ERR("Too small total length for multi-segment PDU"); close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED); return; @@ -1292,7 +1310,7 @@ static void gen_prov_start(struct prov_rx *rx, struct net_buf_simple *buf) link.rx.seg = (1 << (START_LAST_SEG(rx->gpc) + 1)) - 1; link.rx.last_seg = START_LAST_SEG(rx->gpc); - memcpy(link.rx.buf->data, buf->data, buf->len); + memcpy(link.rx.buf->om_data, buf->om_data, buf->om_len); XACT_SEG_RECV(0); if (!link.rx.seg) { @@ -1301,7 +1319,7 @@ static void gen_prov_start(struct prov_rx *rx, struct net_buf_simple *buf) } static const struct { - void (*const func)(struct prov_rx *rx, struct net_buf_simple *buf); + void (*const func)(struct prov_rx *rx, struct os_mbuf *buf); const u8_t require_link; const u8_t min_len; } gen_prov[] = { @@ -1311,9 +1329,9 @@ static const struct { { gen_prov_ctl, false, 0 }, }; -static void gen_prov_recv(struct prov_rx *rx, struct net_buf_simple *buf) +static void gen_prov_recv(struct prov_rx *rx, struct os_mbuf *buf) { - if (buf->len < gen_prov[GPCF(rx->gpc)].min_len) { + if (buf->om_len < gen_prov[GPCF(rx->gpc)].min_len) { BT_ERR("Too short GPC message type %u", GPCF(rx->gpc)); return; } @@ -1324,10 +1342,11 @@ static void gen_prov_recv(struct prov_rx *rx, struct net_buf_simple *buf) return; } + BT_INFO("prov_action: %d", GPCF(rx->gpc)); gen_prov[GPCF(rx->gpc)].func(rx, buf); } -void bt_mesh_pb_adv_recv(struct net_buf_simple *buf) +void bt_mesh_pb_adv_recv(struct os_mbuf *buf) { struct prov_rx rx; @@ -1336,8 +1355,8 @@ void bt_mesh_pb_adv_recv(struct net_buf_simple *buf) return; } - if (buf->len < 6) { - BT_WARN("Too short provisioning packet (len %u)", buf->len); + if (buf->om_len < 6) { + BT_WARN("Too short provisioning packet (len %u)", buf->om_len); return; } @@ -1354,27 +1373,27 @@ void bt_mesh_pb_adv_recv(struct net_buf_simple *buf) gen_prov_recv(&rx, buf); } -#endif /* CONFIG_BLUETOOTH_MESH_PB_ADV */ +#endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */ -#if defined(CONFIG_BLUETOOTH_MESH_PB_GATT) -int bt_mesh_pb_gatt_recv(struct bt_conn *conn, struct net_buf_simple *buf) +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) +int bt_mesh_pb_gatt_recv(uint16_t conn_handle, struct os_mbuf *buf) { u8_t type; - BT_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (link.conn != conn) { + if (link.conn_handle != conn_handle) { BT_WARN("Data for unexpected connection"); return -ENOTCONN; } - if (buf->len < 1) { - BT_WARN("Too short provisioning packet (len %u)", buf->len); + if (buf->om_len < 1) { + BT_WARN("Too short provisioning packet (len %u)", buf->om_len); return -EINVAL; } type = net_buf_simple_pull_u8(buf); - if (type != link.expect) { + if (type != PROV_FAILED && type != link.expect) { BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect); return -EINVAL; } @@ -1384,37 +1403,38 @@ int bt_mesh_pb_gatt_recv(struct bt_conn *conn, struct net_buf_simple *buf) return -EINVAL; } - if (prov_handlers[type].len != buf->len) { - BT_ERR("Invalid length %u for type 0x%02x", buf->len, type); + if (prov_handlers[type].len != buf->om_len) { + BT_ERR("Invalid length %u for type 0x%02x", buf->om_len, type); return -EINVAL; } - prov_handlers[type].func(buf->data); + prov_handlers[type].func(buf->om_data); return 0; } -int bt_mesh_pb_gatt_open(struct bt_conn *conn) +int bt_mesh_pb_gatt_open(uint16_t conn_handle) { - BT_DBG("conn %p", conn); + BT_DBG("conn_handle %d", conn_handle); if (atomic_test_and_set_bit(link.flags, LINK_ACTIVE)) { + BT_ERR("Link already opened?"); return -EBUSY; } - link.conn = bt_conn_ref(conn); + link.conn_handle = conn_handle; link.expect = PROV_INVITE; return 0; } -int bt_mesh_pb_gatt_close(struct bt_conn *conn) +int bt_mesh_pb_gatt_close(uint16_t conn_handle) { bool pub_key; - BT_DBG("conn %p", conn); + BT_DBG("conn_handle %d", conn_handle); - if (link.conn != conn) { + if (link.conn_handle != conn_handle) { BT_ERR("Not connected"); return -ENOTCONN; } @@ -1424,8 +1444,6 @@ int bt_mesh_pb_gatt_close(struct bt_conn *conn) bt_mesh_attention(NULL, 0); } - bt_conn_unref(link.conn); - pub_key = atomic_test_bit(link.flags, LOCAL_PUB_KEY); memset(&link, 0, sizeof(link)); @@ -1435,7 +1453,7 @@ int bt_mesh_pb_gatt_close(struct bt_conn *conn) return 0; } -#endif /* CONFIG_BLUETOOTH_MESH_PB_GATT */ +#endif /* MYNEWT_VAL(BLE_MESH_PB_GATT) */ const u8_t *bt_mesh_prov_get_uuid(void) { @@ -1452,6 +1470,10 @@ void bt_mesh_prov_init(const struct bt_mesh_prov *prov_info) static struct bt_pub_key_cb pub_key_cb = { .func = pub_key_ready, }; +#if !(MYNEWT_VAL(BLE_MESH_PB_GATT)) + rx_buf = NET_BUF_SIMPLE(65); + +#endif if (bt_pub_key_gen(&pub_key_cb)) { BT_ERR("Failed to generate public key"); @@ -1459,22 +1481,26 @@ void bt_mesh_prov_init(const struct bt_mesh_prov *prov_info) prov = prov_info; -#if defined(CONFIG_BLUETOOTH_MESH_PB_ADV) +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) k_delayed_work_init(&link.tx.retransmit, prov_retransmit); link.rx.prev_id = XACT_NVAL; -#if defined(CONFIG_BLUETOOTH_MESH_PB_GATT) +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) link.rx.buf = bt_mesh_proxy_get_buf(); #else net_buf_simple_init(rx_buf, 0); link.rx.buf = rx_buf; #endif -#endif /* CONFIG_BLUETOOTH_MESH_PB_ADV */ - - if (IS_ENABLED(CONFIG_BLUETOOTH_DEBUG)) { - struct bt_uuid_128 uuid = { .uuid.type = BT_UUID_TYPE_128 }; - memcpy(uuid.val, prov->uuid, 16); - BT_INFO("Device UUID: %s", bt_uuid_str(&uuid.uuid)); - } +#endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */ } + +void bt_mesh_prov_reset_link(void) { +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + link.rx.buf = bt_mesh_proxy_get_buf(); +#else + net_buf_simple_init(rx_buf, 0); + link.rx.buf = rx_buf; +#endif +} +#endif //MYNEWT_VAL(BLE_MESH_PROV) == 1 diff --git a/nimble/host/mesh/src/prov.h b/nimble/host/mesh/src/prov.h index 99cf603bf..46ceaebd2 100644 --- a/nimble/host/mesh/src/prov.h +++ b/nimble/host/mesh/src/prov.h @@ -6,14 +6,33 @@ * SPDX-License-Identifier: Apache-2.0 */ -void bt_mesh_pb_adv_recv(struct net_buf_simple *buf); +#ifndef __PROV_H__ +#define __PROV_H__ -bool bt_prov_active(void); +#include "os/os_mbuf.h" +#include "mesh/mesh.h" +#include "../src/ble_hs_conn_priv.h" -int bt_mesh_pb_gatt_open(struct bt_conn *conn); -int bt_mesh_pb_gatt_close(struct bt_conn *conn); -int bt_mesh_pb_gatt_recv(struct bt_conn *conn, struct net_buf_simple *buf); +void +bt_mesh_pb_adv_recv(struct os_mbuf *buf); -const u8_t *bt_mesh_prov_get_uuid(void); +bool +bt_prov_active(void); -void bt_mesh_prov_init(const struct bt_mesh_prov *prov); +int +bt_mesh_pb_gatt_open(uint16_t conn_handle); +int +bt_mesh_pb_gatt_close(uint16_t conn_handle); +int +bt_mesh_pb_gatt_recv(uint16_t conn_handle, struct os_mbuf *buf); + +const u8_t * +bt_mesh_prov_get_uuid(void); + +void +bt_mesh_prov_init(const struct bt_mesh_prov *prov); + +void +bt_mesh_prov_reset_link(void); + +#endif diff --git a/nimble/host/mesh/src/proxy.c b/nimble/host/mesh/src/proxy.c index 1c0d10bf1..c9f0d80f2 100644 --- a/nimble/host/mesh/src/proxy.c +++ b/nimble/host/mesh/src/proxy.c @@ -6,19 +6,19 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include +#include "syscfg/syscfg.h" -#include -#include -#include -#include -#include +#if MYNEWT_VAL(BLE_MESH_PROXY) == 1 -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_MESH_DEBUG_PROXY) -#include "common/log.h" +#include "mesh/mesh.h" -#include "mesh.h" +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_PROXY)) +#include "host/ble_hs_log.h" +#include "host/ble_att.h" +#include "services/gatt/ble_svc_gatt.h" +#include "../../host/src/ble_hs_priv.h" + +#include "mesh_priv.h" #include "adv.h" #include "net.h" #include "prov.h" @@ -40,33 +40,69 @@ #define CFG_FILTER_REMOVE 0x02 #define CFG_FILTER_STATUS 0x03 +/** @def BT_UUID_MESH_PROV + * @brief Mesh Provisioning Service + */ +ble_uuid16_t BT_UUID_MESH_PROV = BLE_UUID16_INIT(0x1827); +#define BT_UUID_MESH_PROV_VAL 0x1827 +/** @def BT_UUID_MESH_PROXY + * @brief Mesh Proxy Service + */ +ble_uuid16_t BT_UUID_MESH_PROXY = BLE_UUID16_INIT(0x1828); +#define BT_UUID_MESH_PROXY_VAL 0x1828 +/** @def BT_UUID_GATT_CCC + * @brief GATT Client Characteristic Configuration + */ +ble_uuid16_t BT_UUID_GATT_CCC = BLE_UUID16_INIT(0x2902); +#define BT_UUID_GATT_CCC_VAL 0x2902 +/** @def BT_UUID_MESH_PROV_DATA_IN + * @brief Mesh Provisioning Data In + */ +ble_uuid16_t BT_UUID_MESH_PROV_DATA_IN = BLE_UUID16_INIT(0x2adb); +#define BT_UUID_MESH_PROV_DATA_IN_VAL 0x2adb +/** @def BT_UUID_MESH_PROV_DATA_OUT + * @brief Mesh Provisioning Data Out + */ +ble_uuid16_t BT_UUID_MESH_PROV_DATA_OUT = BLE_UUID16_INIT(0x2adc); +#define BT_UUID_MESH_PROV_DATA_OUT_VAL 0x2adc +/** @def BT_UUID_MESH_PROXY_DATA_IN + * @brief Mesh Proxy Data In + */ +ble_uuid16_t BT_UUID_MESH_PROXY_DATA_IN = BLE_UUID16_INIT(0x2add); +#define BT_UUID_MESH_PROXY_DATA_IN_VAL 0x2add +/** @def BT_UUID_MESH_PROXY_DATA_OUT + * @brief Mesh Proxy Data Out + */ +ble_uuid16_t BT_UUID_MESH_PROXY_DATA_OUT = BLE_UUID16_INIT(0x2ade); +#define BT_UUID_MESH_PROXY_DATA_OUT_VAL 0x2ade + #define PDU_HDR(sar, type) (sar << 6 | (type & BIT_MASK(6))) #define CLIENT_BUF_SIZE 68 -static const struct bt_le_adv_param slow_adv_param = { - .options = (BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME), - .interval_min = BT_GAP_ADV_SLOW_INT_MIN, - .interval_max = BT_GAP_ADV_SLOW_INT_MAX, +static const struct ble_gap_adv_params slow_adv_param = { + .conn_mode = (BLE_GAP_CONN_MODE_UND ), + .itvl_min = BT_GAP_ADV_SLOW_INT_MIN, + .itvl_max = BT_GAP_ADV_SLOW_INT_MAX, }; -static const struct bt_le_adv_param fast_adv_param = { - .options = (BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME), - .interval_min = BT_GAP_ADV_FAST_INT_MIN_2, - .interval_max = BT_GAP_ADV_FAST_INT_MAX_2, +static const struct ble_gap_adv_params fast_adv_param = { + .conn_mode = (BLE_GAP_CONN_MODE_UND), + .itvl_min = BT_GAP_ADV_FAST_INT_MIN_2, + .itvl_max = BT_GAP_ADV_FAST_INT_MAX_2, }; -static const struct bt_le_adv_param *proxy_adv_param = &fast_adv_param; +static const struct ble_gap_adv_params *proxy_adv_param = &fast_adv_param; static bool proxy_adv_enabled; -#if defined(CONFIG_BLUETOOTH_MESH_GATT_PROXY) -static void proxy_send_beacons(struct k_work *work); +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) +static void proxy_send_beacons(struct os_event *work); #endif static struct bt_mesh_proxy_client { - struct bt_conn *conn; - u16_t filter[CONFIG_BLUETOOTH_MESH_PROXY_FILTER_SIZE]; + uint16_t conn_handle; + u16_t filter[MYNEWT_VAL(BLE_MESH_PROXY_FILTER_SIZE)]; enum __packed { NONE, WHITELIST, @@ -74,18 +110,12 @@ static struct bt_mesh_proxy_client { PROV, } filter_type; u8_t msg_type; -#if defined(CONFIG_BLUETOOTH_MESH_GATT_PROXY) - struct k_work send_beacons; +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + struct os_callout send_beacons; #endif - struct net_buf_simple buf; - u8_t buf_data[CLIENT_BUF_SIZE]; -} clients[CONFIG_BLUETOOTH_MAX_CONN] = { - [0 ... (CONFIG_BLUETOOTH_MAX_CONN - 1)] = { -#if defined(CONFIG_BLUETOOTH_MESH_GATT_PROXY) - .send_beacons = _K_WORK_INITIALIZER(proxy_send_beacons), -#endif - .buf.size = CLIENT_BUF_SIZE, - }, + struct os_mbuf *buf; +} clients[MYNEWT_VAL(BLE_MAX_CONNECTIONS)] = { + [0 ... (MYNEWT_VAL(BLE_MAX_CONNECTIONS) - 1)] = { 0 }, }; /* Track which service is enabled */ @@ -95,12 +125,58 @@ static enum { MESH_GATT_PROXY, } gatt_svc = MESH_GATT_NONE; -static struct bt_mesh_proxy_client *find_client(struct bt_conn *conn) +static struct { + uint16_t proxy_h; + uint16_t proxy_data_out_h; + uint16_t prov_h; + uint16_t prov_data_in_h; + uint16_t prov_data_out_h; +} svc_handles; + +static void resolve_svc_handles(void) +{ + int rc; + + /* Either all handles are already resolved, or none of them */ + if (svc_handles.prov_data_out_h) { + return; + } + + /* + * We assert if attribute is not found since at this stage all attributes + * shall be already registered and thus shall be found. + */ + + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), + &svc_handles.proxy_h); + assert(rc == 0); + + rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), + BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL), + NULL, &svc_handles.proxy_data_out_h); + assert(rc == 0); + + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + &svc_handles.prov_h); + assert(rc == 0); + + rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL), + NULL, &svc_handles.prov_data_in_h); + assert(rc == 0); + + rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL), + NULL, &svc_handles.prov_data_out_h); + assert(rc == 0); +} + +static struct bt_mesh_proxy_client *find_client(uint16_t conn_handle) { int i; for (i = 0; i < ARRAY_SIZE(clients); i++) { - if (clients[i].conn == conn) { + if (clients[i].conn_handle == conn_handle) { return &clients[i]; } } @@ -108,16 +184,16 @@ static struct bt_mesh_proxy_client *find_client(struct bt_conn *conn) return NULL; } -#if defined(CONFIG_BLUETOOTH_MESH_GATT_PROXY) -static int proxy_segment_and_send(struct bt_conn *conn, u8_t type, - struct net_buf_simple *msg); +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) +static int proxy_segment_and_send(uint16_t conn_handle, u8_t type, + struct os_mbuf *msg); static int filter_set(struct bt_mesh_proxy_client *client, - struct net_buf_simple *buf) + struct os_mbuf *buf) { u8_t type; - if (buf->len < 1) { + if (buf->om_len < 1) { BT_WARN("Too short Filter Set message"); return -EINVAL; } @@ -186,7 +262,7 @@ static void filter_remove(struct bt_mesh_proxy_client *client, u16_t addr) static void send_filter_status(struct bt_mesh_proxy_client *client, struct bt_mesh_net_rx *rx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct bt_mesh_net_tx tx = { .sub = rx->sub, @@ -217,7 +293,7 @@ static void send_filter_status(struct bt_mesh_proxy_client *client, net_buf_simple_add_be16(buf, filter_size); - BT_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); err = bt_mesh_net_encode(&tx, buf, true); if (err) { @@ -225,7 +301,7 @@ static void send_filter_status(struct bt_mesh_proxy_client *client, return; } - err = proxy_segment_and_send(client->conn, BT_MESH_PROXY_CONFIG, buf); + err = proxy_segment_and_send(client->conn_handle, BT_MESH_PROXY_CONFIG, buf); if (err) { BT_ERR("Failed to send proxy cfg message (err %d)", err); } @@ -233,23 +309,23 @@ static void send_filter_status(struct bt_mesh_proxy_client *client, static void proxy_cfg(struct bt_mesh_proxy_client *client) { - struct net_buf_simple *buf = NET_BUF_SIMPLE(29); + struct os_mbuf *buf = NET_BUF_SIMPLE(29); struct bt_mesh_net_rx rx; u8_t opcode; int err; - err = bt_mesh_net_decode(&client->buf, BT_MESH_NET_IF_PROXY_CFG, + err = bt_mesh_net_decode(client->buf, BT_MESH_NET_IF_PROXY_CFG, &rx, buf, NULL); if (err) { BT_ERR("Failed to decode Proxy Configuration (err %d)", err); - return; + goto done; } - BT_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (buf->len < 1) { + if (buf->om_len < 1) { BT_WARN("Too short proxy configuration PDU"); - return; + goto done; } opcode = net_buf_simple_pull_u8(buf); @@ -259,7 +335,7 @@ static void proxy_cfg(struct bt_mesh_proxy_client *client) send_filter_status(client, &rx, buf); break; case CFG_FILTER_ADD: - while (buf->len >= 2) { + while (buf->om_len >= 2) { u16_t addr; addr = net_buf_simple_pull_be16(buf); @@ -268,7 +344,7 @@ static void proxy_cfg(struct bt_mesh_proxy_client *client) send_filter_status(client, &rx, buf); break; case CFG_FILTER_REMOVE: - while (buf->len >= 2) { + while (buf->om_len >= 2) { u16_t addr; addr = net_buf_simple_pull_be16(buf); @@ -280,30 +356,36 @@ static void proxy_cfg(struct bt_mesh_proxy_client *client) BT_WARN("Unhandled configuration OpCode 0x%02x", opcode); break; } + +done: + os_mbuf_free_chain(buf); } -static int beacon_send(struct bt_conn *conn, struct bt_mesh_subnet *sub) +static int beacon_send(uint16_t conn_handle, struct bt_mesh_subnet *sub) { - struct net_buf_simple *buf = NET_BUF_SIMPLE(23); + struct os_mbuf *buf = NET_BUF_SIMPLE(23); + int rc; net_buf_simple_init(buf, 1); bt_mesh_beacon_create(sub, buf); - return proxy_segment_and_send(conn, BT_MESH_PROXY_BEACON, buf); + rc = proxy_segment_and_send(conn_handle, BT_MESH_PROXY_BEACON, buf); + os_mbuf_free_chain(buf); + return rc; } -static void proxy_send_beacons(struct k_work *work) +static void proxy_send_beacons(struct os_event *work) { struct bt_mesh_proxy_client *client; int i; - client = CONTAINER_OF(work, struct bt_mesh_proxy_client, send_beacons); + client = work->ev_arg; for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; if (sub->net_idx != BT_MESH_KEY_UNUSED) { - beacon_send(client->conn, sub); + beacon_send(client->conn_handle, sub); } } } @@ -313,8 +395,8 @@ void bt_mesh_proxy_beacon_send(struct bt_mesh_subnet *sub) int i; for (i = 0; i < ARRAY_SIZE(clients); i++) { - if (clients[i].conn) { - beacon_send(clients[i].conn, sub); + if (clients[i].conn_handle) { + beacon_send(clients[i].conn_handle, sub); } } } @@ -353,24 +435,24 @@ int bt_mesh_proxy_identity_enable(void) static void proxy_complete_pdu(struct bt_mesh_proxy_client *client) { switch (client->msg_type) { -#if defined(CONFIG_BLUETOOTH_MESH_GATT_PROXY) +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) case BT_MESH_PROXY_NET_PDU: - BT_DBG("Mesh Network PDU"); - bt_mesh_net_recv(&client->buf, 0, BT_MESH_NET_IF_PROXY); + BT_INFO("Mesh Network PDU"); + bt_mesh_net_recv(client->buf, 0, BT_MESH_NET_IF_PROXY); break; case BT_MESH_PROXY_BEACON: - BT_DBG("Mesh Beacon PDU"); - bt_mesh_beacon_recv(&client->buf); + BT_INFO("Mesh Beacon PDU"); + bt_mesh_beacon_recv(client->buf); break; case BT_MESH_PROXY_CONFIG: - BT_DBG("Mesh Configuration PDU"); + BT_INFO("Mesh Configuration PDU"); proxy_cfg(client); break; #endif -#if defined(CONFIG_BLUETOOTH_MESH_PB_GATT) +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) case BT_MESH_PROXY_PROV: - BT_DBG("Mesh Provisioning PDU"); - bt_mesh_pb_gatt_recv(client->conn, &client->buf); + BT_INFO("Mesh Provisioning PDU"); + bt_mesh_pb_gatt_recv(client->conn_handle, client->buf); break; #endif default: @@ -378,17 +460,17 @@ static void proxy_complete_pdu(struct bt_mesh_proxy_client *client) break; } - net_buf_simple_init(&client->buf, 0); + net_buf_simple_init(client->buf, 0); } -#define ATTR_IS_PROV(attr) (attr->user_data != NULL) - -static ssize_t proxy_recv(struct bt_conn *conn, - const struct bt_gatt_attr *attr, const void *buf, - u16_t len, u16_t offset, u8_t flags) +static int proxy_recv(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) { - struct bt_mesh_proxy_client *client = find_client(conn); - const u8_t *data = buf; + struct bt_mesh_proxy_client *client; + const u8_t *data = ctxt->om->om_data; + u16_t len = ctxt->om->om_len; + + client = find_client(conn_handle); if (!client) { return -ENOTCONN; @@ -399,40 +481,41 @@ static ssize_t proxy_recv(struct bt_conn *conn, return -EINVAL; } - if (ATTR_IS_PROV(attr) != (PDU_TYPE(data) == BT_MESH_PROXY_PROV)) { + if ((attr_handle == svc_handles.prov_data_in_h) != + (PDU_TYPE(data) == BT_MESH_PROXY_PROV)) { BT_WARN("Proxy PDU type doesn't match GATT service"); return -EINVAL; } - if (len - 1 > net_buf_simple_tailroom(&client->buf)) { + if (len - 1 > net_buf_simple_tailroom(client->buf)) { BT_WARN("Too big proxy PDU"); return -EINVAL; } switch (PDU_SAR(data)) { case SAR_COMPLETE: - if (client->buf.len) { + if (client->buf->om_len) { BT_WARN("Complete PDU while a pending incomplete one"); return -EINVAL; } client->msg_type = PDU_TYPE(data); - net_buf_simple_add_mem(&client->buf, data + 1, len - 1); + net_buf_simple_add_mem(client->buf, data + 1, len - 1); proxy_complete_pdu(client); break; case SAR_FIRST: - if (client->buf.len) { + if (client->buf->om_len) { BT_WARN("First PDU while a pending incomplete one"); return -EINVAL; } client->msg_type = PDU_TYPE(data); - net_buf_simple_add_mem(&client->buf, data + 1, len - 1); + net_buf_simple_add_mem(client->buf, data + 1, len - 1); break; case SAR_CONT: - if (!client->buf.len) { + if (!client->buf->om_len) { BT_WARN("Continuation with no prior data"); return -EINVAL; } @@ -442,11 +525,11 @@ static ssize_t proxy_recv(struct bt_conn *conn, return -EINVAL; } - net_buf_simple_add_mem(&client->buf, data + 1, len - 1); + net_buf_simple_add_mem(client->buf, data + 1, len - 1); break; case SAR_LAST: - if (!client->buf.len) { + if (!client->buf->om_len) { BT_WARN("Last SAR PDU with no prior data"); return -EINVAL; } @@ -456,7 +539,7 @@ static ssize_t proxy_recv(struct bt_conn *conn, return -EINVAL; } - net_buf_simple_add_mem(&client->buf, data + 1, len - 1); + net_buf_simple_add_mem(client->buf, data + 1, len - 1); proxy_complete_pdu(client); break; } @@ -464,23 +547,23 @@ static ssize_t proxy_recv(struct bt_conn *conn, return len; } -static void proxy_connected(struct bt_conn *conn, u8_t err) +static void proxy_connected(uint16_t conn_handle) { struct bt_mesh_proxy_client *client; int i; - BT_DBG("conn %p err 0x%02x", conn, err); + BT_INFO("conn_handle %d", conn_handle); /* Since we use ADV_OPT_ONE_TIME */ proxy_adv_enabled = false; -#if CONFIG_BLUETOOTH_MAX_CONN > 1 +#if MYNEWT_VAL(BLE_MAX_CONNECTIONS) > 1 /* Try to re-enable advertising in case it's possible */ bt_mesh_adv_update(); #endif for (client = NULL, i = 0; i < ARRAY_SIZE(clients); i++) { - if (!clients[i].conn) { + if (!clients[i].conn_handle) { client = &clients[i]; break; } @@ -491,29 +574,28 @@ static void proxy_connected(struct bt_conn *conn, u8_t err) return; } - client->conn = bt_conn_ref(conn); + client->conn_handle = conn_handle; client->filter_type = NONE; memset(client->filter, 0, sizeof(client->filter)); - net_buf_simple_init(&client->buf, 0); + net_buf_simple_init(client->buf, 0); } -static void proxy_disconnected(struct bt_conn *conn, u8_t reason) +static void proxy_disconnected(uint16_t conn_handle, int reason) { int i; - BT_DBG("conn %p reason 0x%02x", conn, reason); + BT_INFO("conn_handle %d reason %d", conn_handle, reason); for (i = 0; i < ARRAY_SIZE(clients); i++) { struct bt_mesh_proxy_client *client = &clients[i]; - if (client->conn == conn) { - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_PB_GATT) && + if (client->conn_handle == conn_handle) { + if ((MYNEWT_VAL(BLE_MESH_PB_GATT)) && client->filter_type == PROV) { - bt_mesh_pb_gatt_close(conn); + bt_mesh_pb_gatt_close(conn_handle); } - bt_conn_unref(client->conn); - client->conn = NULL; + client->conn_handle = 0; break; } } @@ -521,80 +603,51 @@ static void proxy_disconnected(struct bt_conn *conn, u8_t reason) bt_mesh_adv_update(); } -struct net_buf_simple *bt_mesh_proxy_get_buf(void) +struct os_mbuf *bt_mesh_proxy_get_buf(void) { - struct net_buf_simple *buf = &clients[0].buf; + struct os_mbuf *buf = clients[0].buf; net_buf_simple_init(buf, 0); return buf; } -#if defined(CONFIG_BLUETOOTH_MESH_PB_GATT) -static ssize_t prov_ccc_write(struct bt_conn *conn, - const struct bt_gatt_attr *attr, - const void *buf, u16_t len, - u16_t offset, u8_t flags) +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) +static void prov_ccc_write(uint16_t conn_handle) { - struct bt_mesh_proxy_client *client; - u16_t value; + struct bt_mesh_proxy_client *client; - BT_DBG("len %u: %s", len, bt_hex(buf, len)); - - if (len != sizeof(value)) { - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); - } - - value = sys_get_le16(buf); - if (value != BT_GATT_CCC_NOTIFY) { - BT_WARN("Client wrote 0x%04x instead enabling notify", value); - return len; - } + BT_DBG("conn_handle %d", conn_handle); /* If a connection exists there must be a client */ - client = find_client(conn); + client = find_client(conn_handle); __ASSERT(client, "No client for connection"); if (client->filter_type == NONE) { client->filter_type = PROV; - bt_mesh_pb_gatt_open(conn); + bt_mesh_pb_gatt_open(conn_handle); } - - return len; } -/* Mesh Provisioning Service Declaration */ -static struct bt_gatt_attr prov_attrs[] = { - BT_GATT_PRIMARY_SERVICE(BT_UUID_MESH_PROV), - - BT_GATT_CHARACTERISTIC(BT_UUID_MESH_PROV_DATA_IN, - BT_GATT_CHRC_WRITE_WITHOUT_RESP), - BT_GATT_DESCRIPTOR(BT_UUID_MESH_PROV_DATA_IN, BT_GATT_PERM_WRITE, - NULL, proxy_recv, (void *)1), - - BT_GATT_CHARACTERISTIC(BT_UUID_MESH_PROV_DATA_OUT, - BT_GATT_CHRC_NOTIFY), - BT_GATT_DESCRIPTOR(BT_UUID_MESH_PROV_DATA_OUT, BT_GATT_PERM_NONE, - NULL, NULL, NULL), - /* Add custom CCC as clients need to be tracked individually */ - BT_GATT_DESCRIPTOR(BT_UUID_GATT_CCC, BT_GATT_PERM_WRITE, NULL, - prov_ccc_write, NULL), -}; - -static struct bt_gatt_service prov_svc = BT_GATT_SERVICE(prov_attrs); - int bt_mesh_proxy_prov_enable(void) { + uint16_t handle; + int rc; int i; BT_DBG(""); - bt_gatt_service_register(&prov_svc); - gatt_svc = MESH_GATT_PROV; + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle); + assert(rc == 0); + ble_gatts_svc_set_visibility(handle, 1); + /* FIXME: figure out end handle */ + ble_svc_gatt_changed(svc_handles.prov_h, 0xffff); + + gatt_svc = MESH_GATT_PROV; proxy_adv_param = &fast_adv_param; for (i = 0; i < ARRAY_SIZE(clients); i++) { - if (clients[i].conn) { + if (clients[i].conn_handle) { clients[i].filter_type = PROV; } } @@ -605,93 +658,68 @@ int bt_mesh_proxy_prov_enable(void) int bt_mesh_proxy_prov_disable(void) { + uint16_t handle; + int rc; int i; BT_DBG(""); - bt_gatt_service_unregister(&prov_svc); - gatt_svc = MESH_GATT_NONE; + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle); + assert(rc == 0); + ble_gatts_svc_set_visibility(handle, 0); + /* FIXME: figure out end handle */ + ble_svc_gatt_changed(svc_handles.prov_h, 0xffff); + + gatt_svc = MESH_GATT_NONE; for (i = 0; i < ARRAY_SIZE(clients); i++) { struct bt_mesh_proxy_client *client = &clients[i]; - if (clients->conn && client->filter_type == PROV) { - bt_mesh_pb_gatt_close(client->conn); + if (clients->conn_handle && client->filter_type == PROV) { + bt_mesh_pb_gatt_close(client->conn_handle); client->filter_type = NONE; } } return 0; } +#endif /* MYNEWT_VAL(BLE_MESH_PB_GATT) */ -#endif /* CONFIG_BLUETOOTH_MESH_PB_GATT */ - - - -#if defined(CONFIG_BLUETOOTH_MESH_GATT_PROXY) -static ssize_t proxy_ccc_write(struct bt_conn *conn, - const struct bt_gatt_attr *attr, - const void *buf, u16_t len, - u16_t offset, u8_t flags) +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) +static void proxy_ccc_write(uint16_t conn_handle) { struct bt_mesh_proxy_client *client; - u16_t value; - BT_DBG("len %u: %s", len, bt_hex(buf, len)); + BT_DBG("conn_handle %d", conn_handle); - if (len != sizeof(value)) { - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); - } - - value = sys_get_le16(buf); - if (value != BT_GATT_CCC_NOTIFY) { - BT_WARN("Client wrote 0x%04x instead enabling notify", value); - return len; - } - - /* If a connection exists there must be a client */ - client = find_client(conn); + client = find_client(conn_handle); __ASSERT(client, "No client for connection"); if (client->filter_type == NONE) { client->filter_type = WHITELIST; + k_work_add_arg(&client->send_beacons, client); k_work_submit(&client->send_beacons); } - - return len; } -/* Mesh Proxy Service Declaration */ -static struct bt_gatt_attr proxy_attrs[] = { - BT_GATT_PRIMARY_SERVICE(BT_UUID_MESH_PROXY), - - BT_GATT_CHARACTERISTIC(BT_UUID_MESH_PROXY_DATA_IN, - BT_GATT_CHRC_WRITE_WITHOUT_RESP), - BT_GATT_DESCRIPTOR(BT_UUID_MESH_PROXY_DATA_IN, BT_GATT_PERM_WRITE, - NULL, proxy_recv, NULL), - - BT_GATT_CHARACTERISTIC(BT_UUID_MESH_PROXY_DATA_OUT, - BT_GATT_CHRC_NOTIFY), - BT_GATT_DESCRIPTOR(BT_UUID_MESH_PROXY_DATA_OUT, BT_GATT_PERM_NONE, - NULL, NULL, NULL), - /* Add custom CCC as clients need to be tracked individually */ - BT_GATT_DESCRIPTOR(BT_UUID_GATT_CCC, BT_GATT_PERM_WRITE, NULL, - proxy_ccc_write, NULL), -}; - -static struct bt_gatt_service proxy_svc = BT_GATT_SERVICE(proxy_attrs); - int bt_mesh_proxy_gatt_enable(void) { + uint16_t handle; + int rc; int i; BT_DBG(""); - bt_gatt_service_register(&proxy_svc); + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), &handle); + assert(rc == 0); + ble_gatts_svc_set_visibility(handle, 1); + /* FIXME: figure out end handle */ + ble_svc_gatt_changed(svc_handles.proxy_h, 0xffff); + gatt_svc = MESH_GATT_PROXY; for (i = 0; i < ARRAY_SIZE(clients); i++) { - if (clients[i].conn) { + if (clients[i].conn_handle) { clients[i].filter_type = WHITELIST; } } @@ -701,17 +729,24 @@ int bt_mesh_proxy_gatt_enable(void) int bt_mesh_proxy_gatt_disable(void) { + uint16_t handle; + int rc; int i; BT_DBG(""); - bt_gatt_service_unregister(&proxy_svc); + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), &handle); + assert(rc == 0); + ble_gatts_svc_set_visibility(handle, 0); + /* FIXME: figure out end handle */ + ble_svc_gatt_changed(svc_handles.proxy_h, 0xffff); + gatt_svc = MESH_GATT_NONE; for (i = 0; i < ARRAY_SIZE(clients); i++) { struct bt_mesh_proxy_client *client = &clients[i]; - if (clients->conn && (client->filter_type == WHITELIST || + if (clients->conn_handle && (client->filter_type == WHITELIST || client->filter_type == BLACKLIST)) { client->filter_type = NONE; } @@ -720,10 +755,19 @@ int bt_mesh_proxy_gatt_disable(void) return 0; } -void bt_mesh_proxy_addr_add(struct net_buf_simple *buf, u16_t addr) +void bt_mesh_proxy_addr_add(struct os_mbuf *buf, u16_t addr) { - struct bt_mesh_proxy_client *client = - CONTAINER_OF(buf, struct bt_mesh_proxy_client, buf); + struct bt_mesh_proxy_client *client = NULL; + int i; + + for (i = 0; i < ARRAY_SIZE(clients); i++) { + client = &clients[i]; + if (client->buf == buf) { + break; + } + } + + assert(client); BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr); @@ -764,18 +808,18 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client, return false; } -bool bt_mesh_proxy_relay(struct net_buf_simple *buf, u16_t dst) +bool bt_mesh_proxy_relay(struct os_mbuf *buf, u16_t dst) { bool relayed = false; int i; - BT_DBG("%u bytes to dst 0x%04x", buf->len, dst); + BT_DBG("%u bytes to dst 0x%04x", buf->om_len, dst); for (i = 0; i < ARRAY_SIZE(clients); i++) { struct bt_mesh_proxy_client *client = &clients[i]; - struct net_buf_simple *msg = NET_BUF_SIMPLE(32); + struct os_mbuf *msg; - if (!client->conn) { + if (!client->conn_handle) { continue; } @@ -786,75 +830,83 @@ bool bt_mesh_proxy_relay(struct net_buf_simple *buf, u16_t dst) /* Proxy PDU sending modifies the original buffer, * so we need to make a copy. */ + msg = NET_BUF_SIMPLE(32); net_buf_simple_init(msg, 1); - net_buf_simple_add_mem(msg, buf->data, buf->len); + net_buf_simple_add_mem(msg, buf->om_data, buf->om_len); - bt_mesh_proxy_send(client->conn, BT_MESH_PROXY_NET_PDU, msg); + bt_mesh_proxy_send(client->conn_handle, BT_MESH_PROXY_NET_PDU, msg); + os_mbuf_free_chain(msg); relayed = true; } return relayed; } -#endif /* CONFIG_BLUETOOTH_MESH_GATT_PROXY */ +#endif /* MYNEWT_VAL(BLE_MESH_GATT_PROXY) */ -static int proxy_send(struct bt_conn *conn, const void *data, u16_t len) +static int proxy_send(uint16_t conn_handle, const void *data, u16_t len) { + struct os_mbuf *om; + BT_DBG("%u bytes: %s", len, bt_hex(data, len)); -#if defined(CONFIG_BLUETOOTH_MESH_GATT_PROXY) +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) if (gatt_svc == MESH_GATT_PROXY) { - return bt_gatt_notify(conn, &proxy_attrs[4], data, len); + om = ble_hs_mbuf_from_flat(data, len); + assert(om); + ble_gattc_notify_custom(conn_handle, svc_handles.proxy_data_out_h, om); } #endif -#if defined(CONFIG_BLUETOOTH_MESH_PB_GATT) +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) if (gatt_svc == MESH_GATT_PROV) { - return bt_gatt_notify(conn, &prov_attrs[4], data, len); + om = ble_hs_mbuf_from_flat(data, len); + assert(om); + ble_gattc_notify_custom(conn_handle, svc_handles.prov_data_out_h, om); } #endif return 0; } -static int proxy_segment_and_send(struct bt_conn *conn, u8_t type, - struct net_buf_simple *msg) +static int proxy_segment_and_send(uint16_t conn_handle, u8_t type, + struct os_mbuf *msg) { u16_t mtu; - BT_DBG("conn %p type 0x%02x len %u: %s", conn, type, msg->len, - bt_hex(msg->data, msg->len)); + BT_DBG("conn_handle %d type 0x%02x len %u: %s", conn_handle, type, msg->om_len, + bt_hex(msg->om_data, msg->om_len)); /* ATT_MTU - OpCode (1 byte) - Handle (2 bytes) */ - mtu = bt_gatt_get_mtu(conn) - 3; - if (mtu > msg->len) { + mtu = ble_att_mtu(conn_handle) - 3; + if (mtu > msg->om_len) { net_buf_simple_push_u8(msg, PDU_HDR(SAR_COMPLETE, type)); - return proxy_send(conn, msg->data, msg->len); + return proxy_send(conn_handle, msg->om_data, msg->om_len); } net_buf_simple_push_u8(msg, PDU_HDR(SAR_FIRST, type)); - proxy_send(conn, msg->data, mtu); + proxy_send(conn_handle, msg->om_data, mtu); net_buf_simple_pull(msg, mtu); - while (msg->len) { - if (msg->len + 1 < mtu) { + while (msg->om_len) { + if (msg->om_len + 1 < mtu) { net_buf_simple_push_u8(msg, PDU_HDR(SAR_LAST, type)); - proxy_send(conn, msg->data, msg->len); + proxy_send(conn_handle, msg->om_data, msg->om_len); break; } net_buf_simple_push_u8(msg, PDU_HDR(SAR_CONT, type)); - proxy_send(conn, msg->data, mtu); + proxy_send(conn_handle, msg->om_data, mtu); net_buf_simple_pull(msg, mtu); } return 0; } -int bt_mesh_proxy_send(struct bt_conn *conn, u8_t type, - struct net_buf_simple *msg) +int bt_mesh_proxy_send(uint16_t conn_handle, u8_t type, + struct os_mbuf *msg) { - struct bt_mesh_proxy_client *client = find_client(conn); + struct bt_mesh_proxy_client *client = find_client(conn_handle); if (!client) { BT_ERR("No Proxy Client found"); @@ -866,10 +918,10 @@ int bt_mesh_proxy_send(struct bt_conn *conn, u8_t type, return -EINVAL; } - return proxy_segment_and_send(conn, type, msg); + return proxy_segment_and_send(conn_handle, type, msg); } -#if defined(CONFIG_BLUETOOTH_MESH_PB_GATT) +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) static u8_t prov_svc_data[20] = { 0x27, 0x18, }; static const struct bt_data prov_ad[] = { @@ -879,12 +931,12 @@ static const struct bt_data prov_ad[] = { }; static const struct bt_data prov_sd[] = { - BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BLUETOOTH_DEVICE_NAME, - (sizeof(CONFIG_BLUETOOTH_DEVICE_NAME) - 1)), + BT_DATA(BT_DATA_NAME_COMPLETE, "mynewtproxy", + (sizeof("mynewtproxy") - 1)), }; #endif /* PB_GATT */ -#if defined(CONFIG_BLUETOOTH_MESH_GATT_PROXY) +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) static s64_t node_id_start; #define ID_TYPE_NET 0x00 @@ -985,7 +1037,7 @@ static s32_t gatt_proxy_advertise(void) if (node_id_start) { s64_t active = k_uptime_get() - node_id_start; - BT_DBG("Node Id active for %lld ms", active); + BT_DBG("Node Id active for %d ms", active); if (active < K_SECONDS(60)) { remaining = K_SECONDS(60) - active; @@ -1014,7 +1066,7 @@ s32_t bt_mesh_proxy_adv_start(void) { BT_DBG(""); -#if defined(CONFIG_BLUETOOTH_MESH_PB_GATT) +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) if (!bt_mesh_is_provisioned()) { if (bt_le_adv_start(proxy_adv_param, prov_ad, ARRAY_SIZE(prov_ad), @@ -1028,7 +1080,7 @@ s32_t bt_mesh_proxy_adv_start(void) } #endif /* PB_GATT */ -#if defined(CONFIG_BLUETOOTH_MESH_GATT_PROXY) +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) if (bt_mesh_is_provisioned()) { return gatt_proxy_advertise(); } @@ -1055,18 +1107,113 @@ void bt_mesh_proxy_adv_stop(void) } } -static struct bt_conn_cb conn_callbacks = { - .connected = proxy_connected, - .disconnected = proxy_disconnected, +int +ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) +{ +// BT_DBG("event %d", event->type); + + if (event->type == BLE_GAP_EVENT_CONNECT) { + proxy_connected(event->connect.conn_handle); + } else if (event->type == BLE_GAP_EVENT_DISCONNECT) { + proxy_disconnected(event->disconnect.conn.conn_handle, + event->disconnect.reason); + } else if (event->type == BLE_GAP_EVENT_SUBSCRIBE) { + if (event->subscribe.attr_handle == svc_handles.proxy_data_out_h) { +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + proxy_ccc_write(event->subscribe.conn_handle); +#endif + } else if (event->subscribe.attr_handle == + svc_handles.prov_data_out_h) { +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + prov_ccc_write(event->subscribe.conn_handle); +#endif + } + } + + return 0; +} + +static int +dummy_access_cb(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + /* + * We should never never enter this callback - it's attached to notify-only + * characteristic which are notified directly from mbuf. And we can't pass + * NULL as access_cb because gatts will assert on init... + */ + BLE_HS_DBG_ASSERT(0); + return 0; +} + +static const struct ble_gatt_svc_def svc_defs [] = { + { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), + .characteristics = (struct ble_gatt_chr_def[]) { { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_IN_VAL), + .access_cb = proxy_recv, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + }, { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL), + .access_cb = dummy_access_cb, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + .characteristics = (struct ble_gatt_chr_def[]) { { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL), + .access_cb = proxy_recv, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + }, { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL), + .access_cb = dummy_access_cb, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, { + 0, /* No more services. */ + }, }; +int bt_mesh_proxy_svcs_register(void) +{ + int rc; + + rc = ble_gatts_count_cfg(svc_defs); + assert(rc == 0); + + rc = ble_gatts_add_svcs(svc_defs); + assert(rc == 0); + + return 0; +} + int bt_mesh_proxy_init(void) { - bt_conn_cb_register(&conn_callbacks); + int i; -#if defined(CONFIG_BLUETOOTH_MESH_PB_GATT) + for (i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); ++i) { +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + k_work_init(&clients[i].send_beacons, proxy_send_beacons); +#endif + clients[i].buf = NET_BUF_SIMPLE(CLIENT_BUF_SIZE); + } + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) memcpy(prov_svc_data + 2, bt_mesh_prov_get_uuid(), 16); #endif + resolve_svc_handles(); + + ble_gatts_svc_set_visibility(svc_handles.proxy_h, 0); + ble_gatts_svc_set_visibility(svc_handles.prov_h, 0); + return 0; } + +#endif //MYNEWT_VAL(BLE_MESH_PROXY) diff --git a/nimble/host/mesh/src/proxy.h b/nimble/host/mesh/src/proxy.h index 1d65a6ee5..655139147 100644 --- a/nimble/host/mesh/src/proxy.h +++ b/nimble/host/mesh/src/proxy.h @@ -6,13 +6,17 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef __PROXY_H__ +#define __PROXY_H__ + #define BT_MESH_PROXY_NET_PDU 0x00 #define BT_MESH_PROXY_BEACON 0x01 #define BT_MESH_PROXY_CONFIG 0x02 #define BT_MESH_PROXY_PROV 0x03 -int bt_mesh_proxy_send(struct bt_conn *conn, u8_t type, - struct net_buf_simple *msg); +#include "mesh/mesh.h" + +int bt_mesh_proxy_send(uint16_t conn_handle, u8_t type, struct os_mbuf *msg); int bt_mesh_proxy_prov_enable(void); int bt_mesh_proxy_prov_disable(void); @@ -22,12 +26,16 @@ int bt_mesh_proxy_gatt_disable(void); void bt_mesh_proxy_beacon_send(struct bt_mesh_subnet *sub); -struct net_buf_simple *bt_mesh_proxy_get_buf(void); +struct os_mbuf * bt_mesh_proxy_get_buf(void); s32_t bt_mesh_proxy_adv_start(void); void bt_mesh_proxy_adv_stop(void); -bool bt_mesh_proxy_relay(struct net_buf_simple *buf, u16_t dst); -void bt_mesh_proxy_addr_add(struct net_buf_simple *buf, u16_t addr); +bool bt_mesh_proxy_relay(struct os_mbuf *buf, u16_t dst); +void bt_mesh_proxy_addr_add(struct os_mbuf *buf, u16_t addr); int bt_mesh_proxy_init(void); + +int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg); + +#endif diff --git a/nimble/host/mesh/src/test.c b/nimble/host/mesh/src/test.c deleted file mode 100644 index 5295e785d..000000000 --- a/nimble/host/mesh/src/test.c +++ /dev/null @@ -1,22 +0,0 @@ -/* Bluetooth Mesh */ - -/* - * Copyright (c) 2017 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include - -#include "common/log.h" - -#include "mesh.h" -#include "test.h" - -int bt_mesh_test(void) -{ - return 0; -} diff --git a/nimble/host/mesh/src/test.h b/nimble/host/mesh/src/test.h deleted file mode 100644 index d51513602..000000000 --- a/nimble/host/mesh/src/test.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Bluetooth Mesh */ - -/* - * Copyright (c) 2017 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#if defined(CONFIG_BLUETOOTH_MESH_SELF_TEST) -int bt_mesh_test(void); -#else -static inline int bt_mesh_test(void) -{ - return 0; -} -#endif diff --git a/nimble/host/mesh/src/transport.c b/nimble/host/mesh/src/transport.c index e12f7a26a..98fbecddd 100644 --- a/nimble/host/mesh/src/transport.c +++ b/nimble/host/mesh/src/transport.c @@ -6,24 +6,18 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include + #include #include -#include -#include -#include -#include +#include "mesh/mesh.h" +#include "mesh_priv.h" -#include -#include - -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_MESH_DEBUG_TRANS) -#include "common/log.h" +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_TRANS)) +#include "host/ble_hs_log.h" #include "crypto.h" #include "adv.h" -#include "mesh.h" #include "net.h" #include "lpn.h" #include "friend.h" @@ -62,14 +56,14 @@ static struct seg_tx { struct bt_mesh_subnet *sub; - struct net_buf *seg[BT_MESH_TX_SEG_COUNT]; + struct os_mbuf *seg[BT_MESH_TX_SEG_COUNT]; u64_t seq_auth; u8_t seg_n; /* Last segment index */ u8_t nack_count; /* Number of not acked segments */ bt_mesh_cb_t cb; void *cb_data; struct k_delayed_work retransmit; /* Retransmit timer */ -} seg_tx[CONFIG_BLUETOOTH_MESH_TX_SEG_MSG_COUNT]; +} seg_tx[MYNEWT_VAL(BLE_MESH_TX_SEG_MSG_COUNT)]; static struct seg_rx { struct bt_mesh_subnet *sub; @@ -84,22 +78,19 @@ static struct seg_rx { u32_t block; u32_t last; struct k_delayed_work ack; - struct net_buf_simple buf; - u8_t buf_data[CONFIG_BLUETOOTH_MESH_RX_SDU_MAX]; -} seg_rx[CONFIG_BLUETOOTH_MESH_RX_SEG_MSG_COUNT] = { - [0 ... (CONFIG_BLUETOOTH_MESH_RX_SEG_MSG_COUNT - 1)] = { - .buf.size = CONFIG_BLUETOOTH_MESH_RX_SDU_MAX, - }, + struct os_mbuf *buf; +} seg_rx[MYNEWT_VAL(BLE_MESH_RX_SEG_MSG_COUNT)] = { + [0 ... (MYNEWT_VAL(BLE_MESH_RX_SEG_MSG_COUNT) - 1)] = { 0 }, }; static int send_unseg(struct bt_mesh_net_tx *tx, u8_t aid, - struct net_buf_simple *sdu) + struct os_mbuf *sdu) { - struct net_buf *buf; + struct os_mbuf *buf; u8_t xmit; BT_DBG("src 0x%04x dst 0x%04x app_idx 0x%04x sdu_len %u", - tx->src, tx->ctx->addr, tx->ctx->app_idx, sdu->len); + tx->src, tx->ctx->addr, tx->ctx->app_idx, sdu->om_len); xmit = bt_mesh_net_transmit_get(); buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, TRANSMIT_COUNT(xmit), @@ -112,12 +103,12 @@ static int send_unseg(struct bt_mesh_net_tx *tx, u8_t aid, net_buf_reserve(buf, 9); if (tx->ctx->app_idx == BT_MESH_KEY_DEV) { - net_buf_add_u8(buf, UNSEG_HDR(0, 0)); + net_buf_simple_add_u8(buf, UNSEG_HDR(0, 0)); } else { - net_buf_add_u8(buf, UNSEG_HDR(1, aid)); + net_buf_simple_add_u8(buf, UNSEG_HDR(1, aid)); } - net_buf_add_mem(buf, sdu->data, sdu->len); + net_buf_add_mem(buf, sdu->om_data, sdu->om_len); return bt_mesh_net_send(tx, buf, NULL); } @@ -180,7 +171,7 @@ static inline void seg_tx_complete(struct seg_tx *tx, int err) seg_tx_reset(tx); } -static void seg_sent(struct net_buf *buf, int err) +static void seg_sent(struct os_mbuf *buf, int err) { struct seg_tx *tx = &seg_tx[BT_MESH_ADV(buf)->seg.tx_id]; @@ -192,7 +183,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) int i, err; for (i = 0; i <= tx->seg_n; i++) { - struct net_buf *seg = tx->seg[i]; + struct os_mbuf *seg = tx->seg[i]; if (!seg) { continue; @@ -223,15 +214,14 @@ static void seg_tx_send_unacked(struct seg_tx *tx) } } -static void seg_retransmit(struct k_work *work) +static void seg_retransmit(struct os_event *work) { - struct seg_tx *tx = CONTAINER_OF(work, struct seg_tx, retransmit); - + struct seg_tx *tx = work->ev_arg; seg_tx_send_unacked(tx); } static int send_seg(struct bt_mesh_net_tx *net_tx, u8_t aid, - u8_t mic_len, struct net_buf_simple *sdu, + u8_t mic_len, struct os_mbuf *sdu, bt_mesh_cb_t cb, void *cb_data) { u8_t seg_hdr, seg_o; @@ -241,15 +231,15 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, u8_t aid, BT_DBG("src 0x%04x dst 0x%04x app_idx 0x%04x mic_len %u sdu_len %u", net_tx->src, net_tx->ctx->addr, net_tx->ctx->app_idx, mic_len, - sdu->len); + sdu->om_len); - if (sdu->len < 1) { + if (sdu->om_len < 1) { BT_ERR("Zero-length SDU not allowed"); return -EINVAL; } - if (sdu->len > BT_MESH_TX_SDU_MAX) { - BT_ERR("Not enough segment buffers for length %u", sdu->len); + if (sdu->om_len > BT_MESH_TX_SDU_MAX) { + BT_ERR("Not enough segment buffers for length %u", sdu->om_len); return -EMSGSIZE; } @@ -272,7 +262,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, u8_t aid, } seg_o = 0; - tx->seg_n = (sdu->len - 1) / 12; + tx->seg_n = (sdu->om_len - 1) / 12; tx->nack_count = tx->seg_n + 1; tx->seq_auth = SEQ_AUTH(BT_MESH_NET_IVI_TX, bt_mesh.seq); tx->sub = net_tx->sub; @@ -281,8 +271,8 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, u8_t aid, BT_DBG("SeqZero 0x%04x", seq_zero); - for (seg_o = 0; sdu->len; seg_o++) { - struct net_buf *seg; + for (seg_o = 0; sdu->om_len; seg_o++) { + struct os_mbuf *seg; u16_t len; u8_t xmit; int err; @@ -303,14 +293,14 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, u8_t aid, net_buf_reserve(seg, 9); - net_buf_add_u8(seg, seg_hdr); - net_buf_add_u8(seg, (SZMIC(mic_len) << 7) | seq_zero >> 6); - net_buf_add_u8(seg, (((seq_zero & 0x3f) << 2) | + net_buf_simple_add_u8(seg, seg_hdr); + net_buf_simple_add_u8(seg, (SZMIC(mic_len) << 7) | seq_zero >> 6); + net_buf_simple_add_u8(seg, (((seq_zero & 0x3f) << 2) | (seg_o >> 3))); - net_buf_add_u8(seg, ((seg_o & 0x07) << 5) | tx->seg_n); + net_buf_simple_add_u8(seg, ((seg_o & 0x07) << 5) | tx->seg_n); - len = min(sdu->len, 12); - net_buf_add_mem(seg, sdu->data, len); + len = min(sdu->om_len, 12); + net_buf_add_mem(seg, sdu->om_data, len); net_buf_simple_pull(sdu, len); tx->seg[seg_o] = net_buf_ref(seg); @@ -348,10 +338,10 @@ struct bt_mesh_app_key *bt_mesh_app_key_find(u16_t app_idx) return NULL; } -int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, +int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct os_mbuf *msg, bt_mesh_cb_t cb, void *cb_data) { - bool seg = (msg->len > 11 || cb); + bool seg = (msg->om_len > 11 || cb); const u8_t *key; u8_t mic_len, aid, aszmic; u8_t *ad; @@ -359,7 +349,7 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx->sub->net_idx, tx->ctx->app_idx, tx->ctx->addr); - BT_DBG("len %u: %s", msg->len, bt_hex(msg->data, msg->len)); + BT_DBG("len %u: %s", msg->om_len, bt_hex(msg->om_data, msg->om_len)); if (tx->ctx->app_idx == BT_MESH_KEY_DEV) { key = bt_mesh.dev_key; @@ -447,21 +437,22 @@ static bool is_replay(struct bt_mesh_net_rx *rx) } static int sdu_recv(struct bt_mesh_net_rx *rx, u8_t hdr, u8_t mic_size, - u8_t aszmic, struct net_buf_simple *buf) + u8_t aszmic, struct os_mbuf *buf) { - struct net_buf_simple *sdu = - NET_BUF_SIMPLE(CONFIG_BLUETOOTH_MESH_RX_SDU_MAX - 4); + struct os_mbuf *sdu = + NET_BUF_SIMPLE(MYNEWT_VAL(BLE_MESH_RX_SDU_MAX) - 4); u8_t *ad; u16_t i; - int err; + int err = 0; BT_DBG("MIC_SIZE %u ASZMIC %u AKF %u AID 0x%02x", mic_size, aszmic, AKF(&hdr), AID(&hdr)); - BT_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("len %u: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (buf->len < 1 + mic_size) { + if (buf->om_len < 1 + mic_size) { BT_ERR("Too short SDU + MIC"); - return -EINVAL; + err = -EINVAL; + goto done; } if (BT_MESH_ADDR_IS_VIRTUAL(rx->dst)) { @@ -471,7 +462,7 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, u8_t hdr, u8_t mic_size, } /* Adjust the length to not contain the MIC at the end */ - buf->len -= mic_size; + buf->om_len -= mic_size; if (!AKF(&hdr)) { net_buf_simple_init(sdu, 0); @@ -481,12 +472,13 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, u8_t hdr, u8_t mic_size, BT_MESH_NET_IVI_RX(rx)); if (err) { BT_ERR("Unable to decrypt with DevKey"); - return -EINVAL; + err = -EINVAL; + goto done; } rx->ctx.app_idx = BT_MESH_KEY_DEV; bt_mesh_model_recv(rx, sdu); - return 0; + goto done; } for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { @@ -525,7 +517,8 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, u8_t hdr, u8_t mic_size, if (is_replay(rx)) { BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", rx->ctx.addr, rx->dst, rx->seq); - return -EINVAL; + err = -EINVAL; + goto done; } bt_mesh_model_recv(rx, sdu); @@ -533,11 +526,14 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, u8_t hdr, u8_t mic_size, BT_WARN("No matching AppKey"); - return -EINVAL; + err = -EINVAL; +done: + os_mbuf_free_chain(sdu); + return err; } static int trans_ack(struct bt_mesh_net_rx *rx, u8_t hdr, - struct net_buf_simple *buf) + struct os_mbuf *buf) { struct seg_tx *tx; unsigned int bit; @@ -546,7 +542,7 @@ static int trans_ack(struct bt_mesh_net_rx *rx, u8_t hdr, u8_t obo; int i; - if (buf->len < 6) { + if (buf->om_len < 6) { BT_ERR("Too short ack message"); return -EINVAL; } @@ -606,12 +602,12 @@ static int trans_ack(struct bt_mesh_net_rx *rx, u8_t hdr, } static int trans_heartbeat(struct bt_mesh_net_rx *rx, - struct net_buf_simple *buf) + struct os_mbuf *buf) { u8_t init_ttl, hops; u16_t feat; - if (buf->len < 3) { + if (buf->om_len < 3) { BT_ERR("Too short heartbeat message"); return -EINVAL; } @@ -631,11 +627,11 @@ static int trans_heartbeat(struct bt_mesh_net_rx *rx, } static int ctl_recv(struct bt_mesh_net_rx *rx, u8_t hdr, - struct net_buf_simple *buf) + struct os_mbuf *buf) { u8_t ctl_op = CTL_OP(&hdr); - BT_DBG("OpCode 0x%02x len %u", ctl_op, buf->len); + BT_DBG("OpCode 0x%02x len %u", ctl_op, buf->om_len); switch (ctl_op) { case TRANS_CTL_OP_ACK: @@ -644,7 +640,7 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, u8_t hdr, return trans_heartbeat(rx, buf); } -#if defined(CONFIG_BLUETOOTH_MESH_FRIEND) +#if (MYNEWT_VAL(BLE_MESH_FRIEND)) switch (ctl_op) { case TRANS_CTL_OP_FRIEND_POLL: return bt_mesh_friend_poll(rx, buf); @@ -653,7 +649,7 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, u8_t hdr, } #endif -#if defined(CONFIG_BLUETOOTH_MESH_LOW_POWER) +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) if (ctl_op == TRANS_CTL_OP_FRIEND_OFFER) { return bt_mesh_lpn_friend_offer(rx, buf); } @@ -675,20 +671,20 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, u8_t hdr, return bt_mesh_lpn_friend_sub_cfm(rx, buf); } } -#endif /* CONFIG_BLUETOOTH_MESH_LOW_POWER */ +#endif /* MYNEWT_VAL(BLE_MESH_LOW_POWER) */ BT_WARN("Unhandled TransOpCode 0x%02x", ctl_op); return -ENOENT; } -static int trans_unseg(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) +static int trans_unseg(struct os_mbuf *buf, struct bt_mesh_net_rx *rx) { u8_t hdr; - BT_DBG("AFK %u AID 0x%02x", AKF(buf->data), AID(buf->data)); + BT_DBG("AFK %u AID 0x%02x", AKF(buf->om_data), AID(buf->om_data)); - if (buf->len < 1) { + if (buf->om_len < 1) { BT_ERR("Too small unsegmented PDU"); return -EINVAL; } @@ -718,7 +714,7 @@ static inline s32_t ack_timeout(struct seg_rx *rx) int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, u8_t ctl_op, void *data, size_t data_len, bt_mesh_adv_func_t cb) { - struct net_buf *buf; + struct os_mbuf *buf; u8_t xmit; BT_DBG("src 0x%04x dst 0x%04x ttl 0x%02x ctl 0x%02x", tx->src, @@ -736,7 +732,7 @@ int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, u8_t ctl_op, void *data, /* Reserve space for Network headers */ net_buf_reserve(buf, 9); - net_buf_add_u8(buf, CTL_HDR(ctl_op, 0)); + net_buf_simple_add_u8(buf, CTL_HDR(ctl_op, 0)); net_buf_add_mem(buf, data, data_len); @@ -794,9 +790,9 @@ static void seg_rx_reset(struct seg_rx *rx) rx->in_use = 0; } -static void seg_ack(struct k_work *work) +static void seg_ack(struct os_event *work) { - struct seg_rx *rx = CONTAINER_OF(work, struct seg_rx, ack); + struct seg_rx *rx = work->ev_arg; BT_DBG("rx %p", rx); @@ -825,7 +821,7 @@ static inline u8_t seg_len(bool ctl) static inline bool sdu_len_is_ok(bool ctl, u8_t seg_n) { - return ((seg_n * seg_len(ctl) + 1) <= CONFIG_BLUETOOTH_MESH_RX_SDU_MAX); + return ((seg_n * seg_len(ctl) + 1) <= MYNEWT_VAL(BLE_MESH_RX_SDU_MAX)); } static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx, @@ -894,7 +890,7 @@ static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx, } rx->in_use = 1; - net_buf_simple_init(&rx->buf, 0); + net_buf_simple_init(rx->buf, 0); rx->sub = net_rx->sub; rx->ctl = net_rx->ctl; rx->seq_auth = *seq_auth; @@ -914,18 +910,18 @@ static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx, return NULL; } -static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx) +static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx) { struct seg_rx *rx; u64_t seq_auth; - u8_t *hdr = buf->data; + u8_t *hdr = buf->om_data; u16_t seq_zero; u8_t seg_n; u8_t seg_o; int err; - if (buf->len < 5) { - BT_ERR("Too short segmented message (len %u)", buf->len); + if (buf->om_len < 5) { + BT_ERR("Too short segmented message (len %u)", buf->om_len); return -EINVAL; } @@ -1009,11 +1005,11 @@ found_rx: */ if (seg_o == seg_n) { /* Set the expected final buffer length */ - rx->buf.len = seg_n * seg_len(rx->ctl) + buf->len; + rx->buf->om_len = seg_n * seg_len(rx->ctl) + buf->om_len; BT_DBG("Target len %u * %u + %u = %u", seg_n, seg_len(rx->ctl), - buf->len, rx->buf.len); + buf->om_len, rx->buf->om_len); - if (rx->buf.len > CONFIG_BLUETOOTH_MESH_RX_SDU_MAX) { + if (rx->buf->om_len > MYNEWT_VAL(BLE_MESH_RX_SDU_MAX)) { BT_ERR("Too large SDU len"); send_ack(net_rx->sub, net_rx->dst, net_rx->ctx.addr, net_rx->ctx.send_ttl, seq_zero, 0); @@ -1021,7 +1017,7 @@ found_rx: return 0; } } else { - if (buf->len != seg_len(rx->ctl)) { + if (buf->om_len != seg_len(rx->ctl)) { BT_ERR("Incorrect segment size for message type"); return -EINVAL; } @@ -1036,7 +1032,7 @@ found_rx: } /* Location in buffer can be calculated based on seg_o & rx->ctl */ - memcpy(rx->buf_data + (seg_o * seg_len(rx->ctl)), buf->data, buf->len); + memcpy(rx->buf->om_data + (seg_o * seg_len(rx->ctl)), buf->om_data, buf->om_len); BT_DBG("Received %u/%u", seg_o, seg_n); @@ -1057,10 +1053,10 @@ found_rx: net_rx->ctx.send_ttl, seq_zero, rx->block); if (net_rx->ctl) { - err = ctl_recv(net_rx, *hdr, &rx->buf); + err = ctl_recv(net_rx, *hdr, rx->buf); } else { err = sdu_recv(net_rx, *hdr, MIC_SIZE(hdr), - SZMIC(MIC_SIZE(hdr)), &rx->buf); + SZMIC(MIC_SIZE(hdr)), rx->buf); } seg_rx_reset(rx); @@ -1068,26 +1064,26 @@ found_rx: return err; } -int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) +int bt_mesh_trans_recv(struct os_mbuf *buf, struct bt_mesh_net_rx *rx) { int err; BT_DBG("src 0x%04x dst 0x%04x seq 0x%08x", rx->ctx.addr, rx->dst, rx->seq); - BT_DBG("Payload %s", bt_hex(buf->data, buf->len)); + BT_DBG("Payload %s", bt_hex(buf->om_data, buf->om_len)); /* If LPN mode is enabled messages are only accepted when we've * requested the Friend to send them. The messages must also * be encrypted using the Friend Credentials. */ - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER) && + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER)) && bt_mesh_lpn_established() && (!bt_mesh_lpn_waiting_update() || !rx->ctx.friend_cred)) { BT_WARN("Ignoring unexpected message in Low Power mode"); return -EAGAIN; } - if (SEG(buf->data)) { + if (SEG(buf->om_data)) { err = trans_seg(buf, rx); } else { err = trans_unseg(buf, rx); @@ -1100,7 +1096,7 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) * we still need to go through the actual sending to the bearer and * wait for ReceiveDelay before transitioning to WAIT_UPDATE state. */ - if (IS_ENABLED(CONFIG_BLUETOOTH_MESH_LOW_POWER) && + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER)) && bt_mesh_lpn_established() && bt_mesh_lpn_waiting_update()) { bt_mesh_lpn_msg_received(rx); } @@ -1125,9 +1121,15 @@ void bt_mesh_trans_init(void) for (i = 0; i < ARRAY_SIZE(seg_tx); i++) { k_delayed_work_init(&seg_tx[i].retransmit, seg_retransmit); + k_delayed_work_add_arg(&seg_tx[i].retransmit, &seg_tx[i]); } + /* XXX Probably we need mempool for that. + * For now we increase MSYS_1_BLOCK_COUNT + */ for (i = 0; i < ARRAY_SIZE(seg_rx); i++) { + seg_rx[i].buf = NET_BUF_SIMPLE(MYNEWT_VAL(BLE_MESH_RX_SDU_MAX)); k_delayed_work_init(&seg_rx[i].ack, seg_ack); + k_delayed_work_add_arg(&seg_rx[i].ack, &seg_rx[i]); } } diff --git a/nimble/host/mesh/src/transport.h b/nimble/host/mesh/src/transport.h index 756af6bd3..b6cb00115 100644 --- a/nimble/host/mesh/src/transport.h +++ b/nimble/host/mesh/src/transport.h @@ -6,7 +6,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define BT_MESH_TX_SEG_COUNT (CONFIG_BLUETOOTH_MESH_ADV_BUF_COUNT - 3) +#include "syscfg/syscfg.h" +#include "mesh/mesh.h" + +#define BT_MESH_TX_SEG_COUNT (MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT) - 3) #define BT_MESH_TX_SDU_MAX (BT_MESH_TX_SEG_COUNT * 12) #define TRANS_CTL_OP_ACK 0x00 @@ -21,64 +24,79 @@ #define TRANS_CTL_OP_FRIEND_SUB_CFM 0x09 #define TRANS_CTL_OP_HEARTBEAT 0x0a -struct bt_mesh_ctl_friend_poll { - u8_t fsn; -} __packed; +struct bt_mesh_ctl_friend_poll +{ + u8_t fsn; +}__attribute__((__packed__)); -struct bt_mesh_ctl_friend_update { - u8_t flags; - u32_t iv_index; - u8_t md; -} __packed; +struct bt_mesh_ctl_friend_update +{ + u8_t flags; + u32_t iv_index; + u8_t md; +}__attribute__((__packed__)); -struct bt_mesh_ctl_friend_req { - u8_t criteria; - u8_t recv_delay; - u8_t poll_to[3]; - u16_t prev_addr; - u8_t num_elem; - u16_t lpn_counter; -} __packed; +struct bt_mesh_ctl_friend_req +{ + u8_t criteria; + u8_t recv_delay; + u8_t poll_to[3]; + u16_t prev_addr; + u8_t num_elem; + u16_t lpn_counter; +}__attribute__((__packed__)); -struct bt_mesh_ctl_friend_offer { - u8_t recv_win; - u8_t queue_size; - u8_t sub_list_size; - s8_t rssi; - u16_t frnd_counter; -} __packed; +struct bt_mesh_ctl_friend_offer +{ + u8_t recv_win; + u8_t queue_size; + u8_t sub_list_size; + s8_t rssi; + u16_t frnd_counter; +}__attribute__((__packed__)); -struct bt_mesh_ctl_friend_clear { - u16_t lpn_addr; - u16_t lpn_counter; -} __packed; +struct bt_mesh_ctl_friend_clear +{ + u16_t lpn_addr; + u16_t lpn_counter; +}__attribute__((__packed__)); -struct bt_mesh_ctl_friend_clear_confirm { - u16_t lpn_addr; - u16_t lpn_counter; -} __packed; +struct bt_mesh_ctl_friend_clear_confirm +{ + u16_t lpn_addr; + u16_t lpn_counter; +}__attribute__((__packed__)); -struct bt_mesh_ctl_friend_sub { - u8_t xact; - u16_t addr_list[5]; -} __packed; +struct bt_mesh_ctl_friend_sub +{ + u8_t xact; + u16_t addr_list[5]; +}__attribute__((__packed__)); -struct bt_mesh_ctl_friend_sub_confirm { - u8_t xact; -} __packed; +struct bt_mesh_ctl_friend_sub_confirm +{ + u8_t xact; +}__attribute__((__packed__)); -struct bt_mesh_app_key *bt_mesh_app_key_find(u16_t app_idx); +struct bt_mesh_app_key * +bt_mesh_app_key_find(u16_t app_idx); -bool bt_mesh_tx_in_progress(void); +bool +bt_mesh_tx_in_progress(void); -void bt_mesh_rx_reset(void); +void +bt_mesh_rx_reset(void); -int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, u8_t ctl_op, void *data, - size_t data_len, bt_mesh_adv_func_t cb); +int +bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, u8_t ctl_op, void *data, + size_t data_len, bt_mesh_adv_func_t cb); -int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, - bt_mesh_cb_t cb, void *cb_data); +int +bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct os_mbuf *msg, + bt_mesh_cb_t cb, void *cb_data); -int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx); +int +bt_mesh_trans_recv(struct os_mbuf *buf, struct bt_mesh_net_rx *rx); -void bt_mesh_trans_init(void); +void +bt_mesh_trans_init(void); diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml new file mode 100644 index 000000000..95b67f9b0 --- /dev/null +++ b/nimble/host/mesh/syscfg.yml @@ -0,0 +1,322 @@ +# 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. +# + +# Package: net/nimble/host/mesh + +syscfg.defs: + BLE_MESH_PROV: + description: > + Enable provisioning. It is automatically enabled whenever + BLE_MESH_PB_ADV or BLE_MESH_PB_GATT is set. + value: 1 + + BLE_MESH_PB_ADV: + description: > + Enable this option to allow the device to be provisioned over + the advertising bearer. + value: 1 + + BLE_MESH_PROXY: + description: > + Enable proxy. This is automatically set whenever BLE_MESH_PB_GATT or + BLE_MESH_GATT_PROXY is set. + value: 0 + + BLE_MESH_PB_GATT: + description: > + Enable this option to allow the device to be provisioned over + the advertising bearer. + value: 1 + + BLE_MESH_GATT_PROXY: + descruption: > + This option enables support for the Mesh GATT Proxy Service, + i.e. the ability to act as a proxy between a Mesh GATT Client + and a Mesh network. + value: 1 + + BLE_MESH_PROXY_FILTER_SIZE: + descryption: > + This option specifies how many Proxy Filter entries the local + node supports. + value: 1 + + BLE_MESH_LOCAL_INTERFACE: + description: > + This is needed in order to send messages between two local Mesh + elements. Only disable it if you're sure this will not be needed + (which description: >s save a little bit of memory). + value: 1 + + BLE_MESH_SUBNET_COUNT: + description: > + This option specifies how many subnets a Mesh network can + participate in at the same time. + value: 1 + + BLE_MESH_APP_KEY_COUNT: + description: > + This option specifies how many application keys the device can + store per network. + value: 1 + + BLE_MESH_MODEL_KEY_COUNT: + description: > + This option specifies how many application keys each model can + at most be bound to. + value: 1 + + BLE_MESH_MODEL_GROUP_COUNT: + description: > + This option specifies how many group addresses each model can + at most be subscribed to. + value: 1 + + BLE_MESH_LABEL_COUNT: + description: > + This option specifies how many Label UUIDs can be stored. + value: 1 + + BLE_MESH_CRPL: + description: > + This options specifies the maximum capacity of the replay + protection list. This option is similar to the network message + cache size, but has a different purpose. + value: 10 + + BLE_MESH_ADV_TASK_PRIO: + description: > + Advertising task prio (FIXME) + value: 9 + + BLE_MESH_MSG_CACHE_SIZE: + description: > + Number of messages that are cached for the network. This description + prevent unnecessary decryption operations and unnecessary + relays. This option is similar to the replay protection list, + but has a different purpose. + value: 10 + + BLE_MESH_ADV_BUF_COUNT: + description: > + Number of advertising buffers available. The transport layer + reserves ADV_BUF_COUNT - 3 buffers for outgoing segments. The + maximum outgoing SDU size is 12 times this number (out of which + 4 or 8 bytes is used for the Transport Layer MIC). For + example, 5 segments means the maximum SDU size is 60 bytes, + which leaves 56 bytes for application layer data using a + 4-byte MIC and 52 bytes using an 8-byte MIC. + value: 10 + + BLE_MESH_TX_SEG_MSG_COUNT: + description: > + Maximum number of simultaneous outgoing multi-segment and/or + reliable messages. + value: 4 + + BLE_MESH_RX_SEG_MSG_COUNT: + description: > + Maximum number of simultaneous incoming multi-segment and/or + reliable messages. + value: 2 + + BLE_MESH_RX_SDU_MAX: + description: > + Maximum incoming Upper Transport Access PDU length. Leave this + to the value; value, unless you really need to optimize memory + usage. + value: 384 + + BLE_MESH_RELAY: + description: > + Support for acting as a Mesh Relay Node. + value: 0 + + BLE_MESH_LOW_POWER: + description: > + Enable this option to be able to act as a Low Power Node. + value: 1 + + BLE_MESH_LPN_RSSI_FACTOR: + description: > + The contribution of the RSSI measured by the Friend node used + in Friend Offer Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5. + value: 0 + + BLE_MESH_LPN_RECV_WIN_FACTOR: + description: > + The contribution of the supported Receive Window used in + Friend Offer Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5. + value: 0 + + BLE_MESH_LPN_MIN_QUEUE_SIZE: + description: > + The MinQueueSizeLog field is defined as log_2(N), where N is + the minimum number of maximum size Lower Transport PDUs that + the Friend node can store in its Friend Queue. As an example, + MinQueueSizeLog value 1 gives N = 2, and value 7 gives N = 128. + value: 1 + + BLE_MESH_LPN_RECV_DELAY: + description: > + The ReceiveDelay is the time between the Low Power node + sending a request and listening for a response. This delay + allows the Friend node time to prepare the response. The value + is in units of milliseconds. + value: 20 + + BLE_MESH_LPN_POLL_TIMEOUT: + description: > + PollTimeout timer is used to measure time between two + consecutive requests sent by the Low Power node. If no + requests are received by the Friend node before the + PollTimeout timer expires, then the friendship is considered + terminated. The value is in units of 100 milliseconds. + value: 100 + + BLE_MESH_LPN_SCAN_LATENCY: + description: > + Latency in milliseconds that it takes to enable scanning. This + is in practice how much time in advance before the Receive Window + that scanning is requested to be enabled. + value: 10 + + BLE_MESH_LPN_GROUPS: + description: > + Maximum number of groups that the LPN can subscribe to. + value: 10 + + BLE_MESH_FRIEND: + description: > + Enable this option to be able to act as a Friend Node. + value: 1 + + BLE_MESH_FRIEND_RECV_WIN: + description: > + Receive Window in milliseconds supported by the Friend node. + value: 255 + + BLE_MESH_FRIEND_QUEUE_SIZE: + description: > + Queue Size available on the Friend node. + value: 16 + + BLE_MESH_FRIEND_SUB_LIST_SIZE: + description: > + Size of the Subscription List that can be supported by a + Friend node for a Low Power node. + value: 16 + + BLE_MESH_FRIEND_LPN_COUNT: + description: > + Number of Low Power Nodes the Friend can have a Friendship + with simultaneously. + value: 1 + + BLE_MESH_DEBUG: + description: > + Use this option to enable debug logs for the Bluetooth + Mesh functionality. + value: 0 + + BLE_MESH_DEBUG_NET: + description: > + Use this option to enable Network layer debug logs for the + Bluetooth Mesh functionality. + value: 0 + + BLE_MESH_DEBUG_TRANS: + description: > + Use this option to enable Transport layer debug logs for the + Bluetooth Mesh functionality. + value: 0 + + BLE_MESH_DEBUG_BEACON: + description: > + Use this option to enable Beacon-related debug logs for the + Bluetooth Mesh functionality. + value: 0 + + BLE_MESH_DEBUG_CRYPTO: + description: > + Use this option to enable cryptographic debug logs for the + Bluetooth Mesh functionality. + value: 0 + + BLE_MESH_DEBUG_PROV: + description: > + Use this option to enable Provisioning debug logs for the + Bluetooth Mesh functionality. + value: 0 + + BLE_MESH_DEBUG_ACCESS: + description: > + Use this option to enable Access layer and device composition + related debug logs for Bluetooth Mesh. + value: 0 + + BLE_MESH_DEBUG_MODEL: + description: > + Use this option to enable debug logs for the Foundation + Models. + value: 0 + + BLE_MESH_DEBUG_ADV: + description: > + Use this option to enable advertising debug logs for + the Bluetooth Mesh functionality. + value: 0 + + BLE_MESH_DEBUG_LOW_POWER: + description: > + Use this option to enable Low Power debug logs for the + Bluetooth Mesh functionality. + value: 0 + + BLE_MESH_DEBUG_FRIEND: + description: > + Use this option to enable Friend debug logs for the + Bluetooth Mesh functionality. + value: 0 + + BLE_MESH_DEBUG_PROXY: + description: > + Use this option to enable Proxy protocol debug logs. + value: 0 + + BLE_MESH_IV_UPDATE_TEST: + description: > + This option removes the 96 hour limit of the IV Update + Procedure and lets the state be changed at any time. + value: 0 + + BLE_MESH_DEV_UUID: + description: > + Device UUID + value: ((uint8_t[16]){0x11, 0x22, 0}) + + +syscfg.vals.BLE_MESH_GATT_PROXY: + BLE_MESH_PROXY: 1 + +syscfg.vals.BLE_MESH_PB_GATT: + BLE_MESH_PROXY: 1 + BLE_MESH_PROV: 1 + +syscfg.vals.BLE_MESH_PB_ADV: + BLE_MESH_PROV: 1 diff --git a/nimble/host/pkg.yml b/nimble/host/pkg.yml index bf83156bf..4affd38ce 100644 --- a/nimble/host/pkg.yml +++ b/nimble/host/pkg.yml @@ -39,6 +39,9 @@ pkg.deps.BLE_SM_SC: pkg.deps.BLE_MONITOR_RTT: - hw/drivers/rtt +pkg.deps.BLE_MESH: + - net/nimble/host/mesh + pkg.req_apis: - ble_transport - console diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index e267d18e5..160ab389c 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -113,9 +113,19 @@ struct ble_gap_master_state { uint8_t extended:1; } disc; }; + + }; static bssnz_t struct ble_gap_master_state ble_gap_master; + +#if MYNEWT_VAL(BLE_MESH) +struct ble_gap_mesh_state { + ble_gap_event_fn *cb; + void *cb_arg; +} ble_gap_mesh; +#endif + /** * The state of the in-progress slave connection. If no slave connection is * currently in progress, then the op field is set to BLE_GAP_OP_NULL. @@ -521,6 +531,17 @@ ble_gap_set_prefered_le_phy(uint16_t conn_handle, uint8_t tx_phys_mask, buf, sizeof(buf), NULL, 0, NULL); } +#if MYNEWT_VAL(BLE_MESH) +int +ble_gap_mesh_cb_register(ble_gap_event_fn *cb, void *cb_arg) +{ + ble_gap_mesh.cb = cb; + ble_gap_mesh.cb_arg = cb_arg; + + return 0; +} +#endif + /***************************************************************************** * $misc * *****************************************************************************/ @@ -587,6 +608,16 @@ ble_gap_slave_reset_state(void) ble_hs_timer_resched(); } +static bool +ble_gap_has_client(struct ble_gap_master_state *out_state) +{ + if (!out_state) { + return 0; + } + + return out_state->cb; +} + static void ble_gap_master_extract_state(struct ble_gap_master_state *out_state, int reset_state) @@ -638,7 +669,7 @@ ble_gap_master_connect_failure(int status) int rc; ble_gap_master_extract_state(&state, 1); - if (state.cb != NULL) { + if (!ble_gap_has_client(&state)) { memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_CONNECT; event.connect.status = status; @@ -686,27 +717,32 @@ ble_gap_is_extended_disc(void) static void ble_gap_disc_report(void *desc) { - struct ble_gap_master_state state; + struct ble_gap_master_state state;; struct ble_gap_event event; - ble_gap_master_extract_state(&state, 0); - - if (state.cb != NULL) { - memset(&event, 0, sizeof event); - if (ble_gap_is_extended_disc()) { + memset(&event, 0, sizeof event); + if (ble_gap_is_extended_disc()) { #if MYNEWT_VAL(BLE_EXT_ADV) - event.type = BLE_GAP_EVENT_EXT_DISC; - event.ext_disc = *((struct ble_gap_ext_disc_desc *)desc); + event.type = BLE_GAP_EVENT_EXT_DISC; + event.ext_disc = *((struct ble_gap_ext_disc_desc *)desc); #else - assert(0); + assert(0); #endif - } else { - event.type = BLE_GAP_EVENT_DISC; - event.disc = *((struct ble_gap_disc_desc *)desc); - } + } else { + event.type = BLE_GAP_EVENT_DISC; + event.disc = *((struct ble_gap_disc_desc *)desc); + } + ble_gap_master_extract_state(&state, 0); + if (ble_gap_has_client(&state)) { state.cb(&event, state.cb_arg); } + +#if MYNEWT_VAL(BLE_MESH) + if (ble_gap_mesh.cb) { + ble_gap_mesh.cb(&event, ble_gap_mesh.cb_arg); + } +#endif } static void @@ -715,14 +751,19 @@ ble_gap_disc_complete(void) struct ble_gap_master_state state; struct ble_gap_event event; + memset(&event, 0, sizeof event); + event.type = BLE_GAP_EVENT_DISC_COMPLETE; + ble_gap_master_extract_state(&state, 1); - - if (state.cb != NULL) { - memset(&event, 0, sizeof event); - event.type = BLE_GAP_EVENT_DISC_COMPLETE; - + if (ble_gap_has_client(&state)) { ble_gap_call_event_cb(&event, state.cb, state.cb_arg); } + +#if MYNEWT_VAL(BLE_MESH) + if (ble_gap_mesh.cb) { + ble_gap_mesh.cb(&event, ble_gap_mesh.cb_arg); + } +#endif } static void @@ -924,6 +965,12 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason) event.disconnect.reason = reason; ble_gap_call_event_cb(&event, snap.cb, snap.cb_arg); +#if MYNEWT_VAL(BLE_MESH) + if (ble_gap_mesh.cb) { + ble_gap_mesh.cb(&event, ble_gap_mesh.cb_arg); + } +#endif + STATS_INC(ble_gap_stats, disconnect); } @@ -1341,6 +1388,12 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt) event.connect.status = 0; ble_gap_call_conn_event_cb(&event, evt->connection_handle); +#if MYNEWT_VAL(BLE_MESH) + if (ble_gap_mesh.cb) { + ble_gap_mesh.cb(&event, ble_gap_mesh.cb_arg); + } +#endif + ble_gap_rd_rem_sup_feat_tx(evt->connection_handle); return 0; @@ -4138,6 +4191,12 @@ ble_gap_subscribe_event(uint16_t conn_handle, uint16_t attr_handle, event.subscribe.prev_indicate = !!prev_indicate; event.subscribe.cur_indicate = !!cur_indicate; ble_gap_call_conn_event_cb(&event, conn_handle); + +#if MYNEWT_VAL(BLE_MESH) + if (ble_gap_mesh.cb) { + ble_gap_mesh.cb(&event, ble_gap_mesh.cb_arg); + } +#endif } /***************************************************************************** diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index 0e054bb60..76bf81591 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -353,3 +353,11 @@ syscfg.defs: mechanism. value: 8 + + BLE_MESH: + description: > + Enable Bluetooth Mesh + value: 0 + +syscfg.vals.BLE_MESH: + BLE_SM_SC: 1