Bluetooth: Mesh: Introduce public LPN APIs for better control

Many apps, the mesh shell included (due to PTS test requirements)
benefit from exposing LPN state and polling outside of the stack.
Introduce new APIs for these, and add code to the mesh shell module to
take advantage of them.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2017-11-23 09:44:49 +02:00 committed by Johan Hedberg
commit 89030f0906
5 changed files with 95 additions and 28 deletions

View file

@ -278,6 +278,24 @@ int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx,
*/ */
int bt_mesh_lpn_set(bool enable); int bt_mesh_lpn_set(bool enable);
/** @brief Send out a Friend Poll message.
*
* Send a Friend Poll message to the Friend of this node. If there is no
* established Friendship the function will return an error.
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_lpn_poll(void);
/** @brief Register a callback for Friendship changes.
*
* Registers a callback that will be called whenever Friendship gets
* established or is lost.
*
* @param cb Function to call when the Friendship status changes.
*/
void bt_mesh_lpn_set_cb(void (*cb)(u16_t friend_addr, bool established));
/** /**
* @} * @}
*/ */

View file

@ -65,6 +65,8 @@
/* 2 transmissions, 20ms interval */ /* 2 transmissions, 20ms interval */
#define POLL_XMIT BT_MESH_TRANSMIT(1, 20) #define POLL_XMIT BT_MESH_TRANSMIT(1, 20)
static void (*lpn_cb)(u16_t friend_addr, bool established);
#if defined(CONFIG_BT_MESH_DEBUG_LOW_POWER) #if defined(CONFIG_BT_MESH_DEBUG_LOW_POWER)
static const char *state2str(int state) static const char *state2str(int state)
{ {
@ -158,6 +160,8 @@ static void clear_friendship(bool force, bool disable)
{ {
struct bt_mesh_lpn *lpn = &bt_mesh.lpn; struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
BT_DBG("force %u disable %u", force, disable);
if (!force && lpn->established && !lpn->clear_success && if (!force && lpn->established && !lpn->clear_success &&
lpn->req_attempts < CLEAR_ATTEMPTS) { lpn->req_attempts < CLEAR_ATTEMPTS) {
send_friend_clear(); send_friend_clear();
@ -177,6 +181,10 @@ static void clear_friendship(bool force, bool disable)
lpn->old_friend = lpn->frnd; lpn->old_friend = lpn->frnd;
} }
if (lpn_cb && lpn->frnd != BT_MESH_ADDR_UNASSIGNED) {
lpn_cb(lpn->frnd, false);
}
lpn->frnd = BT_MESH_ADDR_UNASSIGNED; lpn->frnd = BT_MESH_ADDR_UNASSIGNED;
lpn->fsn = 0; lpn->fsn = 0;
lpn->req_attempts = 0; lpn->req_attempts = 0;
@ -951,6 +959,10 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx,
BT_INFO("Friendship established with 0x%04x", lpn->frnd); BT_INFO("Friendship established with 0x%04x", lpn->frnd);
if (lpn_cb) {
lpn_cb(lpn->frnd, true);
}
/* Set initial poll timeout */ /* Set initial poll timeout */
lpn->poll_timeout = min(POLL_TIMEOUT_MAX(lpn), K_SECONDS(1)); lpn->poll_timeout = min(POLL_TIMEOUT_MAX(lpn), K_SECONDS(1));
} }
@ -990,10 +1002,20 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx,
return 0; return 0;
} }
void bt_mesh_lpn_friend_poll(void) int bt_mesh_lpn_poll(void)
{ {
if (!bt_mesh.lpn.established) {
return -EAGAIN;
}
BT_DBG("Requesting more messages"); BT_DBG("Requesting more messages");
send_friend_poll();
return send_friend_poll();
}
void bt_mesh_lpn_set_cb(void (*cb)(u16_t friend_addr, bool established))
{
lpn_cb = cb;
} }
int bt_mesh_lpn_init(void) int bt_mesh_lpn_init(void)

