Bluetooth: Mesh: Add more flexible APIs for provisioning bearers

Add the ability to track the provisioning bearer through an extra
parameter to link_open/close. Also introduce new public functions to
enable/disable specific provisioning bearers. This also means that one
now needs to explicitly enable provisioning bearers after calling
bt_mesh_init().

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2017-11-13 20:52:26 +02:00 committed by Johan Hedberg
commit 0ef7c6e09a
9 changed files with 167 additions and 38 deletions

View file

@ -34,6 +34,11 @@ typedef enum {
BT_MESH_ENTER_STRING = BIT(3), BT_MESH_ENTER_STRING = BIT(3),
} bt_mesh_input_action_t; } bt_mesh_input_action_t;
typedef enum {
BT_MESH_PROV_ADV = BIT(0),
BT_MESH_PROV_GATT = BIT(1),
} bt_mesh_prov_bearer_t;
struct bt_mesh_prov { struct bt_mesh_prov {
const u8_t *uuid; const u8_t *uuid;
@ -51,14 +56,18 @@ struct bt_mesh_prov {
int (*input)(bt_mesh_input_action_t act, u8_t size); int (*input)(bt_mesh_input_action_t act, u8_t size);
void (*link_open)(bt); void (*link_open)(bt_mesh_prov_bearer_t bearer);
void (*link_close)(void); void (*link_close)(bt_mesh_prov_bearer_t bearer);
void (*complete)(u16_t addr); void (*complete)(u16_t addr);
void (*reset)(void);
}; };
int bt_mesh_input_string(const char *str); int bt_mesh_input_string(const char *str);
int bt_mesh_input_number(u32_t num); int bt_mesh_input_number(u32_t num);
int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers);
int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers);
/** /**
* @} * @}
*/ */

View file

@ -152,6 +152,11 @@ static void prov_complete(u16_t addr)
board_prov_complete(); board_prov_complete();
} }
static void prov_reset(void)
{
bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
}
static const uint8_t dev_uuid[16] = { 0xdd, 0xdd }; static const uint8_t dev_uuid[16] = { 0xdd, 0xdd };
static const struct bt_mesh_prov prov = { static const struct bt_mesh_prov prov = {
@ -160,6 +165,7 @@ static const struct bt_mesh_prov prov = {
.output_actions = BT_MESH_DISPLAY_NUMBER, .output_actions = BT_MESH_DISPLAY_NUMBER,
.output_number = output_number, .output_number = output_number,
.complete = prov_complete, .complete = prov_complete,
.reset = prov_reset,
}; };
static void bt_ready(int err) static void bt_ready(int err)
@ -179,6 +185,8 @@ static void bt_ready(int err)
return; return;
} }
bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
printk("Mesh initialized\n"); printk("Mesh initialized\n");
} }

View file

@ -351,9 +351,6 @@ void bt_mesh_beacon_recv(struct net_buf_simple *buf)
void bt_mesh_beacon_init(void) void bt_mesh_beacon_init(void)
{ {
k_delayed_work_init(&beacon_timer, beacon_send); k_delayed_work_init(&beacon_timer, beacon_send);
/* Start beaconing since we're unprovisioned */
k_work_submit(&beacon_timer.work);
} }
void bt_mesh_beacon_ivu_initiator(bool enable) void bt_mesh_beacon_ivu_initiator(bool enable)

View file

