ble_mesh: add ble mesh friend node event

This commit is contained in:
lly 2019-09-17 16:56:52 +08:00
parent fdfe59d369
commit c6286529eb
5 changed files with 112 additions and 7 deletions

View file

@ -578,6 +578,7 @@ if BLE_MESH
config BLE_MESH_FRIEND
bool "Support for acting as a Friend Node"
select BLE_MESH_NODE
help
Enable this option to be able to act as a Friend Node.

View file

@ -1246,6 +1246,8 @@ typedef enum {
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_FRIEND_FRIENDSHIP_ESTABLISH_EVT, /*!< Friend Node establishes friendship event */
ESP_BLE_MESH_FRIEND_FRIENDSHIP_TERMINATE_EVT, /*!< Friend Node terminates friendship event */
ESP_BLE_MESH_PROV_EVT_MAX,
} esp_ble_mesh_prov_cb_event_t;
@ -1536,7 +1538,7 @@ typedef union {
uint8_t hops; /*!< Heartbeat hops (InitTTL - RxTTL + 1) */
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 */
/*
/**
* @brief ESP_BLE_MESH_LPN_ENABLE_COMP_EVT
*/
struct ble_mesh_lpn_enable_comp_param {
@ -1566,6 +1568,26 @@ typedef union {
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 */
/**
* @brief ESP_BLE_MESH_FRIEND_FRIENDSHIP_ESTABLISH_EVT
*/
struct ble_mesh_friend_friendship_establish_param {
uint16_t lpn_addr; /*!< Low Power Node unciast address */
} frnd_friendship_establish; /*!< Event parameter of ESP_BLE_MESH_FRIEND_FRIENDSHIP_ESTABLISH_EVT */
/**
* @brief ESP_BLE_MESH_FRIEND_FRIENDSHIP_TERMINATE_EVT
*/
struct ble_mesh_friend_friendship_terminate_param {
uint16_t lpn_addr; /*!< Low Power Node unicast address */
/** This enum value is the reason of friendship termination on the friend node side */
enum {
ESP_BLE_MESH_FRND_FRIENDSHIP_TERMINATE_ESTABLISH_FAIL, /*!< Friend Offer has been sent, but Friend Offer is not received within 1 second, friendship fails to be established */
ESP_BLE_MESH_FRND_FRIENDSHIP_TERMINATE_POLL_TIMEOUT, /*!< Friendship is established, PollTimeout timer expires and no Friend Poll/Sub Add/Sub Remove is received */
ESP_BLE_MESH_FRND_FRIENDSHIP_TERMINATE_RECV_FRND_REQ, /*!< Receive Friend Request from existing Low Power Node */
ESP_BLE_MESH_FRND_FRIENDSHIP_TERMINATE_RECV_FRND_CLEAR, /*!< Receive Friend Clear from other friend node */
ESP_BLE_MESH_FRND_FRIENDSHIP_TERMINATE_DISABLE, /*!< Friend feature disabled or corresponding NetKey is deleted */
} reason; /*!< Friendship terminated reason */
} frnd_friendship_terminate; /*!< Event parameter of ESP_BLE_MESH_FRIEND_FRIENDSHIP_TERMINATE_EVT */
} esp_ble_mesh_prov_cb_param_t;
/**

View file

@ -599,6 +599,43 @@ static void btc_ble_mesh_lpn_cb(u16_t friend_addr, bool established)
}
#endif /* CONFIG_BLE_MESH_LOW_POWER */
#if CONFIG_BLE_MESH_FRIEND
void btc_ble_mesh_friend_cb(bool establish, u16_t lpn_addr, u8_t reason)
{
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 (!BLE_MESH_ADDR_IS_UNICAST(lpn_addr)) {
LOG_ERROR("%s, Not a unicast address", __func__);
return;
}
if (establish) {
mesh_param.frnd_friendship_establish.lpn_addr = lpn_addr;
act = ESP_BLE_MESH_FRIEND_FRIENDSHIP_ESTABLISH_EVT;
} else {
mesh_param.frnd_friendship_terminate.lpn_addr = lpn_addr;
mesh_param.frnd_friendship_terminate.reason = reason;
act = ESP_BLE_MESH_FRIEND_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_FRIEND */
#endif /* CONFIG_BLE_MESH_NODE */
static void btc_ble_mesh_prov_register_complete_cb(int err_code)
@ -1259,6 +1296,9 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
#if CONFIG_BLE_MESH_LOW_POWER
bt_mesh_lpn_set_cb(btc_ble_mesh_lpn_cb);
#endif /* CONFIG_BLE_MESH_LOW_POWER */
#if CONFIG_BLE_MESH_FRIEND
bt_mesh_friend_set_cb(btc_ble_mesh_friend_cb);
#endif /* CONFIG_BLE_MESH_FRIEND */
#endif /* CONFIG_BLE_MESH_NODE */
#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;

View file

@ -65,6 +65,18 @@ static struct friend_adv {
u64_t seq_auth;
} adv_pool[FRIEND_BUF_COUNT];
enum {
BLE_MESH_FRIENDSHIP_TERMINATE_ESTABLISH_FAIL,
BLE_MESH_FRIENDSHIP_TERMINATE_POLL_TIMEOUT,
BLE_MESH_FRIENDSHIP_TERMINATE_RECV_FRND_REQ,
BLE_MESH_FRIENDSHIP_TERMINATE_RECV_FRND_CLEAR,
BLE_MESH_FRIENDSHIP_TERMINATE_DISABLE,
};
static void (*friend_cb)(bool establish, u16_t lpn_addr, u8_t reason);
static struct bt_mesh_adv *adv_alloc(int id)
{
return &adv_pool[id].adv;
@ -137,7 +149,7 @@ static s32_t recv_delay(struct bt_mesh_friend *frnd)
#endif
}
static void friend_clear(struct bt_mesh_friend *frnd)
static void friend_clear(struct bt_mesh_friend *frnd, u8_t reason)
{
int i;
@ -145,6 +157,12 @@ static void friend_clear(struct bt_mesh_friend *frnd)
k_delayed_work_cancel(&frnd->timer);
if (frnd->established) {
if (friend_cb) {
friend_cb(false, frnd->lpn, reason);
}
}
friend_cred_del(frnd->net_idx, frnd->lpn);
if (frnd->last) {
@ -189,7 +207,7 @@ void bt_mesh_friend_clear_net_idx(u16_t net_idx)
}
if (net_idx == BLE_MESH_KEY_ANY || frnd->net_idx == net_idx) {
friend_clear(frnd);
friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_DISABLE);
}
}
}
@ -262,7 +280,7 @@ int bt_mesh_friend_clear(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR_CFM, &cfm,
sizeof(cfm), NULL, NULL, NULL);
friend_clear(frnd);
friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_RECV_FRND_CLEAR);
return 0;
}
@ -568,6 +586,9 @@ int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
if (!frnd->established) {
BT_DBG("Friendship established with 0x%04x", frnd->lpn);
frnd->established = 1U;
if (friend_cb) {
friend_cb(true, frnd->lpn, 0);
}
}
if (msg->fsn == frnd->fsn && frnd->last) {
@ -828,7 +849,7 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
frnd = bt_mesh_friend_find(rx->sub->net_idx, rx->ctx.addr, true, false);
if (frnd) {
BT_WARN("%s, Existing LPN re-requesting Friendship", __func__);
friend_clear(frnd);
friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_RECV_FRND_REQ);
goto init_friend;
}
@ -857,6 +878,13 @@ init_friend:
BT_DBG("LPN 0x%04x rssi %d recv_delay %u poll_to %ums",
frnd->lpn, rx->rssi, frnd->recv_delay, frnd->poll_to);
/**
* Spec says:
* After a friendship has been established, if the PreviousAddress field
* of the Friend Request message contains a valid unicast address that is
* not the Friend nodes own unicast address, then the Friend node shall
* begin sending Friend Clear messages to that unicast address.
*/
if (BLE_MESH_ADDR_IS_UNICAST(frnd->clear.frnd) &&
!bt_mesh_elem_find(frnd->clear.frnd)) {
clear_procedure_start(frnd);
@ -1010,14 +1038,14 @@ static void friend_timeout(struct k_work *work)
if (frnd->established && !frnd->pending_req) {
BT_WARN("%s, Friendship lost with 0x%04x", __func__, frnd->lpn);
friend_clear(frnd);
friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_POLL_TIMEOUT);
return;
}
frnd->last = (void *)sys_slist_get(&frnd->queue);
if (!frnd->last) {
BT_WARN("%s, Friendship not established with 0x%04x", __func__, frnd->lpn);
friend_clear(frnd);
friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_ESTABLISH_FAIL);
return;
}
@ -1035,6 +1063,11 @@ send_last:
bt_mesh_adv_send(frnd->last, &buf_sent_cb, frnd);
}
void bt_mesh_friend_set_cb(void (*cb)(bool establish, u16_t lpn_addr, u8_t reason))
{
friend_cb = cb;
}
int bt_mesh_friend_init(void)
{
int i;

View file

@ -581,6 +581,15 @@ int bt_mesh_lpn_poll(void);
*/
void bt_mesh_lpn_set_cb(void (*cb)(u16_t friend_addr, bool established));
/** @brief Register a callback for Friendship changes of friend node.
*
* Registers a callback that will be called whenever Friendship gets
* established or is terminated.
*
* @param cb Function to call when the Friendship status of friend node changes.
*/
void bt_mesh_friend_set_cb(void (*cb)(bool establish, u16_t lpn_addr, u8_t reason));
/**
* @}
*/