ble_mesh: add low power node api and event

This commit is contained in:
lly
2019-09-17 16:32:27 +08:00
parent afc00fb5f5
commit fdfe59d369
8 changed files with 226 additions and 26 deletions

View File

@@ -446,6 +446,7 @@ if BLE_MESH
config BLE_MESH_LOW_POWER config BLE_MESH_LOW_POWER
bool "Support for Low Power features" bool "Support for Low Power features"
select BLE_MESH_NODE
help help
Enable this option to operate as a Low Power Node. If low power consumption Enable this option to operate as a Low Power Node. If low power consumption
is required by a node, this option should be enabled. And once the node is required by a node, this option should be enabled. And once the node
@@ -456,7 +457,7 @@ if BLE_MESH
config BLE_MESH_LPN_ESTABLISHMENT config BLE_MESH_LPN_ESTABLISHMENT
bool "Perform Friendship establishment using low power" bool "Perform Friendship establishment using low power"
default y default n
help help
Perform the Friendship establishment using low power with the help of a 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 reduced scan duty cycle. The downside of this is that the node may miss
@@ -468,7 +469,7 @@ if BLE_MESH
config BLE_MESH_LPN_AUTO config BLE_MESH_LPN_AUTO
bool "Automatically start looking for Friend nodes once provisioned" bool "Automatically start looking for Friend nodes once provisioned"
default y default n
help help
Once provisioned, automatically enable LPN functionality and start looking Once provisioned, automatically enable LPN functionality and start looking
for Friend nodes. If this option is disabled LPN mode needs to be manually for Friend nodes. If this option is disabled LPN mode needs to be manually
@@ -487,8 +488,8 @@ if BLE_MESH
before starting to look for Friend nodes. before starting to look for Friend nodes.
config BLE_MESH_LPN_RETRY_TIMEOUT config BLE_MESH_LPN_RETRY_TIMEOUT
int "Retry timeout for Friend Requests" int "Retry timeout for Friend requests"
default 8 default 6
range 1 3600 range 1 3600
help help
Time in seconds between Friend Requests, if a previous Friend Request did Time in seconds between Friend Requests, if a previous Friend Request did
@@ -569,7 +570,7 @@ if BLE_MESH
config BLE_MESH_LPN_GROUPS config BLE_MESH_LPN_GROUPS
int "Number of groups the LPN can subscribe to" int "Number of groups the LPN can subscribe to"
range 0 16384 range 0 16384
default 8 default 2
help help
Maximum number of groups to which the LPN can subscribe. Maximum number of groups to which the LPN can subscribe.

View File