@ -95,7 +95,7 @@ int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx,
void bt_mesh_reset(void) void bt_mesh_reset(void)
{ {
if (!provisioned) { if (!provisioned) {
goto enable_beacon; return;
} }
bt_mesh_comp_unprovision(); bt_mesh_comp_unprovision();
@ -119,25 +119,17 @@ void bt_mesh_reset(void)
bt_mesh_proxy_gatt_disable(); bt_mesh_proxy_gatt_disable();
} }
if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
bt_mesh_proxy_prov_enable();
}
memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key)); memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key));
memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl)); memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl));
provisioned = false; provisioned = false;
enable_beacon: bt_mesh_scan_disable();
if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV)) { bt_mesh_beacon_disable();
/* Make sure we're scanning for provisioning inviations */
bt_mesh_scan_enable(); if (IS_ENABLED(CONFIG_BT_MESH_PROV)) {
/* Enable unprovisioned beacon sending */ bt_mesh_prov_reset();
bt_mesh_beacon_enable();
} else {
bt_mesh_scan_disable();
bt_mesh_beacon_disable();
} }
} }
@ -146,6 +138,50 @@ bool bt_mesh_is_provisioned(void)
return provisioned; return provisioned;
} }
int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers)
{
if (bt_mesh_is_provisioned()) {
return -EALREADY;
}
if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV) &&
(bearers & BT_MESH_PROV_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_BT_MESH_PB_GATT) &&
(bearers & BT_MESH_PROV_GATT)) {
bt_mesh_proxy_prov_enable();
bt_mesh_adv_update();
}
return 0;
}
int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers)
{
if (bt_mesh_is_provisioned()) {
return -EALREADY;
}
if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV) &&
(bearers & BT_MESH_PROV_ADV)) {
bt_mesh_beacon_disable();
bt_mesh_scan_disable();
}
if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) &&
(bearers & BT_MESH_PROV_GATT)) {
bt_mesh_proxy_prov_disable();
bt_mesh_adv_update();
}
return 0;
}
int bt_mesh_init(const struct bt_mesh_prov *prov, int bt_mesh_init(const struct bt_mesh_prov *prov,
const struct bt_mesh_comp *comp) const struct bt_mesh_comp *comp)
{ {
@ -177,16 +213,5 @@ int bt_mesh_init(const struct bt_mesh_prov *prov,
bt_mesh_proxy_init(); bt_mesh_proxy_init();
} }
if (IS_ENABLED(CONFIG_BT_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_BT_MESH_PB_GATT)) {
bt_mesh_proxy_prov_enable();
}
return 0; return 0;
} }

View file

@ -230,7 +230,7 @@ static void reset_link(void)
prov_clear_tx(); prov_clear_tx();
if (prov->link_close) { if (prov->link_close) {
prov->link_close(); prov->link_close(BT_MESH_PROV_ADV);
} }
/* Clear everything except the retransmit delayed work config */ /* Clear everything except the retransmit delayed work config */
@ -1167,7 +1167,7 @@ static void link_open(struct prov_rx *rx, struct net_buf_simple *buf)
} }
if (prov->link_open) { if (prov->link_open) {
prov->link_open(); prov->link_open(BT_MESH_PROV_ADV);
} }
link.id = rx->link_id; link.id = rx->link_id;
@ -1472,7 +1472,7 @@ int bt_mesh_pb_gatt_open(struct bt_conn *conn)
link.expect = PROV_INVITE; link.expect = PROV_INVITE;
if (prov->link_open) { if (prov->link_open) {
prov->link_open(); prov->link_open(BT_MESH_PROV_GATT);
} }
return 0; return 0;
@ -1495,7 +1495,7 @@ int bt_mesh_pb_gatt_close(struct bt_conn *conn)
} }
if (prov->link_close) { if (prov->link_close) {
prov->link_close(); prov->link_close(BT_MESH_PROV_GATT);
} }
bt_conn_unref(link.conn); bt_conn_unref(link.conn);
@ -1558,3 +1558,10 @@ int bt_mesh_prov_init(const struct bt_mesh_prov *prov_info)
return 0; return 0;
} }
void bt_mesh_prov_reset(void)
{
if (prov->reset) {
prov->reset();
}
}

View file

@ -17,3 +17,5 @@ int bt_mesh_pb_gatt_recv(struct bt_conn *conn, struct net_buf_simple *buf);
const u8_t *bt_mesh_prov_get_uuid(void); const u8_t *bt_mesh_prov_get_uuid(void);
int bt_mesh_prov_init(const struct bt_mesh_prov *prov); int bt_mesh_prov_init(const struct bt_mesh_prov *prov);
void bt_mesh_prov_reset(void);

View file

