mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-10-09 15:57:22 +00:00
nimble/mesh: Porting Mesh to Mynewt
This patch adds glue layer for mesh together with blemesh sample application. X-Original-Commit: 1a6239b0b98a000da62357fe4d62726c7ccec19c
This commit is contained in:
@@ -23,6 +23,8 @@
|
||||
#include <inttypes.h>
|
||||
#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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__ */
|
||||
@@ -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 <assert.h>
|
||||
|
||||
#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
|
||||
@@ -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 <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#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 */
|
||||
@@ -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 <[email protected]>"
|
||||
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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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?)
|
||||
@@ -6,19 +6,15 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <errno.h>
|
||||
#include <misc/util.h>
|
||||
#include <misc/byteorder.h>
|
||||
|
||||
#include <net/buf.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/mesh.h>
|
||||
#include <os/os_mbuf.h>
|
||||
#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;
|
||||
|
||||
@@ -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
|
||||
|
||||
+199
-130
@@ -6,20 +6,13 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <misc/stack.h>
|
||||
#include <misc/util.h>
|
||||
#include "mesh/mesh.h"
|
||||
|
||||
#include <net/buf.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/conn.h>
|
||||
#include <bluetooth/mesh.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
+41
-28
@@ -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
|
||||
|
||||
@@ -6,28 +6,24 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <errno.h>
|
||||
#include <misc/util.h>
|
||||
#include <assert.h>
|
||||
#include "os/os_mbuf.h"
|
||||
#include "mesh/mesh.h"
|
||||
|
||||
#include <net/buf.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/conn.h>
|
||||
#include <bluetooth/mesh.h>
|
||||
|
||||
#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 <mesh_priv.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+310
-247
File diff suppressed because it is too large
Load Diff
@@ -9,10 +9,6 @@
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <toolchain.h>
|
||||
#include <zephyr/types.h>
|
||||
#include <misc/byteorder.h>
|
||||
#include <misc/util.h>
|
||||
|
||||
#include <tinycrypt/constants.h>
|
||||
#include <tinycrypt/utils.h>
|
||||
@@ -20,13 +16,9 @@
|
||||
#include <tinycrypt/cmac_mode.h>
|
||||
#include <tinycrypt/ccm_mode.h>
|
||||
|
||||
#include <bluetooth/mesh.h>
|
||||
#include <bluetooth/crypto.h>
|
||||
#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],
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,20 +6,21 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include "syscfg/syscfg.h"
|
||||
#if MYNEWT_VAL(BLE_MESH_FRIEND) == 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <zephyr.h>
|
||||
#include <misc/byteorder.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <net/buf.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/mesh.h>
|
||||
|
||||
#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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -6,21 +6,16 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <zephyr/types.h>
|
||||
#include <misc/byteorder.h>
|
||||
#include <misc/util.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/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/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) {
|
||||
|
||||
+36
-35
@@ -6,28 +6,27 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "syscfg/syscfg.h"
|
||||
|
||||
#if MYNEWT_VAL(BLE_MESH_LOW_POWER) == 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <zephyr.h>
|
||||
#include <misc/byteorder.h>
|
||||
|
||||
#include <net/buf.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/mesh.h>
|
||||
|
||||
#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
|
||||
|
||||
+36
-22
@@ -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
|
||||
|
||||
@@ -1,185 +0,0 @@
|
||||
/* Bluetooth Mesh */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <net/buf.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/conn.h>
|
||||
#include <bluetooth/mesh.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
/* Bluetooth Mesh */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -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
|
||||
+101
-104
@@ -6,25 +6,19 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <atomic.h>
|
||||
#include <misc/util.h>
|
||||
#include <misc/byteorder.h>
|
||||
|
||||
#include <net/buf.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/conn.h>
|
||||
#include <bluetooth/mesh.h>
|
||||
#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
|
||||
}
|
||||
|
||||
+208
-178
@@ -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 <stdbool.h>
|
||||
#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
|
||||
|
||||
+211
-185
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
+390
-243
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/* Bluetooth Mesh */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <bluetooth/mesh.h>
|
||||
|
||||
#include "common/log.h"
|
||||
|
||||
#include "mesh.h"
|
||||
#include "test.h"
|
||||
|
||||
int bt_mesh_test(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -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
|
||||
@@ -6,24 +6,18 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <misc/util.h>
|
||||
#include <misc/byteorder.h>
|
||||
|
||||
#include <net/buf.h>
|
||||
#include "mesh/mesh.h"
|
||||
#include "mesh_priv.h"
|
||||
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/mesh.h>
|
||||
|
||||
#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]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
+78
-19
@@ -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
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user