Merge pull request #841 from michal-narajowski/mesh-zephyr-ports

Mesh zephyr ports

X-Original-Commit: 6192e73f2685d55fa950013e2040621a5d619f77
This commit is contained in:
Michał Narajowski
2018-02-27 12:06:19 +01:00
committed by GitHub
12 changed files with 176 additions and 50 deletions
+3
View File
@@ -97,6 +97,7 @@
#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_URI 0x24 /* URI */
#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 */
@@ -286,6 +287,7 @@ 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_sleep(int32_t duration);
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);
@@ -356,6 +358,7 @@ static inline unsigned int find_msb_set(u32_t op)
#define CONFIG_BT_MESH_MODEL_KEY_COUNT MYNEWT_VAL(BLE_MESH_MODEL_KEY_COUNT)
#define CONFIG_BT_MESH_NODE_ID_TIMEOUT MYNEWT_VAL(BLE_MESH_NODE_ID_TIMEOUT)
#define CONFIG_BT_MAX_CONN MYNEWT_VAL(BLE_MAX_CONNECTIONS)
#define CONFIG_BT_DEVICE_NAME "nimble-mesh"
#define printk console_printf
+26
View File
@@ -39,11 +39,37 @@ typedef enum {
BT_MESH_PROV_GATT = BIT(1),
} bt_mesh_prov_bearer_t;
typedef enum {
BT_MESH_PROV_OOB_OTHER = BIT(0),
BT_MESH_PROV_OOB_URI = BIT(1),
BT_MESH_PROV_OOB_2D_CODE = BIT(2),
BT_MESH_PROV_OOB_BAR_CODE = BIT(3),
BT_MESH_PROV_OOB_NFC = BIT(4),
BT_MESH_PROV_OOB_NUMBER = BIT(5),
BT_MESH_PROV_OOB_STRING = BIT(6),
/* 7 - 10 are reserved */
BT_MESH_PROV_OOB_ON_BOX = BIT(11),
BT_MESH_PROV_OOB_IN_BOX = BIT(12),
BT_MESH_PROV_OOB_ON_PAPER = BIT(13),
BT_MESH_PROV_OOB_IN_MANUAL = BIT(14),
BT_MESH_PROV_OOB_ON_DEV = BIT(15),
} bt_mesh_prov_oob_info_t;
/** Provisioning properties & capabilities. */
struct bt_mesh_prov {
/** The UUID that's used when advertising as unprovisioned */
const u8_t *uuid;
/** Optional URI. This will be advertised separately from the
* unprovisioned beacon, however the unprovisioned beacon will
* contain a hash of it so the two can be associated by the
* provisioner.
*/
const char *uri;
/** Out of Band information field. */
bt_mesh_prov_oob_info_t oob_info;
/** Static OOB value */
const u8_t *static_val;
/** Static OOB value length */
+18 -14
View File
@@ -1,6 +1,7 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
@@ -23,20 +24,22 @@
#include "prov.h"
#include "proxy.h"
/* Window and Interval are equal for continuous scanning */
#define MESH_SCAN_INTERVAL 0x10
#define MESH_SCAN_WINDOW 0x10
/* Convert from ms to 0.625ms units */
#define ADV_INT(_ms) ((_ms) * 8 / 5)
#define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5)
/* Window and Interval are equal for continuous scanning */
#define MESH_SCAN_INTERVAL_MS 10
#define MESH_SCAN_WINDOW_MS 10
#define MESH_SCAN_INTERVAL ADV_SCAN_UNIT(MESH_SCAN_INTERVAL_MS)
#define MESH_SCAN_WINDOW ADV_SCAN_UNIT(MESH_SCAN_WINDOW_MS)
/* Pre-5.0 controllers enforce a minimum interval of 100ms
* whereas 5.0+ controllers can go down to 20ms.
*/
#define ADV_INT_DEFAULT K_MSEC(100)
#define ADV_INT_FAST K_MSEC(20)
#define ADV_INT_DEFAULT_MS 100
#define ADV_INT_FAST_MS 20
static s32_t adv_int_min = ADV_INT_DEFAULT;
static s32_t adv_int_min = ADV_INT_DEFAULT_MS;
/* TinyCrypt PRNG consumes a lot of stack space, so we need to have
* an increased call stack whenever it's used.
@@ -55,9 +58,10 @@ 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] = BLE_HS_ADV_TYPE_MESH_PROV,
[BT_MESH_ADV_DATA] = BLE_HS_ADV_TYPE_MESH_MESSAGE,
[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,
[BT_MESH_ADV_URI] = BLE_HS_ADV_TYPE_URI,
};
@@ -96,7 +100,7 @@ static inline void adv_send(struct os_mbuf *buf)
int err;
adv_int = max(adv_int_min, adv->adv_int);
duration = (adv->count + 1) * (adv_int + 10);
duration = MESH_SCAN_WINDOW_MS + (adv->count + 1) * (adv_int + 10);
BT_DBG("buf %p, type %u len %u:", buf, adv->type,
buf->om_len);
@@ -107,7 +111,7 @@ static inline void adv_send(struct os_mbuf *buf)
ad.data_len = buf->om_len;
ad.data = buf->om_data;
param.itvl_min = ADV_INT(adv_int);
param.itvl_min = ADV_SCAN_UNIT(adv_int);
param.itvl_max = param.itvl_min;
param.conn_mode = BLE_GAP_CONN_MODE_NON;
@@ -121,7 +125,7 @@ static inline void adv_send(struct os_mbuf *buf)
BT_DBG("Advertising started. Sleeping %u ms", duration);
os_time_delay(OS_TICKS_PER_SEC * duration / 1000);
k_sleep(K_MSEC(duration));
err = bt_le_adv_stop();
adv_send_end(err, cb, cb_data);
@@ -314,7 +318,7 @@ void bt_mesh_adv_init(void)
/* For BT5 controllers we can have fast advertising interval */
if (ble_hs_hci_get_hci_version() >= BLE_HCI_VER_BCS_5_0) {
adv_int_min = ADV_INT_FAST;
adv_int_min = ADV_INT_FAST_MS;
}
}
+1
View File
@@ -28,6 +28,7 @@ enum bt_mesh_adv_type
BT_MESH_ADV_PROV,
BT_MESH_ADV_DATA,
BT_MESH_ADV_BEACON,
BT_MESH_ADV_URI,
};
typedef void (*bt_mesh_adv_func_t)(struct os_mbuf *buf, u16_t duration,
+36 -4
View File
@@ -150,7 +150,10 @@ static int secure_beacon_send(void)
static int unprovisioned_beacon_send(void)
{
#if (MYNEWT_VAL(BLE_MESH_PB_ADV))
const struct bt_mesh_prov *prov;
u8_t uri_hash[16] = { 0 };
struct os_mbuf *buf;
u16_t oob_info;
BT_DBG("unprovisioned_beacon_send");
@@ -161,15 +164,44 @@ static int unprovisioned_beacon_send(void)
return -ENOBUFS;
}
net_buf_add_u8(buf, BEACON_TYPE_UNPROVISIONED);
net_buf_add_mem(buf, bt_mesh_prov_get_uuid(), 16);
prov = bt_mesh_prov_get();
/* OOB Info (2 bytes) + URI Hash (4 bytes) */
net_buf_add_zeros(buf, 2 + 4);
net_buf_add_u8(buf, BEACON_TYPE_UNPROVISIONED);
net_buf_add_mem(buf, prov->uuid, 16);
if (prov->uri && bt_mesh_s1(prov->uri, uri_hash) == 0) {
oob_info = prov->oob_info | BT_MESH_PROV_OOB_URI;
} else {
oob_info = prov->oob_info;
}
net_buf_add_be16(buf, oob_info);
net_buf_add_mem(buf, uri_hash, 4);
bt_mesh_adv_send(buf, NULL, NULL);
net_buf_unref(buf);
if (prov->uri) {
size_t len;
buf = bt_mesh_adv_create(BT_MESH_ADV_URI, UNPROV_XMIT_COUNT,
UNPROV_XMIT_INT, K_NO_WAIT);
if (!buf) {
BT_ERR("Unable to allocate URI buffer");
return -ENOBUFS;
}
len = strlen(prov->uri);
if (net_buf_tailroom(buf) < len) {
BT_WARN("Too long URI to fit advertising data");
} else {
net_buf_add_mem(buf, prov->uri, len);
bt_mesh_adv_send(buf, NULL, NULL);
}
net_buf_unref(buf);
}
#endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */
return 0;
}
+2 -4
View File
@@ -1132,8 +1132,7 @@ int bt_mesh_cfg_mod_pub_get_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
return -EINVAL;
}
return mod_pub_get(net_idx, addr, elem_addr, mod_id, CID_NVAL,
pub, status);
return mod_pub_get(net_idx, addr, elem_addr, mod_id, cid, pub, status);
}
static int mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr,
@@ -1205,8 +1204,7 @@ int bt_mesh_cfg_mod_pub_set_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
return -EINVAL;
}
return mod_pub_set(net_idx, addr, elem_addr, mod_id, CID_NVAL,
pub, status);
return mod_pub_set(net_idx, addr, elem_addr, mod_id, cid, pub, status);
}
int bt_mesh_cfg_hb_sub_set(u16_t net_idx, u16_t addr,
+8 -4
View File
@@ -44,6 +44,12 @@ static struct os_mempool friend_buf_mempool;
#define FRIEND_ADV(buf) CONTAINER_OF(BT_MESH_ADV(buf), \
struct friend_adv, adv)
/* PDUs from Friend to the LPN should only be transmitted once with the
* smallest possible interval (20ms).
*/
#define FRIEND_XMIT_COUNT 0
#define FRIEND_XMIT_INT 20
struct friend_pdu_info {
u16_t src;
u16_t dst;
@@ -87,15 +93,13 @@ static void discard_buffer(void)
static struct os_mbuf *friend_buf_alloc(u16_t src)
{
u8_t xmit = bt_mesh_net_transmit_get();
struct os_mbuf *buf;
do {
buf = bt_mesh_adv_create_from_pool(&friend_os_mbuf_pool, adv_alloc,
BT_MESH_ADV_DATA,
BT_MESH_TRANSMIT_COUNT(xmit),
BT_MESH_TRANSMIT_INT(xmit),
K_NO_WAIT);
FRIEND_XMIT_COUNT,
FRIEND_XMIT_INT, K_NO_WAIT);
if (!buf) {
discard_buffer();
}
+5
View File
@@ -391,6 +391,11 @@ u32_t k_uptime_get_32(void)
return k_uptime_get();
}
void k_sleep(int32_t duration)
{
os_time_delay(OS_TICKS_PER_SEC * duration / 1000);
}
static uint8_t pub[64];
static uint8_t priv[32];
static bool has_pub = false;
+11 -3
View File
@@ -1179,7 +1179,14 @@ static void link_open(struct prov_rx *rx, struct os_mbuf *buf)
}
if (atomic_test_bit(link.flags, LINK_ACTIVE)) {
BT_WARN("Ignoring bearer open: link already active");
/* Send another link ack if the provisioner missed the last */
if (link.id == rx->link_id && link.expect == PROV_INVITE) {
BT_DBG("Resending link ack");
bearer_ctl_send(LINK_ACK, NULL, 0);
} else {
BT_WARN("Ignoring bearer open: link already active");
}
return;
}
@@ -1470,6 +1477,7 @@ int bt_mesh_pb_gatt_recv(uint16_t conn_handle, struct os_mbuf *buf)
type = net_buf_simple_pull_u8(buf);
if (type != PROV_FAILED && type != link.expect) {
BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect);
prov_send_fail_msg(PROV_ERR_UNEXP_PDU);
return -EINVAL;
}
@@ -1540,9 +1548,9 @@ int bt_mesh_pb_gatt_close(uint16_t conn_handle)
}
#endif /* MYNEWT_VAL(BLE_MESH_PB_GATT) */
const u8_t *bt_mesh_prov_get_uuid(void)
const struct bt_mesh_prov *bt_mesh_prov_get(void)
{
return prov->uuid;
return prov;
}
bool bt_prov_active(void)
+1 -1
View File
@@ -21,7 +21,7 @@ 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);
const struct bt_mesh_prov *bt_mesh_prov_get(void);
int bt_mesh_prov_init(const struct bt_mesh_prov *prov);
+39 -6
View File
@@ -985,10 +985,8 @@ static const struct bt_data prov_ad[] = {
BT_DATA(BT_DATA_SVC_DATA16, prov_svc_data, sizeof(prov_svc_data)),
};
static const struct bt_data prov_sd[] = {
BT_DATA(BT_DATA_NAME_COMPLETE, "mynewtproxy",
(sizeof("mynewtproxy") - 1)),
};
static struct bt_data prov_sd[2];
static size_t prov_sd_len;
#endif /* PB_GATT */
#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY))
@@ -1201,7 +1199,7 @@ s32_t bt_mesh_proxy_adv_start(void)
}
if (bt_le_adv_start(param, prov_ad, ARRAY_SIZE(prov_ad),
prov_sd, ARRAY_SIZE(prov_sd)) == 0) {
prov_sd, prov_sd_len) == 0) {
proxy_adv_enabled = true;
/* Advertise 60 seconds using fast interval */
@@ -1338,7 +1336,42 @@ int bt_mesh_proxy_init(void)
}
#if (MYNEWT_VAL(BLE_MESH_PB_GATT))
memcpy(prov_svc_data + 2, bt_mesh_prov_get_uuid(), 16);
const struct bt_mesh_prov *prov = bt_mesh_prov_get();
size_t name_len = strlen(CONFIG_BT_DEVICE_NAME);
size_t sd_space = 31;
memcpy(prov_svc_data + 2, prov->uuid, 16);
sys_put_be16(prov->oob_info, prov_svc_data + 18);
if (prov->uri) {
size_t uri_len = strlen(prov->uri);
if (uri_len > 29) {
/* There's no way to shorten an URI */
BT_WARN("Too long URI to fit advertising packet");
} else {
prov_sd[0].type = BT_DATA_URI;
prov_sd[0].data_len = uri_len;
prov_sd[0].data = (void *)prov->uri;
sd_space -= 2 + uri_len;
prov_sd_len++;
}
}
if (sd_space > 2 && name_len > 0) {
sd_space -= 2;
if (sd_space < name_len) {
prov_sd[prov_sd_len].type = BT_DATA_NAME_SHORTENED;
prov_sd[prov_sd_len].data_len = sd_space;
} else {
prov_sd[prov_sd_len].type = BT_DATA_NAME_COMPLETE;
prov_sd[prov_sd_len].data_len = name_len;
}
prov_sd[prov_sd_len].data = (void *)CONFIG_BT_DEVICE_NAME;
prov_sd_len++;
}
#endif
resolve_svc_handles();
+26 -14
View File
@@ -46,6 +46,12 @@
/* Number of retransmit attempts (after the initial transmit) per segment */
#define SEG_RETRANSMIT_ATTEMPTS 4
/* "This timer shall be set to a minimum of 200 + 50 * TTL milliseconds.".
* We use 400 since 300 is a common send duration for standard HCI, and we
* need to have a timeout that's bigger than that.
*/
#define SEG_RETRANSMIT_TIMEOUT(tx) (K_MSEC(400) + 50 * (tx)->ttl)
/* How long to wait for available buffers before giving up */
#define BUF_TIMEOUT K_NO_WAIT
@@ -191,7 +197,7 @@ static inline void seg_tx_complete(struct seg_tx *tx, int err)
seg_tx_reset(tx);
}
static void seg_send_start(u16_t duration, int err, void *user_data)
static void seg_first_send_start(u16_t duration, int err, void *user_data)
{
struct seg_tx *tx = user_data;
@@ -200,27 +206,35 @@ static void seg_send_start(u16_t duration, int err, void *user_data)
}
}
static void seg_send_start(u16_t duration, int err, void *user_data)
{
struct seg_tx *tx = user_data;
/* If there's an error in transmitting the 'sent' callback will never
* be called. Make sure that we kick the retransmit timer also in this
* case since otherwise we risk the transmission of becoming stale.
*/
if (err) {
k_delayed_work_submit(&tx->retransmit,
SEG_RETRANSMIT_TIMEOUT(tx));
}
}
static void seg_sent(int err, void *user_data)
{
struct seg_tx *tx = user_data;
s32_t timeout;
/* "This timer shall be set to a minimum of 200 + 50 * TTL
* milliseconds.". We use 400 since 300 is a common send
* duration for standard HCI, and we need to have a timeout
* that's bigger than that.
*/
timeout = K_MSEC(400) + 50 * tx->ttl;
k_delayed_work_submit(&tx->retransmit, timeout);
k_delayed_work_submit(&tx->retransmit,
SEG_RETRANSMIT_TIMEOUT(tx));
}
static const struct bt_mesh_send_cb first_sent_cb = {
.start = seg_send_start,
.start = seg_first_send_start,
.end = seg_sent,
};
static const struct bt_mesh_send_cb seg_sent_cb = {
.start = seg_send_start,
.end = seg_sent,
};
@@ -995,9 +1009,7 @@ static void seg_ack(struct os_event *work)
if (k_uptime_get_32() - rx->last > K_SECONDS(60)) {
BT_WARN("Incomplete timer expired");
send_ack(rx->sub, rx->dst, rx->src, rx->ttl,
&rx->seq_auth, 0, rx->obo);
seg_rx_reset(rx, true);
seg_rx_reset(rx, false);
if (IS_ENABLED(CONFIG_BT_TESTING)) {
bt_test_mesh_trans_incomp_timer_exp();