@ -1043,6 +1043,10 @@ s32_t bt_mesh_proxy_adv_start(void)
{ {
BT_DBG(""); BT_DBG("");
if (gatt_svc == MESH_GATT_NONE) {
return K_FOREVER;
}
#if defined(CONFIG_BT_MESH_PB_GATT) #if defined(CONFIG_BT_MESH_PB_GATT)
if (!bt_mesh_is_provisioned()) { if (!bt_mesh_is_provisioned()) {
if (bt_le_adv_start(proxy_adv_param, if (bt_le_adv_start(proxy_adv_param,

View file

@ -73,6 +73,11 @@ static void prov_complete(u16_t addr)
dst = addr; dst = addr;
} }
static void prov_reset(void)
{
printk("The local node has been reset and needs reprovisioning\n");
}
static int output_number(bt_mesh_output_action_t action, uint32_t number) static int output_number(bt_mesh_output_action_t action, uint32_t number)
{ {
printk("OOB Number: %u\n", number); printk("OOB Number: %u\n", number);
@ -168,14 +173,26 @@ static int input(bt_mesh_input_action_t act, u8_t size)
return 0; return 0;
} }
static void link_open(void) static const char *bearer2str(bt_mesh_prov_bearer_t bearer)
{ {
printk("Provisioning link opened\n"); switch (bearer) {
case BT_MESH_PROV_ADV:
return "PB-ADV";
case BT_MESH_PROV_GATT:
return "PB-GATT";
default:
return "unknown";
}
} }
static void link_close(void) static void link_open(bt_mesh_prov_bearer_t bearer)
{ {
printk("Provisioning link closed\n"); printk("Provisioning link opened on %s\n", bearer2str(bearer));
}
static void link_close(bt_mesh_prov_bearer_t bearer)
{
printk("Provisioning link closed on %s\n", bearer2str(bearer));
} }
static const u8_t static_val[] = { static const u8_t static_val[] = {
@ -187,6 +204,7 @@ static const struct bt_mesh_prov prov = {
.link_open = link_open, .link_open = link_open,
.link_close = link_close, .link_close = link_close,
.complete = prov_complete, .complete = prov_complete,
.reset = prov_reset,
.static_val = static_val, .static_val = static_val,
.static_val_len = sizeof(static_val), .static_val_len = sizeof(static_val),
.output_size = 6, .output_size = 6,
@ -660,8 +678,59 @@ static int cmd_hb_sub_set(int argc, char *argv[])
return 0; return 0;
} }
#if defined(CONFIG_BT_MESH_PROV)
static int cmd_pb(bt_mesh_prov_bearer_t bearer, int argc, char *argv[])
{
int err;
if (argc < 2) {
return -EINVAL;
}
if (str2bool(argv[1])) {
err = bt_mesh_prov_enable(bearer);
if (err) {
printk("Failed to enable %s\n (err %d)",
bearer2str(bearer), err);
} else {
printk("%s enabled\n", bearer2str(bearer));
}
} else {
err = bt_mesh_prov_disable(bearer);
if (err) {
printk("Failed to disable %s (err %d)\n",
bearer2str(bearer), err);
} else {
printk("%s disabled\n", bearer2str(bearer));
}
}
return 0;
}
#endif
#if defined(CONFIG_BT_MESH_PB_ADV)
static int cmd_pb_adv(int argc, char *argv[])
{
return cmd_pb(BT_MESH_PROV_ADV, argc, argv);
}
#endif /* CONFIG_BT_MESH_PB_ADV */
#if defined(CONFIG_BT_MESH_PB_GATT)
static int cmd_pb_gatt(int argc, char *argv[])
{
return cmd_pb(BT_MESH_PROV_GATT, argc, argv);
}
#endif /* CONFIG_BT_MESH_PB_GATT */
static const struct shell_cmd mesh_commands[] = { static const struct shell_cmd mesh_commands[] = {
{ "init", cmd_init, NULL }, { "init", cmd_init, NULL },
#if defined(CONFIG_BT_MESH_PB_ADV)
{ "pb-adv", cmd_pb_adv, "<val: off, on>" },
#endif
#if defined(CONFIG_BT_MESH_PB_GATT)
{ "pb-gatt", cmd_pb_gatt, "<val: off, on>" },
#endif
{ "reset", cmd_reset, NULL }, { "reset", cmd_reset, NULL },
{ "input-num", cmd_input_num, "<number>" }, { "input-num", cmd_input_num, "<number>" },
{ "input-str", cmd_input_str, "<string>" }, { "input-str", cmd_input_str, "<string>" },

View file

@ -161,6 +161,11 @@ static void prov_complete(u16_t addr)
board_prov_complete(); board_prov_complete();
} }
static void prov_reset(void)
{
bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
}
static const u8_t dev_uuid[16] = { 0xdd, 0xdd }; static const u8_t dev_uuid[16] = { 0xdd, 0xdd };
static const struct bt_mesh_prov prov = { static const struct bt_mesh_prov prov = {
@ -171,6 +176,7 @@ static const struct bt_mesh_prov prov = {
.output_number = output_number, .output_number = output_number,
#endif #endif
.complete = prov_complete, .complete = prov_complete,
.reset = prov_reset,
}; };
static void bt_ready(int err) static void bt_ready(int err)
@ -190,6 +196,8 @@ static void bt_ready(int err)
return; return;
} }
bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
printk("Mesh initialized\n"); printk("Mesh initialized\n");
} }