Bluetooth: Mesh: Improve Low Power establishment procedure
Add some automated policies for starting LPN establishment and make it possible to perform the establishment in a "low power" way, i.e. switching to low duty-cycle already when starting to send Friend Requests. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
f38482a8fd
commit
b95d70c3f0
5 changed files with 164 additions and 35 deletions
|
@ -186,6 +186,42 @@ config BT_MESH_LOW_POWER
|
||||||
Enable this option to be able to act as a Low Power Node.
|
Enable this option to be able to act as a Low Power Node.
|
||||||
|
|
||||||
if BT_MESH_LOW_POWER
|
if BT_MESH_LOW_POWER
|
||||||
|
|
||||||
|
config BT_MESH_LPN_ESTABLISHMENT
|
||||||
|
bool "Perform Friendship establishment using low power"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Perform the Friendship establishment using low power, with
|
||||||
|
the help of a reduced scan duty cycle. The downside of this
|
||||||
|
is that the node may miss out on messages intended for it
|
||||||
|
until it has successfully set up Friendship with a Friend
|
||||||
|
node.
|
||||||
|
|
||||||
|
config BT_MESH_LPN_AUTO
|
||||||
|
bool "Automatically start looking for Friend nodes once provisioned"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Automatically enable LPN functionality once provisioned and start
|
||||||
|
looking for Friend nodes. If this option is disabled LPN mode
|
||||||
|
needs to be manually enabled by calling bt_mesh_lpn_set(true).
|
||||||
|
|
||||||
|
config BT_MESH_LPN_AUTO_TIMEOUT
|
||||||
|
int "Time from last received message before going to LPN mode"
|
||||||
|
default 15
|
||||||
|
range 0 3600
|
||||||
|
depends on BT_MESH_LPN_AUTO
|
||||||
|
help
|
||||||
|
Time in seconds from the last received message, that the node
|
||||||
|
will wait before starting to look for Friend nodes.
|
||||||
|
|
||||||
|
config BT_MESH_LPN_RETRY_TIMEOUT
|
||||||
|
int "Retry timeout for Friend requests"
|
||||||
|
default 8
|
||||||
|
range 1 3600
|
||||||
|
help
|
||||||
|
Time in seconds between Friend Requests, if a previous Friend
|
||||||
|
Request did not receive any acceptable Friend Offers.
|
||||||
|
|
||||||
config BT_MESH_LPN_RSSI_FACTOR
|
config BT_MESH_LPN_RSSI_FACTOR
|
||||||
int "RSSIFactor, used in the Friend Offer Delay calculation"
|
int "RSSIFactor, used in the Friend Offer Delay calculation"
|
||||||
range 0 3
|
range 0 3
|
||||||
|
|
|
@ -26,12 +26,21 @@
|
||||||
#include "beacon.h"
|
#include "beacon.h"
|
||||||
#include "lpn.h"
|
#include "lpn.h"
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_MESH_LPN_AUTO)
|
||||||
|
#define LPN_AUTO_TIMEOUT K_SECONDS(CONFIG_BT_MESH_LPN_AUTO_TIMEOUT)
|
||||||
|
#else
|
||||||
|
#define LPN_AUTO_TIMEOUT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define LPN_RECV_DELAY CONFIG_BT_MESH_LPN_RECV_DELAY
|
#define LPN_RECV_DELAY CONFIG_BT_MESH_LPN_RECV_DELAY
|
||||||
#define SCAN_LATENCY min(CONFIG_BT_MESH_LPN_SCAN_LATENCY, \
|
#define SCAN_LATENCY min(CONFIG_BT_MESH_LPN_SCAN_LATENCY, \
|
||||||
LPN_RECV_DELAY)
|
LPN_RECV_DELAY)
|
||||||
|
|
||||||
#define FRIEND_REQ_RETRY_TIMEOUT K_SECONDS(5)
|
#define FRIEND_REQ_RETRY_TIMEOUT K_SECONDS(CONFIG_BT_MESH_LPN_RETRY_TIMEOUT)
|
||||||
#define FRIEND_REQ_TIMEOUT (K_MSEC(100) + K_SECONDS(1))
|
|
||||||
|
#define FRIEND_REQ_WAIT K_MSEC(100)
|
||||||
|
#define FRIEND_REQ_SCAN K_SECONDS(1)
|
||||||
|
#define FRIEND_REQ_TIMEOUT (FRIEND_REQ_WAIT + FRIEND_REQ_SCAN)
|
||||||
|
|
||||||
#define POLL_RETRY_TIMEOUT K_MSEC(100)
|
#define POLL_RETRY_TIMEOUT K_MSEC(100)
|
||||||
|
|
||||||
|
@ -59,12 +68,14 @@ static const char *state2str(int state)
|
||||||
return "disabled";
|
return "disabled";
|
||||||
case BT_MESH_LPN_CLEAR:
|
case BT_MESH_LPN_CLEAR:
|
||||||
return "clear";
|
return "clear";
|
||||||
|
case BT_MESH_LPN_TIMER:
|
||||||
|
return "timer";
|
||||||
case BT_MESH_LPN_ENABLED:
|
case BT_MESH_LPN_ENABLED:
|
||||||
return "enabled";
|
return "enabled";
|
||||||
|
case BT_MESH_LPN_REQ_WAIT:
|
||||||
|
return "req wait";
|
||||||
case BT_MESH_LPN_WAIT_OFFER:
|
case BT_MESH_LPN_WAIT_OFFER:
|
||||||
return "wait offer";
|
return "wait offer";
|
||||||
case BT_MESH_LPN_ESTABLISHING:
|
|
||||||
return "establishing";
|
|
||||||
case BT_MESH_LPN_ESTABLISHED:
|
case BT_MESH_LPN_ESTABLISHED:
|
||||||
return "established";
|
return "established";
|
||||||
case BT_MESH_LPN_RECV_DELAY:
|
case BT_MESH_LPN_RECV_DELAY:
|
||||||
|
@ -133,7 +144,7 @@ static void clear_friendship(bool disable)
|
||||||
{
|
{
|
||||||
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
|
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
|
||||||
|
|
||||||
if (lpn->state >= BT_MESH_LPN_ESTABLISHED) {
|
if (lpn->established) {
|
||||||
send_friend_clear();
|
send_friend_clear();
|
||||||
lpn->disable = disable;
|
lpn->disable = disable;
|
||||||
return;
|
return;
|
||||||
|
@ -152,6 +163,7 @@ static void clear_friendship(bool disable)
|
||||||
lpn->queue_size = 0;
|
lpn->queue_size = 0;
|
||||||
lpn->disable = 0;
|
lpn->disable = 0;
|
||||||
lpn->sent_req = 0;
|
lpn->sent_req = 0;
|
||||||
|
lpn->established = 0;
|
||||||
|
|
||||||
/* Set this to 1 to force group subscription when the next
|
/* Set this to 1 to force group subscription when the next
|
||||||
* Friendship is created, in case lpn->groups doesn't get
|
* Friendship is created, in case lpn->groups doesn't get
|
||||||
|
@ -170,13 +182,20 @@ static void clear_friendship(bool disable)
|
||||||
|
|
||||||
static void friend_req_sent(struct net_buf *buf, int err)
|
static void friend_req_sent(struct net_buf *buf, int err)
|
||||||
{
|
{
|
||||||
|
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
BT_ERR("Sending Friend Request failed (err %d)", err);
|
BT_ERR("Sending Friend Request failed (err %d)", err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpn_set_state(BT_MESH_LPN_WAIT_OFFER);
|
if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
|
||||||
k_delayed_work_submit(&bt_mesh.lpn.timer, FRIEND_REQ_TIMEOUT);
|
k_delayed_work_submit(&lpn->timer, FRIEND_REQ_WAIT);
|
||||||
|
lpn_set_state(BT_MESH_LPN_REQ_WAIT);
|
||||||
|
} else {
|
||||||
|
k_delayed_work_submit(&lpn->timer, FRIEND_REQ_TIMEOUT);
|
||||||
|
lpn_set_state(BT_MESH_LPN_WAIT_OFFER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int send_friend_req(void)
|
static int send_friend_req(void)
|
||||||
|
@ -264,16 +283,16 @@ static void req_sent(struct net_buf *buf, int err)
|
||||||
|
|
||||||
lpn->req_attempts++;
|
lpn->req_attempts++;
|
||||||
|
|
||||||
if (lpn->state == BT_MESH_LPN_ESTABLISHING) {
|
if (lpn->established || IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
|
||||||
k_delayed_work_submit(&lpn->timer,
|
|
||||||
LPN_RECV_DELAY + lpn->recv_win);
|
|
||||||
} else { /* Established Friendship */
|
|
||||||
lpn_set_state(BT_MESH_LPN_RECV_DELAY);
|
lpn_set_state(BT_MESH_LPN_RECV_DELAY);
|
||||||
/* We start scanning a bit early to elimitate risk of missing
|
/* We start scanning a bit early to elimitate risk of missing
|
||||||
* response data due to HCI and other latencies.
|
* response data due to HCI and other latencies.
|
||||||
*/
|
*/
|
||||||
k_delayed_work_submit(&lpn->timer,
|
k_delayed_work_submit(&lpn->timer,
|
||||||
LPN_RECV_DELAY - SCAN_LATENCY);
|
LPN_RECV_DELAY - SCAN_LATENCY);
|
||||||
|
} else {
|
||||||
|
k_delayed_work_submit(&lpn->timer,
|
||||||
|
LPN_RECV_DELAY + lpn->recv_win);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,12 +345,14 @@ void bt_mesh_lpn_disable(void)
|
||||||
|
|
||||||
int bt_mesh_lpn_set(bool enable)
|
int bt_mesh_lpn_set(bool enable)
|
||||||
{
|
{
|
||||||
|
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
if (bt_mesh.lpn.state != BT_MESH_LPN_DISABLED) {
|
if (lpn->state != BT_MESH_LPN_DISABLED) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (bt_mesh.lpn.state == BT_MESH_LPN_DISABLED) {
|
if (lpn->state == BT_MESH_LPN_DISABLED) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,9 +368,21 @@ int bt_mesh_lpn_set(bool enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
|
lpn_set_state(BT_MESH_LPN_ENABLED);
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
|
||||||
|
bt_mesh_scan_disable();
|
||||||
|
}
|
||||||
|
|
||||||
send_friend_req();
|
send_friend_req();
|
||||||
} else {
|
} else {
|
||||||
bt_mesh_lpn_disable();
|
if (IS_ENABLED(CONFIG_BT_MESH_LPN_AUTO) &&
|
||||||
|
lpn->state == BT_MESH_LPN_TIMER) {
|
||||||
|
k_delayed_work_cancel(&lpn->timer);
|
||||||
|
lpn_set_state(BT_MESH_LPN_DISABLED);
|
||||||
|
} else {
|
||||||
|
bt_mesh_lpn_disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -374,6 +407,12 @@ void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx)
|
||||||
{
|
{
|
||||||
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
|
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
|
||||||
|
|
||||||
|
if (lpn->state == BT_MESH_LPN_TIMER) {
|
||||||
|
BT_DBG("Restarting establishment timer");
|
||||||
|
k_delayed_work_submit(&lpn->timer, LPN_AUTO_TIMEOUT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) {
|
if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) {
|
||||||
BT_WARN("Unexpected message withouth a preceding Poll");
|
BT_WARN("Unexpected message withouth a preceding Poll");
|
||||||
return;
|
return;
|
||||||
|
@ -452,7 +491,6 @@ int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx,
|
||||||
}
|
}
|
||||||
|
|
||||||
lpn->counter++;
|
lpn->counter++;
|
||||||
lpn_set_state(BT_MESH_LPN_ESTABLISHING);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -614,6 +652,32 @@ static bool sub_update(u8_t op)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void update_timeout(struct bt_mesh_lpn *lpn)
|
||||||
|
{
|
||||||
|
lpn->sent_req = 0;
|
||||||
|
|
||||||
|
if (lpn->established) {
|
||||||
|
BT_WARN("No response from Friend during ReceiveWindow");
|
||||||
|
bt_mesh_scan_disable();
|
||||||
|
lpn_set_state(BT_MESH_LPN_ESTABLISHED);
|
||||||
|
k_delayed_work_submit(&lpn->timer, POLL_RETRY_TIMEOUT);
|
||||||
|
} else {
|
||||||
|
if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
|
||||||
|
bt_mesh_scan_disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpn->req_attempts < 6) {
|
||||||
|
BT_WARN("Retrying first Friend Poll");
|
||||||
|
if (send_friend_poll() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BT_ERR("Timed out waiting for first Friend Update");
|
||||||
|
clear_friendship(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void lpn_timeout(struct k_work *work)
|
static void lpn_timeout(struct k_work *work)
|
||||||
{
|
{
|
||||||
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
|
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
|
||||||
|
@ -628,26 +692,30 @@ static void lpn_timeout(struct k_work *work)
|
||||||
case BT_MESH_LPN_CLEAR:
|
case BT_MESH_LPN_CLEAR:
|
||||||
clear_friendship(bt_mesh.lpn.disable);
|
clear_friendship(bt_mesh.lpn.disable);
|
||||||
break;
|
break;
|
||||||
|
case BT_MESH_LPN_TIMER:
|
||||||
|
BT_DBG("Starting to look for Friend nodes");
|
||||||
|
lpn_set_state(BT_MESH_LPN_ENABLED);
|
||||||
|
if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
|
||||||
|
bt_mesh_scan_disable();
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
case BT_MESH_LPN_ENABLED:
|
case BT_MESH_LPN_ENABLED:
|
||||||
send_friend_req();
|
send_friend_req();
|
||||||
break;
|
break;
|
||||||
|
case BT_MESH_LPN_REQ_WAIT:
|
||||||
|
bt_mesh_scan_enable();
|
||||||
|
k_delayed_work_submit(&lpn->timer, FRIEND_REQ_SCAN);
|
||||||
|
lpn_set_state(BT_MESH_LPN_WAIT_OFFER);
|
||||||
|
break;
|
||||||
case BT_MESH_LPN_WAIT_OFFER:
|
case BT_MESH_LPN_WAIT_OFFER:
|
||||||
BT_WARN("No acceptable Friend Offers received");
|
BT_WARN("No acceptable Friend Offers received");
|
||||||
|
if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
|
||||||
|
bt_mesh_scan_disable();
|
||||||
|
}
|
||||||
lpn->counter++;
|
lpn->counter++;
|
||||||
lpn_set_state(BT_MESH_LPN_ENABLED);
|
lpn_set_state(BT_MESH_LPN_ENABLED);
|
||||||
k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT);
|
k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT);
|
||||||
break;
|
break;
|
||||||
case BT_MESH_LPN_ESTABLISHING:
|
|
||||||
if (lpn->req_attempts < 6) {
|
|
||||||
BT_WARN("Retrying first Friend Poll");
|
|
||||||
if (send_friend_poll() == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BT_ERR("Timed out waiting for first Friend Update");
|
|
||||||
clear_friendship(false);
|
|
||||||
break;
|
|
||||||
case BT_MESH_LPN_ESTABLISHED:
|
case BT_MESH_LPN_ESTABLISHED:
|
||||||
if (lpn->req_attempts < REQ_ATTEMPTS(lpn)) {
|
if (lpn->req_attempts < REQ_ATTEMPTS(lpn)) {
|
||||||
u8_t req = lpn->sent_req;
|
u8_t req = lpn->sent_req;
|
||||||
|
@ -674,10 +742,7 @@ static void lpn_timeout(struct k_work *work)
|
||||||
lpn->recv_win + SCAN_LATENCY);
|
lpn->recv_win + SCAN_LATENCY);
|
||||||
break;
|
break;
|
||||||
case BT_MESH_LPN_WAIT_UPDATE:
|
case BT_MESH_LPN_WAIT_UPDATE:
|
||||||
BT_WARN("No response from Friend during ReceiveWindow");
|
update_timeout(lpn);
|
||||||
bt_mesh_scan_disable();
|
|
||||||
lpn_set_state(BT_MESH_LPN_ESTABLISHED);
|
|
||||||
k_delayed_work_submit(&lpn->timer, POLL_RETRY_TIMEOUT);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
__ASSERT(0, "Unhandled LPN state");
|
__ASSERT(0, "Unhandled LPN state");
|
||||||
|
@ -826,7 +891,7 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx,
|
||||||
bt_mesh_beacon_ivu_initiator(false);
|
bt_mesh_beacon_ivu_initiator(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lpn->state == BT_MESH_LPN_ESTABLISHING) {
|
if (!lpn->established) {
|
||||||
/* This is normally checked on the transport layer, however
|
/* This is normally checked on the transport layer, however
|
||||||
* in this state we're also still accepting master
|
* in this state we're also still accepting master
|
||||||
* credentials so we need to ensure the right ones (Friend
|
* credentials so we need to ensure the right ones (Friend
|
||||||
|
@ -837,6 +902,8 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lpn->established = 1;
|
||||||
|
|
||||||
BT_INFO("Friendship established with 0x%04x", lpn->frnd);
|
BT_INFO("Friendship established with 0x%04x", lpn->frnd);
|
||||||
|
|
||||||
/* Set initial poll timeout */
|
/* Set initial poll timeout */
|
||||||
|
@ -888,10 +955,20 @@ int bt_mesh_lpn_init(void)
|
||||||
{
|
{
|
||||||
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
|
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
|
||||||
|
|
||||||
|
BT_DBG("");
|
||||||
|
|
||||||
k_delayed_work_init(&lpn->timer, lpn_timeout);
|
k_delayed_work_init(&lpn->timer, lpn_timeout);
|
||||||
|
|
||||||
if (lpn->state == BT_MESH_LPN_ENABLED) {
|
if (lpn->state == BT_MESH_LPN_ENABLED) {
|
||||||
|
if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
|
||||||
|
bt_mesh_scan_disable();
|
||||||
|
}
|
||||||
|
|
||||||
send_friend_req();
|
send_friend_req();
|
||||||
|
} else if (IS_ENABLED(CONFIG_BT_MESH_LPN_AUTO)) {
|
||||||
|
BT_DBG("Waiting %u ms for messages", LPN_AUTO_TIMEOUT);
|
||||||
|
lpn_set_state(BT_MESH_LPN_TIMER);
|
||||||
|
k_delayed_work_submit(&lpn->timer, LPN_AUTO_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -18,7 +18,7 @@ int bt_mesh_lpn_friend_sub_cfm(struct bt_mesh_net_rx *rx,
|
||||||
static inline bool bt_mesh_lpn_established(void)
|
static inline bool bt_mesh_lpn_established(void)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_BT_MESH_LOW_POWER)
|
#if defined(CONFIG_BT_MESH_LOW_POWER)
|
||||||
return (bt_mesh.lpn.state >= BT_MESH_LPN_ESTABLISHED);
|
return bt_mesh.lpn.established;
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,6 +43,15 @@ static inline bool bt_mesh_lpn_waiting_update(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool bt_mesh_lpn_timer(void)
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_BT_MESH_LPN_AUTO)
|
||||||
|
return (bt_mesh.lpn.state == BT_MESH_LPN_TIMER);
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void bt_mesh_lpn_friend_poll(void);
|
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);
|
||||||
|
|
|
@ -126,9 +126,10 @@ struct bt_mesh_lpn {
|
||||||
enum __packed {
|
enum __packed {
|
||||||
BT_MESH_LPN_DISABLED, /* LPN feature is disabled */
|
BT_MESH_LPN_DISABLED, /* LPN feature is disabled */
|
||||||
BT_MESH_LPN_CLEAR, /* Clear in progress */
|
BT_MESH_LPN_CLEAR, /* Clear in progress */
|
||||||
|
BT_MESH_LPN_TIMER, /* Waiting for auto timer expiry */
|
||||||
BT_MESH_LPN_ENABLED, /* LPN enabled, but no Friend */
|
BT_MESH_LPN_ENABLED, /* LPN enabled, but no Friend */
|
||||||
|
BT_MESH_LPN_REQ_WAIT, /* Wait before scanning for offers */
|
||||||
BT_MESH_LPN_WAIT_OFFER, /* Friend Req sent */
|
BT_MESH_LPN_WAIT_OFFER, /* Friend Req sent */
|
||||||
BT_MESH_LPN_ESTABLISHING, /* First Friend Poll sent */
|
|
||||||
BT_MESH_LPN_ESTABLISHED, /* Friendship established */
|
BT_MESH_LPN_ESTABLISHED, /* Friendship established */
|
||||||
BT_MESH_LPN_RECV_DELAY, /* Poll sent, waiting ReceiveDelay */
|
BT_MESH_LPN_RECV_DELAY, /* Poll sent, waiting ReceiveDelay */
|
||||||
BT_MESH_LPN_WAIT_UPDATE, /* Waiting for Update or message */
|
BT_MESH_LPN_WAIT_UPDATE, /* Waiting for Update or message */
|
||||||
|
@ -154,7 +155,8 @@ struct bt_mesh_lpn {
|
||||||
u8_t groups_changed:1, /* Friend Subscription List needs updating */
|
u8_t groups_changed:1, /* Friend Subscription List needs updating */
|
||||||
pending_poll:1, /* Poll to be sent after subscription */
|
pending_poll:1, /* Poll to be sent after subscription */
|
||||||
disable:1, /* Disable LPN after clearing */
|
disable:1, /* Disable LPN after clearing */
|
||||||
fsn:1; /* Friend Sequence Number */
|
fsn:1, /* Friend Sequence Number */
|
||||||
|
established:1; /* Friendship established */
|
||||||
|
|
||||||
/* Friend Queue Size */
|
/* Friend Queue Size */
|
||||||
u8_t queue_size;
|
u8_t queue_size;
|
||||||
|
|
|
@ -1289,12 +1289,17 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx)
|
||||||
* we still need to go through the actual sending to the bearer and
|
* we still need to go through the actual sending to the bearer and
|
||||||
* wait for ReceiveDelay before transitioning to WAIT_UPDATE state.
|
* wait for ReceiveDelay before transitioning to WAIT_UPDATE state.
|
||||||
*
|
*
|
||||||
|
* Another situation where we want to notify the LPN state machine
|
||||||
|
* is if it's configured to use an automatic Friendship establishment
|
||||||
|
* timer, in which case we want to reset the timer at this point.
|
||||||
|
*
|
||||||
* ENOENT is a special condition that's only used to indicate that
|
* ENOENT is a special condition that's only used to indicate that
|
||||||
* the Transport OpCode was invalid, in which case we should ignore
|
* the Transport OpCode was invalid, in which case we should ignore
|
||||||
* the PDU completely, as per MESH/NODE/FRND/LPN/BI-02-C.
|
* the PDU completely, as per MESH/NODE/FRND/LPN/BI-02-C.
|
||||||
*/
|
*/
|
||||||
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && err != -ENOENT &&
|
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && err != -ENOENT &&
|
||||||
bt_mesh_lpn_established() && bt_mesh_lpn_waiting_update()) {
|
(bt_mesh_lpn_timer() ||
|
||||||
|
(bt_mesh_lpn_established() && bt_mesh_lpn_waiting_update()))) {
|
||||||
bt_mesh_lpn_msg_received(rx);
|
bt_mesh_lpn_msg_received(rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue