mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-06-05 21:04:49 +00:00
mesh: Add support for OOB info and URI in provisioning data
Until now the OOB info and URI fields in unprovisioned beacons were generally ignored by the implementation. Add fields for these to bt_mesh_prov and make sure to take them into account when encoding advertising data, both for PB-ADV and PB-GATT. For PB-ADV the URI goes out in a separate beacon, whereas for PB-GATT it is placed in the scan response data. X-Original-Commit: e6b7f42e2688c2d4102dea83bf962d2fbc74ac5e
This commit is contained in:
@@ -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 */
|
||||
@@ -356,6 +357,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
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -55,9 +55,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,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,45 @@ 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) {
|
||||
oob_info = prov->oob_info | BT_MESH_PROV_OOB_URI;
|
||||
bt_mesh_s1(prov->uri, uri_hash);
|
||||
} 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;
|
||||
}
|
||||
|
||||
@@ -1540,9 +1540,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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user