@@ -15,10 +15,51 @@
#include <stdint.h> #include <stdint.h>
#include "btc/btc_task.h" #include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "esp_err.h" #include "esp_err.h"
#include "btc_ble_mesh_prov.h" #include "btc_ble_mesh_prov.h"
#include "esp_ble_mesh_defs.h" #include "esp_ble_mesh_defs.h"
esp_err_t esp_ble_mesh_lpn_enable(void)
{
btc_msg_t msg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_LPN_ENABLE;
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_lpn_disable(bool force)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_LPN_DISABLE;
arg.lpn_disable.force = force;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_lpn_poll(void)
{
btc_msg_t msg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_LPN_POLL;
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View File

@@ -17,4 +17,38 @@
#include "esp_ble_mesh_defs.h" #include "esp_ble_mesh_defs.h"
/**
* @brief Enable BLE Mesh device LPN functionality.
*
* @note This API enables LPN functionality. Once called, the proper
* Friend Request will be sent.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_lpn_enable(void);
/**
* @brief Disable BLE Mesh device LPN functionality.
*
* @param[in] force: when disabling LPN functionality, use this flag to indicate
* whether directly clear corresponding information or just
* send friend clear to disable it if friendship has already
* been established.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_lpn_disable(bool force);
/**
* @brief LPN tries to poll messages from the Friend Node.
*
* @note Once called, Friend Poll will be sent to the Friend Node.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_lpn_poll(void);
#endif /* _ESP_BLE_MESH_LOW_POWER_API_H_ */ #endif /* _ESP_BLE_MESH_LOW_POWER_API_H_ */

View File

@@ -1241,6 +1241,11 @@ typedef enum {
ESP_BLE_MESH_SET_FAST_PROV_INFO_COMP_EVT, /*!< Set fast provisioning information (e.g. unicast address range, net_idx, etc.) completion event */ ESP_BLE_MESH_SET_FAST_PROV_INFO_COMP_EVT, /*!< Set fast provisioning information (e.g. unicast address range, net_idx, etc.) completion event */
ESP_BLE_MESH_SET_FAST_PROV_ACTION_COMP_EVT, /*!< Set fast provisioning action completion event */ ESP_BLE_MESH_SET_FAST_PROV_ACTION_COMP_EVT, /*!< Set fast provisioning action completion event */
ESP_BLE_MESH_HEARTBEAT_MESSAGE_RECV_EVT, /*!< Receive Heartbeat message event */ ESP_BLE_MESH_HEARTBEAT_MESSAGE_RECV_EVT, /*!< Receive Heartbeat message event */
ESP_BLE_MESH_LPN_ENABLE_COMP_EVT, /*!< Enable Low Power Node completion event */
ESP_BLE_MESH_LPN_DISABLE_COMP_EVT, /*!< Disable Low Power Node completion event */
ESP_BLE_MESH_LPN_POLL_COMP_EVT, /*!< Low Power Node send Friend Poll completion event */
ESP_BLE_MESH_LPN_FRIENDSHIP_ESTABLISH_EVT, /*!< Low Power Node establishes friendship event */
ESP_BLE_MESH_LPN_FRIENDSHIP_TERMINATE_EVT, /*!< Low Power Node terminates friendship event */
ESP_BLE_MESH_PROV_EVT_MAX, ESP_BLE_MESH_PROV_EVT_MAX,
} esp_ble_mesh_prov_cb_event_t; } esp_ble_mesh_prov_cb_event_t;
@@ -1531,6 +1536,36 @@ typedef union {
uint8_t hops; /*!< Heartbeat hops (InitTTL - RxTTL + 1) */ uint8_t hops; /*!< Heartbeat hops (InitTTL - RxTTL + 1) */
uint16_t feature; /*!< Bit field of currently active features of the node */ uint16_t feature; /*!< Bit field of currently active features of the node */
} heartbeat_msg_recv; /*!< Event parameter of ESP_BLE_MESH_HEARTBEAT_MESSAGE_RECV_EVT */ } heartbeat_msg_recv; /*!< Event parameter of ESP_BLE_MESH_HEARTBEAT_MESSAGE_RECV_EVT */
/*
* @brief ESP_BLE_MESH_LPN_ENABLE_COMP_EVT
*/
struct ble_mesh_lpn_enable_comp_param {
int err_code; /*!< Indicate the result of enabling LPN functionality */
} lpn_enable_comp; /*!< Event parameter of ESP_BLE_MESH_LPN_ENABLE_COMP_EVT */
/**
* @brief ESP_BLE_MESH_LPN_DISABLE_COMP_EVT
*/
struct ble_mesh_lpn_disable_comp_param {
int err_code; /*!< Indicate the result of disabling LPN functionality */
} lpn_disable_comp; /*!< Event parameter of ESP_BLE_MESH_LPN_DISABLE_COMP_EVT */
/**
* @brief ESP_BLE_MESH_LPN_POLL_COMP_EVT
*/
struct ble_mesh_lpn_poll_comp_param {
int err_code; /*!< Indicate the result of sending Friend Poll */
} lpn_poll_comp; /*!< Event parameter of ESP_BLE_MESH_LPN_POLL_COMP_EVT */
/**
* @brief ESP_BLE_MESH_LPN_FRIENDSHIP_ESTABLISH_EVT
*/
struct ble_mesh_lpn_friendship_establish_param {
uint16_t friend_addr; /*!< Friend Node unicast address */
} lpn_friendship_establish; /*!< Event parameter of ESP_BLE_MESH_LPN_FRIENDSHIP_ESTABLISH_EVT */
/**
* @brief ESP_BLE_MESH_LPN_FRIENDSHIP_TERMINATE_EVT
*/
struct ble_mesh_lpn_friendship_terminate_param {
uint16_t friend_addr; /*!< Friend Node unicast address */
} lpn_friendship_terminate; /*!< Event parameter of ESP_BLE_MESH_LPN_FRIENDSHIP_TERMINATE_EVT */
} esp_ble_mesh_prov_cb_param_t; } esp_ble_mesh_prov_cb_param_t;
/** /**

View File

@@ -567,6 +567,38 @@ static void btc_ble_mesh_reset_cb(void)
} }
return; return;
} }
#if CONFIG_BLE_MESH_LOW_POWER
static void btc_ble_mesh_lpn_cb(u16_t friend_addr, bool established)
{
esp_ble_mesh_prov_cb_param_t mesh_param = {0};
btc_msg_t msg = {0};
bt_status_t ret;
u8_t act;
LOG_DEBUG("%s", __func__);
if (established) {
mesh_param.lpn_friendship_establish.friend_addr = friend_addr;
act = ESP_BLE_MESH_LPN_FRIENDSHIP_ESTABLISH_EVT;
} else {
mesh_param.lpn_friendship_terminate.friend_addr = friend_addr;
act = ESP_BLE_MESH_LPN_FRIENDSHIP_TERMINATE_EVT;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_PROV;
msg.act = act;
ret = btc_transfer_context(&msg, &mesh_param,
sizeof(esp_ble_mesh_prov_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
LOG_ERROR("%s btc_transfer_context failed", __func__);
}
return;
}
#endif /* CONFIG_BLE_MESH_LOW_POWER */
#endif /* CONFIG_BLE_MESH_NODE */ #endif /* CONFIG_BLE_MESH_NODE */
static void btc_ble_mesh_prov_register_complete_cb(int err_code) static void btc_ble_mesh_prov_register_complete_cb(int err_code)
@@ -1224,6 +1256,9 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
arg->mesh_init.prov->link_close_cb = (esp_ble_mesh_cb_t)btc_ble_mesh_link_close_cb; arg->mesh_init.prov->link_close_cb = (esp_ble_mesh_cb_t)btc_ble_mesh_link_close_cb;
arg->mesh_init.prov->complete_cb = (esp_ble_mesh_cb_t)btc_ble_mesh_complete_cb; arg->mesh_init.prov->complete_cb = (esp_ble_mesh_cb_t)btc_ble_mesh_complete_cb;
arg->mesh_init.prov->reset_cb = (esp_ble_mesh_cb_t)btc_ble_mesh_reset_cb; arg->mesh_init.prov->reset_cb = (esp_ble_mesh_cb_t)btc_ble_mesh_reset_cb;
#if CONFIG_BLE_MESH_LOW_POWER
bt_mesh_lpn_set_cb(btc_ble_mesh_lpn_cb);
#endif /* CONFIG_BLE_MESH_LOW_POWER */
#endif /* CONFIG_BLE_MESH_NODE */ #endif /* CONFIG_BLE_MESH_NODE */
#if CONFIG_BLE_MESH_PROVISIONER #if CONFIG_BLE_MESH_PROVISIONER
arg->mesh_init.prov->provisioner_prov_read_oob_pub_key = (esp_ble_mesh_cb_t)btc_ble_mesh_provisioner_prov_read_oob_pub_key_cb; arg->mesh_init.prov->provisioner_prov_read_oob_pub_key = (esp_ble_mesh_cb_t)btc_ble_mesh_provisioner_prov_read_oob_pub_key_cb;
@@ -1440,6 +1475,20 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
bt_mesh_set_fast_prov_action(arg->set_fast_prov_action.action); bt_mesh_set_fast_prov_action(arg->set_fast_prov_action.action);
break; break;
#endif /* CONFIG_BLE_MESH_FAST_PROV */ #endif /* CONFIG_BLE_MESH_FAST_PROV */
#if CONFIG_BLE_MESH_LOW_POWER
case BTC_BLE_MESH_ACT_LPN_ENABLE:
act = ESP_BLE_MESH_LPN_ENABLE_COMP_EVT;
param.lpn_enable_comp.err_code = bt_mesh_lpn_set(true, false);
break;
case BTC_BLE_MESH_ACT_LPN_DISABLE:
act = ESP_BLE_MESH_LPN_DISABLE_COMP_EVT;
param.lpn_disable_comp.err_code = bt_mesh_lpn_set(false, arg->lpn_disable.force);
break;
case BTC_BLE_MESH_ACT_LPN_POLL:
act = ESP_BLE_MESH_LPN_POLL_COMP_EVT;
param.lpn_poll_comp.err_code = bt_mesh_lpn_poll();
break;
#endif /* CONFIG_BLE_MESH_LOW_POWER */
default: default:
LOG_WARN("%s, Invalid msg->act %d", __func__, msg->act); LOG_WARN("%s, Invalid msg->act %d", __func__, msg->act);
return; return;

