Bluetooth: Mesh: Fix proxy advertising handling

Remove inconsistent and sometimes unreliable tracking of what
advertising parameters should be used and when the Node Identity
advertising started. The main change that facilitates this is to have
the Node ID start timestamp as part of the mesh subnet context.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2017-11-27 14:18:05 +02:00 committed by Johan Hedberg
commit 48e6bfaaa7
4 changed files with 27 additions and 22 deletions

View file

@ -2200,6 +2200,7 @@ static void node_identity_set(struct bt_mesh_model *model,
if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
sub->node_id = node_id;
sub->node_id_start = node_id ? k_uptime_get_32() : 0;
bt_mesh_adv_update();
}

View file

@ -467,6 +467,7 @@ int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16],
if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
sub->node_id = BT_MESH_NODE_IDENTITY_RUNNING;
sub->node_id_start = k_uptime_get_32();
} else {
sub->node_id = BT_MESH_NODE_IDENTITY_NOT_SUPPORTED;
}

View file

@ -57,6 +57,7 @@ struct bt_mesh_subnet {
u8_t kr_phase; /* Key Refresh Phase */
u8_t node_id; /* Node Identity State */
u32_t node_id_start; /* Node Identity started timestamp */
u8_t auth[8]; /* Beacon Authentication Value */

View file

@ -56,8 +56,6 @@ static const struct bt_le_adv_param fast_adv_param = {
.interval_max = BT_GAP_ADV_FAST_INT_MAX_2,
};
static const struct bt_le_adv_param *proxy_adv_param = &fast_adv_param;
static bool proxy_adv_enabled;
#if defined(CONFIG_BT_MESH_GATT_PROXY)
@ -67,6 +65,7 @@ static u16_t proxy_ccc_val;
#if defined(CONFIG_BT_MESH_PB_GATT)
static u16_t prov_ccc_val;
static bool prov_fast_adv;
#endif
static struct bt_mesh_proxy_client {
@ -610,7 +609,7 @@ int bt_mesh_proxy_prov_enable(void)
bt_gatt_service_register(&prov_svc);
gatt_svc = MESH_GATT_PROV;
proxy_adv_param = &fast_adv_param;
prov_fast_adv = true;
for (i = 0; i < ARRAY_SIZE(clients); i++) {
if (clients[i].conn) {
@ -914,7 +913,6 @@ static const struct bt_data prov_sd[] = {
#endif /* PB_GATT */
#if defined(CONFIG_BT_MESH_GATT_PROXY)
static u32_t node_id_start;
#define ID_TYPE_NET 0x00
#define ID_TYPE_NODE 0x01
@ -963,7 +961,7 @@ static int node_id_adv(struct bt_mesh_subnet *sub)
memcpy(proxy_svc_data + 3, tmp + 8, 8);
err = bt_le_adv_start(proxy_adv_param, node_id_ad,
err = bt_le_adv_start(&fast_adv_param, node_id_ad,
ARRAY_SIZE(node_id_ad), NULL, 0);
if (err) {
BT_WARN("Failed to advertise using Node ID (err %d)", err);
@ -988,8 +986,8 @@ static int net_id_adv(struct bt_mesh_subnet *sub)
memcpy(proxy_svc_data + 3, sub->keys[sub->kr_flag].net_id, 8);
err = bt_le_adv_start(proxy_adv_param,
net_id_ad, ARRAY_SIZE(net_id_ad), NULL, 0);
err = bt_le_adv_start(&slow_adv_param, net_id_ad,
ARRAY_SIZE(net_id_ad), NULL, 0);
if (err) {
BT_WARN("Failed to advertise using Network ID (err %d)", err);
return err;
@ -1013,28 +1011,23 @@ static s32_t gatt_proxy_advertise(void)
return remaining;
}
if (node_id_start) {
u32_t active = k_uptime_get_32() - node_id_start;
if (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING) {
u32_t active = k_uptime_get_32() - sub->node_id_start;
if (active < NODE_ID_TIMEOUT) {
remaining = NODE_ID_TIMEOUT - active;
BT_DBG("Node ID active for %u ms, %u ms remaining",
active, remaining);
node_id_adv(sub);
} else {
sub->node_id = BT_MESH_NODE_IDENTITY_STOPPED;
node_id_start = 0;
sub->node_id_start = 0;
BT_DBG("Node ID stopped");
}
}
if (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING) {
proxy_adv_param = &fast_adv_param;
if (node_id_adv(sub) == 0 && !node_id_start) {
node_id_start = k_uptime_get_32();
remaining = NODE_ID_TIMEOUT;
}
} else if (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED) {
proxy_adv_param = &slow_adv_param;
if (sub->node_id == BT_MESH_NODE_IDENTITY_STOPPED &&
bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED) {
net_id_adv(sub);
}
@ -1052,12 +1045,21 @@ s32_t bt_mesh_proxy_adv_start(void)
#if defined(CONFIG_BT_MESH_PB_GATT)
if (!bt_mesh_is_provisioned()) {
if (bt_le_adv_start(proxy_adv_param,
prov_ad, ARRAY_SIZE(prov_ad),
const struct bt_le_adv_param *param;
if (prov_fast_adv) {
param = &fast_adv_param;
} else {
param = &slow_adv_param;
}
if (bt_le_adv_start(param, prov_ad, ARRAY_SIZE(prov_ad),
prov_sd, ARRAY_SIZE(prov_sd)) == 0) {
proxy_adv_enabled = true;
if (proxy_adv_param == &fast_adv_param) {
proxy_adv_param = &slow_adv_param;
/* Advertise 60 seconds using fast interval */
if (prov_fast_adv) {
prov_fast_adv = false;
return K_SECONDS(60);
}
}