232 lines
6.0 KiB
C
232 lines
6.0 KiB
C
/* Bluetooth Mesh */
|
|
|
|
/*
|
|
* Copyright (c) 2018 Nordic Semiconductor ASA
|
|
* Copyright (c) 2017 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include "adaptation.h"
|
|
#include "net/buf.h"
|
|
#include "adv.h"
|
|
#include "mesh_net.h"
|
|
#include "foundation.h"
|
|
#include "beacon.h"
|
|
#include "prov.h"
|
|
#include "proxy.h"
|
|
|
|
#define LOG_TAG "[MESH-adv]"
|
|
/* #define LOG_INFO_ENABLE */
|
|
#define LOG_DEBUG_ENABLE
|
|
#define LOG_WARN_ENABLE
|
|
#define LOG_ERROR_ENABLE
|
|
#define LOG_DUMP_ENABLE
|
|
#include "mesh_log.h"
|
|
|
|
#if MESH_RAM_AND_CODE_MAP_DETAIL
|
|
#ifdef SUPPORT_MS_EXTENSIONS
|
|
#pragma bss_seg(".ble_mesh_adv_bss")
|
|
#pragma data_seg(".ble_mesh_adv_data")
|
|
#pragma const_seg(".ble_mesh_adv_const")
|
|
#pragma code_seg(".ble_mesh_adv_code")
|
|
#endif
|
|
#else /* MESH_RAM_AND_CODE_MAP_DETAIL */
|
|
#pragma bss_seg(".ble_mesh_bss")
|
|
#pragma data_seg(".ble_mesh_data")
|
|
#pragma const_seg(".ble_mesh_const")
|
|
#pragma code_seg(".ble_mesh_code")
|
|
#endif /* MESH_RAM_AND_CODE_MAP_DETAIL */
|
|
|
|
NET_BUF_POOL_DEFINE(adv_buf_pool, CONFIG_BT_MESH_ADV_BUF_COUNT,
|
|
BT_MESH_ADV_DATA_SIZE, BT_MESH_ADV_USER_DATA_SIZE, NULL);
|
|
|
|
extern void newbuf_replace(struct net_buf_pool *pool);
|
|
|
|
#if NET_BUF_USE_MALLOC
|
|
static struct bt_mesh_adv *adv_pool;
|
|
#else
|
|
static struct bt_mesh_adv adv_pool[CONFIG_BT_MESH_ADV_BUF_COUNT];
|
|
#endif /* NET_BUF_USE_MALLOC */
|
|
|
|
static struct bt_mesh_adv *adv_alloc(int id)
|
|
{
|
|
return &adv_pool[id];
|
|
}
|
|
|
|
static inline void adv_send_start(u16_t duration, int err,
|
|
const struct bt_mesh_send_cb *cb,
|
|
void *cb_data)
|
|
{
|
|
if (cb && cb->start) {
|
|
cb->start(duration, err, cb_data);
|
|
}
|
|
}
|
|
|
|
static inline void adv_send_end(int err, const struct bt_mesh_send_cb *cb,
|
|
void *cb_data)
|
|
{
|
|
if (cb && cb->end) {
|
|
cb->end(err, cb_data);
|
|
}
|
|
}
|
|
|
|
struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *pool,
|
|
bt_mesh_adv_alloc_t get_id,
|
|
enum bt_mesh_adv_type type,
|
|
u8_t xmit, s32_t timeout)
|
|
{
|
|
struct bt_mesh_adv *adv;
|
|
struct net_buf *buf;
|
|
|
|
buf = net_buf_alloc(pool, timeout);
|
|
if (!buf) {
|
|
return NULL;
|
|
}
|
|
|
|
adv = get_id(net_buf_id(buf));
|
|
BT_MESH_ADV(buf) = adv;
|
|
|
|
(void)memset(adv, 0, sizeof(*adv));
|
|
|
|
adv->type = type;
|
|
adv->xmit = xmit;
|
|
|
|
#if MESH_ADAPTATION_OPTIMIZE
|
|
buf->__buf += BT_MESH_ADV_DATA_HEAD_SIZE;
|
|
buf->data = buf->__buf;
|
|
#endif /* MESH_ADAPTATION_OPTIMIZE */
|
|
|
|
BT_INFO("alloc buf addr=0x%x", buf);
|
|
|
|
return buf;
|
|
}
|
|
|
|
struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit,
|
|
s32_t timeout)
|
|
{
|
|
#if CONFIG_BUF_REPLACE_EN
|
|
if (0 == adv_buf_pool.free_count) {
|
|
newbuf_replace(&adv_buf_pool);
|
|
}
|
|
#endif /* CONFIG_BUF_REPLACE_EN */
|
|
|
|
return bt_mesh_adv_create_from_pool(&adv_buf_pool, adv_alloc, type,
|
|
xmit, timeout);
|
|
}
|
|
|
|
static void bt_mesh_scan_cb(const bt_addr_le_t *addr, s8_t rssi,
|
|
u8_t adv_type, struct net_buf_simple *buf)
|
|
{
|
|
if (adv_type != BT_LE_ADV_NONCONN_IND) {
|
|
return;
|
|
}
|
|
|
|
/* BT_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len)); */
|
|
|
|
while (buf->len > 1) {
|
|
struct net_buf_simple_state state;
|
|
u8_t len, type;
|
|
|
|
len = net_buf_simple_pull_u8(buf);
|
|
/* Check for early termination */
|
|
if (len == 0) {
|
|
return;
|
|
}
|
|
|
|
if (len > buf->len) {
|
|
BT_WARN("AD malformed");
|
|
return;
|
|
}
|
|
|
|
net_buf_simple_save(buf, &state);
|
|
|
|
type = net_buf_simple_pull_u8(buf);
|
|
|
|
buf->len = len - 1;
|
|
|
|
switch (type) {
|
|
case BT_DATA_MESH_MESSAGE:
|
|
BT_INFO("\n< ADV-BT_DATA_MESH_MESSAGE >\n");
|
|
bt_mesh_net_recv(buf, rssi, BT_MESH_NET_IF_ADV);
|
|
break;
|
|
#if defined(CONFIG_BT_MESH_PB_ADV)
|
|
case BT_DATA_MESH_PROV:
|
|
BT_INFO("\n< ADV-BT_DATA_MESH_PROV >\n");
|
|
bt_mesh_pb_adv_recv(buf);
|
|
break;
|
|
#endif
|
|
case BT_DATA_MESH_BEACON:
|
|
BT_INFO("\n< ADV-BT_DATA_MESH_BEACON>\n");
|
|
bt_mesh_beacon_recv(buf);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
net_buf_simple_restore(buf, &state);
|
|
net_buf_simple_pull(buf, len);
|
|
}
|
|
}
|
|
|
|
int bt_mesh_scan_enable(void)
|
|
{
|
|
BT_DBG("");
|
|
|
|
return bt_le_scan_start(bt_mesh_scan_cb);
|
|
}
|
|
|
|
int bt_mesh_scan_disable(void)
|
|
{
|
|
BT_DBG("");
|
|
|
|
return bt_le_scan_stop();
|
|
}
|
|
|
|
#if NET_BUF_USE_MALLOC
|
|
|
|
#include "system/malloc.h"
|
|
|
|
void bt_mesh_adv_buf_alloc(void)
|
|
{
|
|
BT_DBG("--func=%s, adv buffer cnt = %d", __FUNCTION__, config_bt_mesh_adv_buf_count);
|
|
|
|
u32 buf_size;
|
|
u32 net_buf_p, net_buf_data_p, adv_pool_p;
|
|
|
|
buf_size = sizeof(struct net_buf) * config_bt_mesh_adv_buf_count;
|
|
BT_DBG("net_buf size=0x%x", buf_size);
|
|
net_buf_data_p = buf_size;
|
|
buf_size += ALIGN_4BYTE(config_bt_mesh_adv_buf_count * BT_MESH_ADV_DATA_SIZE);
|
|
BT_DBG("net_buf_data size=0x%x", ALIGN_4BYTE(config_bt_mesh_adv_buf_count * BT_MESH_ADV_DATA_SIZE));
|
|
adv_pool_p = buf_size;
|
|
buf_size += (sizeof(struct bt_mesh_adv) * config_bt_mesh_adv_buf_count);
|
|
BT_DBG("adv_pool size=0x%x", sizeof(struct bt_mesh_adv) * config_bt_mesh_adv_buf_count);
|
|
|
|
net_buf_p = (u32)malloc(buf_size);
|
|
ASSERT(net_buf_p);
|
|
memset((u8 *)net_buf_p, 0, buf_size);
|
|
|
|
net_buf_data_p += net_buf_p;
|
|
adv_pool_p += net_buf_p;
|
|
|
|
NET_BUF_MALLOC(adv_buf_pool,
|
|
net_buf_p, net_buf_data_p, (struct bt_mesh_adv *)adv_pool_p,
|
|
config_bt_mesh_adv_buf_count);
|
|
|
|
BT_DBG("total buf_size=0x%x", buf_size);
|
|
BT_DBG("net_buf addr=0x%x", net_buf_p);
|
|
BT_DBG("net_buf_data addr=0x%x", net_buf_data_p);
|
|
BT_DBG("adv_pool addr=0x%x", adv_pool_p);
|
|
BT_DBG("*fixed->data_pool=0x%x", *((u32 *)net_buf_fixed_adv_buf_pool.data_pool));
|
|
BT_DBG("net_buf_adv_buf_pool user_data addr=0x%x\r\n", net_buf_adv_buf_pool->user_data);
|
|
}
|
|
|
|
void bt_mesh_adv_buf_free(void)
|
|
{
|
|
free(NET_BUF_FREE(adv_buf_pool));
|
|
}
|
|
|
|
#endif /* NET_BUF_USE_MALLOC */
|
|
|