View File

@@ -55,6 +55,9 @@ typedef enum {
BTC_BLE_MESH_ACT_PROVISIONER_ADD_LOCAL_NET_KEY, BTC_BLE_MESH_ACT_PROVISIONER_ADD_LOCAL_NET_KEY,
BTC_BLE_MESH_ACT_SET_FAST_PROV_INFO, BTC_BLE_MESH_ACT_SET_FAST_PROV_INFO,
BTC_BLE_MESH_ACT_SET_FAST_PROV_ACTION, BTC_BLE_MESH_ACT_SET_FAST_PROV_ACTION,
BTC_BLE_MESH_ACT_LPN_ENABLE,
BTC_BLE_MESH_ACT_LPN_DISABLE,
BTC_BLE_MESH_ACT_LPN_POLL,
} btc_ble_mesh_prov_act_t; } btc_ble_mesh_prov_act_t;
typedef enum { typedef enum {
@@ -156,6 +159,15 @@ typedef union {
struct ble_mesh_set_fast_prov_action_args { struct ble_mesh_set_fast_prov_action_args {
uint8_t action; uint8_t action;
} set_fast_prov_action; } set_fast_prov_action;
struct ble_mesh_lpn_enable_args {
/* RFU */
} lpn_enable;
struct ble_mesh_lpn_disable_args {
bool force;
} lpn_disable;
struct ble_mesh_lpn_poll_args {
/* RFU */
} lpn_poll;
} btc_ble_mesh_prov_args_t; } btc_ble_mesh_prov_args_t;
typedef union { typedef union {

View File

@@ -555,10 +555,13 @@ bool bt_mesh_iv_update(void);
* from a battery power source. * from a battery power source.
* *
* @param enable true to enable LPN functionality, false to disable it. * @param enable true to enable LPN functionality, false to disable it.
* @param force when disable LPN functionality, use this flag to indicate
* whether directly clear corresponding information or sending
* friend clear to disable it.
* *
* @return Zero on success or (negative) error code otherwise. * @return Zero on success or (negative) error code otherwise.
*/ */
int bt_mesh_lpn_set(bool enable); int bt_mesh_lpn_set(bool enable, bool force);
/** @brief Send out a Friend Poll message. /** @brief Send out a Friend Poll message.
* *

View File

@@ -55,8 +55,11 @@
#define POLL_TIMEOUT_MAX(lpn) ((CONFIG_BLE_MESH_LPN_POLL_TIMEOUT * 100) - \ #define POLL_TIMEOUT_MAX(lpn) ((CONFIG_BLE_MESH_LPN_POLL_TIMEOUT * 100) - \
REQ_RETRY_DURATION(lpn)) REQ_RETRY_DURATION(lpn))
/* Update 4 to 20 for BQB test case MESH/NODE/FRND/LPM/BI-02-C */ /**
#define REQ_ATTEMPTS(lpn) (POLL_TIMEOUT_MAX(lpn) < K_SECONDS(3) ? 2 : 4) * 1. Should use 20 attempts for BQB test case MESH/NODE/FRND/LPM/BI-02-C.
* 2. We should use more specific value for each PollTimeout range.
*/
#define REQ_ATTEMPTS(lpn) (POLL_TIMEOUT_MAX(lpn) < K_SECONDS(3) ? 2 : 6)
#define CLEAR_ATTEMPTS 2 #define CLEAR_ATTEMPTS 2
@@ -72,7 +75,6 @@
static void (*lpn_cb)(u16_t friend_addr, bool established); static void (*lpn_cb)(u16_t friend_addr, bool established);
#if defined(CONFIG_BLE_MESH_DEBUG_LOW_POWER)
static const char *state2str(int state) static const char *state2str(int state)
{ {
switch (state) { switch (state) {
@@ -94,17 +96,16 @@ static const char *state2str(int state)
return "recv delay"; return "recv delay";
case BLE_MESH_LPN_WAIT_UPDATE: case BLE_MESH_LPN_WAIT_UPDATE:
return "wait update"; return "wait update";
case BLE_MESH_LPN_OFFER_RECV:
return "offer recv";
default: default:
return "(unknown)"; return "(unknown)";
} }
} }
#endif /* CONFIG_BLE_MESH_DEBUG_LOW_POWER */
static inline void lpn_set_state(int state) static inline void lpn_set_state(int state)
{ {
#if defined(CONFIG_BLE_MESH_DEBUG_LOW_POWER)
BT_DBG("%s -> %s", state2str(bt_mesh.lpn.state), state2str(state)); BT_DBG("%s -> %s", state2str(bt_mesh.lpn.state), state2str(state));
#endif
bt_mesh.lpn.state = state; bt_mesh.lpn.state = state;
} }
@@ -149,6 +150,8 @@ static inline void group_clear(bt_mesh_atomic_t *target, bt_mesh_atomic_t *sourc
static void clear_friendship(bool force, bool disable); static void clear_friendship(bool force, bool disable);
static bool scan_after_clear;
static void friend_clear_sent(int err, void *user_data) static void friend_clear_sent(int err, void *user_data)
{ {
struct bt_mesh_lpn *lpn = &bt_mesh.lpn; struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
@@ -156,7 +159,10 @@ static void friend_clear_sent(int err, void *user_data)
/* We're switching away from Low Power behavior, so permanently /* We're switching away from Low Power behavior, so permanently
* enable scanning. * enable scanning.
*/ */
bt_mesh_scan_enable(); if (scan_after_clear == false) {
bt_mesh_scan_enable();
scan_after_clear = true;
}
lpn->req_attempts++; lpn->req_attempts++;
@@ -261,6 +267,11 @@ static void clear_friendship(bool force, bool disable)
lpn_set_state(BLE_MESH_LPN_ENABLED); lpn_set_state(BLE_MESH_LPN_ENABLED);
k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT); k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT);
scan_after_clear = false;
if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
bt_mesh_scan_disable();
}
} }
static void friend_req_sent(u16_t duration, int err, void *user_data) static void friend_req_sent(u16_t duration, int err, void *user_data)
@@ -269,6 +280,10 @@ static void friend_req_sent(u16_t duration, int err, void *user_data)
if (err) { if (err) {
BT_ERR("%s, Sending Friend Request failed (err %d)", __func__, err); BT_ERR("%s, Sending Friend Request failed (err %d)", __func__, err);
if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
bt_mesh_scan_enable();
}
return; return;
} }
@@ -322,10 +337,8 @@ static void req_sent(u16_t duration, int err, void *user_data)
{ {
struct bt_mesh_lpn *lpn = &bt_mesh.lpn; struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
#if defined(CONFIG_BLE_MESH_DEBUG_LOW_POWER)
BT_DBG("req 0x%02x duration %u err %d state %s", BT_DBG("req 0x%02x duration %u err %d state %s",
lpn->sent_req, duration, err, state2str(lpn->state)); lpn->sent_req, duration, err, state2str(lpn->state));
#endif
if (err) { if (err) {
BT_ERR("%s, Sending request failed (err %d)", __func__, err); BT_ERR("%s, Sending request failed (err %d)", __func__, err);
@@ -346,6 +359,12 @@ static void req_sent(u16_t duration, int err, void *user_data)
LPN_RECV_DELAY - SCAN_LATENCY); LPN_RECV_DELAY - SCAN_LATENCY);
} else { } else {
lpn_set_state(BLE_MESH_LPN_OFFER_RECV); lpn_set_state(BLE_MESH_LPN_OFFER_RECV);
/**
* Friend Update is replied by Friend Node with TTL set to 0 and Network
* Transmit set to 30ms which will cause the packet easy to be missed.
* Regarding this situation, here we can reduce the duration of receiving
* the first Friend Update.
*/
k_delayed_work_submit(&lpn->timer, k_delayed_work_submit(&lpn->timer,
LPN_RECV_DELAY + duration + LPN_RECV_DELAY + duration +
lpn->recv_win); lpn->recv_win);
@@ -404,7 +423,7 @@ void bt_mesh_lpn_disable(bool force)
clear_friendship(force, true); clear_friendship(force, true);
} }
int bt_mesh_lpn_set(bool enable) int bt_mesh_lpn_set(bool enable, bool force)
{ {
struct bt_mesh_lpn *lpn = &bt_mesh.lpn; struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
@@ -442,7 +461,7 @@ int bt_mesh_lpn_set(bool enable)
k_delayed_work_cancel(&lpn->timer); k_delayed_work_cancel(&lpn->timer);
lpn_set_state(BLE_MESH_LPN_DISABLED); lpn_set_state(BLE_MESH_LPN_DISABLED);
} else { } else {
bt_mesh_lpn_disable(false); bt_mesh_lpn_disable(force);
} }
} }
@@ -543,6 +562,10 @@ int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx,
lpn->counter++; lpn->counter++;
if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
bt_mesh_scan_disable();
}
return 0; return 0;
} }
@@ -737,9 +760,7 @@ static void lpn_timeout(struct k_work *work)
{ {
struct bt_mesh_lpn *lpn = &bt_mesh.lpn; struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
#if defined(CONFIG_BLE_MESH_DEBUG_LOW_POWER)
BT_DBG("state: %s", state2str(lpn->state)); BT_DBG("state: %s", state2str(lpn->state));
#endif
switch (lpn->state) { switch (lpn->state) {
case BLE_MESH_LPN_DISABLED: case BLE_MESH_LPN_DISABLED:
@@ -774,9 +795,15 @@ static void lpn_timeout(struct k_work *work)
k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT); k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT);
break; break;
case BLE_MESH_LPN_OFFER_RECV: case BLE_MESH_LPN_OFFER_RECV:
BT_WARN("No Friend Update received after the first Friend Poll"); if (lpn->req_attempts < 6) {
lpn->sent_req = 0U; BT_WARN("Retrying the first Friend Poll, %d attempts", lpn->req_attempts);
send_friend_poll(); lpn->sent_req = 0U;
send_friend_poll();
break;
}
BT_ERR("Timeout waiting for the first Friend Update");
clear_friendship(true, false);
break; break;
case BLE_MESH_LPN_ESTABLISHED: case BLE_MESH_LPN_ESTABLISHED:
if (lpn->req_attempts < REQ_ATTEMPTS(lpn)) { if (lpn->req_attempts < REQ_ATTEMPTS(lpn)) {
@@ -1047,9 +1074,7 @@ int bt_mesh_lpn_init(void)
k_delayed_work_init(&lpn->timer, lpn_timeout); k_delayed_work_init(&lpn->timer, lpn_timeout);
if (lpn->state == BLE_MESH_LPN_ENABLED) { if (lpn->state == BLE_MESH_LPN_ENABLED) {
if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) { if (!IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
bt_mesh_scan_disable();
} else {
bt_mesh_scan_enable(); bt_mesh_scan_enable();
} }