View file

@ -52,8 +52,6 @@ static inline bool bt_mesh_lpn_timer(void)
#endif #endif
} }
void bt_mesh_lpn_friend_poll(void);
void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx); void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx);
void bt_mesh_lpn_group_add(u16_t group); void bt_mesh_lpn_group_add(u16_t group);

View file

@ -346,29 +346,6 @@ static const struct bt_mesh_prov prov = {
.input = input, .input = input,
}; };
static int cmd_init(int argc, char *argv[])
{
int err;
err = bt_enable(NULL);
if (err && err != -EALREADY) {
printk("Bluetooth init failed (err %d)\n", err);
return 0;
} else if (!err) {
printk("Bluetooth initialized\n");
}
err = bt_mesh_init(&prov, &comp);
if (err) {
printk("Mesh initialization failed (err %d)\n", err);
}
printk("Mesh initialized\n");
printk("Use \"pb-adv on\" or \"pb-gatt on\" to enable advertising\n");
return 0;
}
static int cmd_reset(int argc, char *argv[]) static int cmd_reset(int argc, char *argv[])
{ {
bt_mesh_reset(); bt_mesh_reset();
@ -420,8 +397,59 @@ static int cmd_lpn(int argc, char *argv[])
return 0; return 0;
} }
static int cmd_poll(int argc, char *argv[])
{
int err;
err = bt_mesh_lpn_poll();
if (err) {
printk("Friend Poll failed (err %d)\n", err);
}
return 0;
}
static void lpn_cb(u16_t friend_addr, bool established)
{
if (established) {
printk("Friendship (as LPN) established to Friend 0x%04x\n",
friend_addr);
} else {
printk("Friendship (as LPN) lost with Friend 0x%04x\n",
friend_addr);
}
}
#endif /* MESH_LOW_POWER */ #endif /* MESH_LOW_POWER */
static int cmd_init(int argc, char *argv[])
{
int err;
err = bt_enable(NULL);
if (err && err != -EALREADY) {
printk("Bluetooth init failed (err %d)\n", err);
return 0;
} else if (!err) {
printk("Bluetooth initialized\n");
}
err = bt_mesh_init(&prov, &comp);
if (err) {
printk("Mesh initialization failed (err %d)\n", err);
}
printk("Mesh initialized\n");
printk("Use \"pb-adv on\" or \"pb-gatt on\" to enable advertising\n");
#if IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)
bt_mesh_lpn_set_cb(lpn_cb);
#endif
return 0;
}
#if defined(CONFIG_BT_MESH_GATT_PROXY) #if defined(CONFIG_BT_MESH_GATT_PROXY)
static int cmd_ident(int argc, char *argv[]) static int cmd_ident(int argc, char *argv[])
{ {
@ -1542,6 +1570,7 @@ static const struct shell_cmd mesh_commands[] = {
{ "provision", cmd_provision, "<NetKeyIndex> <addr> [IVIndex]" }, { "provision", cmd_provision, "<NetKeyIndex> <addr> [IVIndex]" },
#if defined(CONFIG_BT_MESH_LOW_POWER) #if defined(CONFIG_BT_MESH_LOW_POWER)
{ "lpn", cmd_lpn, "<value: off, on>" }, { "lpn", cmd_lpn, "<value: off, on>" },
{ "poll", cmd_poll, NULL },
#endif #endif
#if defined(CONFIG_BT_MESH_GATT_PROXY) #if defined(CONFIG_BT_MESH_GATT_PROXY)
{ "ident", cmd_ident, NULL }, { "ident", cmd_ident, NULL },

View file

@ -383,7 +383,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
} }
if (bt_mesh_lpn_established()) { if (bt_mesh_lpn_established()) {
bt_mesh_lpn_friend_poll(); bt_mesh_lpn_poll();
} }
return 0; return 0;