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:
Łukasz Rymanowski
2017-09-01 10:24:04 +02:00
parent 57526844e7
commit b5c85dd6b7
42 changed files with 4481 additions and 2203 deletions
+7
View File
@@ -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
+3
View File
@@ -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
+386
View File
@@ -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__ */
+318
View File
@@ -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
+617
View File
@@ -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 */
+38
View File
@@ -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
-377
View File
@@ -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
-21
View File
@@ -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
-15
View File
@@ -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?)
+20 -26
View File
@@ -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;
+40 -21
View File
@@ -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
View File
@@ -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(&param, &ad, 1, NULL, 0);
adv_sent(buf, err);
if (err) {
BT_ERR("Advertising failed: err %d", err);
return;
}
err = bt_le_adv_start(&param, &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
View File
@@ -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
+30 -34
View File
@@ -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;
}
+19 -7
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+41 -49
View File
@@ -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],
+17 -11
View File
@@ -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
+29 -12
View File
@@ -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
+23 -20
View File
@@ -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)
+20 -8
View File
@@ -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
+486
View File
@@ -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
}
+37 -33
View File
@@ -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
View File
@@ -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
View File
@@ -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
-185
View File
@@ -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;
}
+202
View File
@@ -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
View File
@@ -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
View File
@@ -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
File diff suppressed because it is too large Load Diff
+26 -7
View File
@@ -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
File diff suppressed because it is too large Load Diff
+13 -5
View File
@@ -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
-22
View File
@@ -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;
}
-16
View File
@@ -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
+95 -93
View File
@@ -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]);
}
}
+66 -48
View File
@@ -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);
+322
View File
@@ -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
+3
View File
@@ -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
View File
@@ -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
}
/*****************************************************************************
+8
View File
@@ -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