mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'bugfix/fix_ble_mesh_adv_buf_unref_v4.0' into 'release/v4.0'
ble_mesh: Fix adv buf unref and link_id in exceptional list (v4.0) See merge request espressif/esp-idf!7080
This commit is contained in:
commit
d41c020649
@ -142,6 +142,8 @@ static inline int adv_send(struct net_buf *buf)
|
||||
param.interval_min = ADV_SCAN_UNIT(adv_int);
|
||||
param.interval_max = param.interval_min;
|
||||
|
||||
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
|
||||
|
||||
err = bt_le_adv_start(¶m, &ad, 1, NULL, 0);
|
||||
net_buf_unref(buf);
|
||||
adv_send_start(duration, err, cb, cb_data);
|
||||
@ -273,6 +275,7 @@ static void adv_thread(void *p)
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
bt_mesh_adv_buf_ref_debug(__func__, *buf, 1U, BLE_MESH_BUF_REF_EQUAL);
|
||||
net_buf_unref(*buf);
|
||||
}
|
||||
|
||||
@ -320,6 +323,30 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit,
|
||||
xmit, timeout);
|
||||
}
|
||||
|
||||
void bt_mesh_adv_buf_ref_debug(const char *func, struct net_buf *buf,
|
||||
u8_t ref_cmp, bt_mesh_buf_ref_flag_t flag)
|
||||
{
|
||||
if (buf == NULL || func == NULL || flag >= BLE_MESH_BUF_REF_MAX) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (flag) {
|
||||
case BLE_MESH_BUF_REF_EQUAL:
|
||||
if (buf->ref != ref_cmp) {
|
||||
BT_ERR("Unexpected ref %d in %s, expect to equal to %d", buf->ref, func, ref_cmp);
|
||||
}
|
||||
break;
|
||||
case BLE_MESH_BUF_REF_SMALL:
|
||||
if (buf->ref >= ref_cmp) {
|
||||
BT_ERR("Unexpected ref %d in %s, expect to smaller than %d", buf->ref, func, ref_cmp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_mesh_unref_buf(bt_mesh_msg_t *msg)
|
||||
{
|
||||
struct net_buf *buf;
|
||||
@ -356,6 +383,8 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
|
||||
BLE_MESH_ADV(buf)->cb_data = cb_data;
|
||||
BLE_MESH_ADV(buf)->busy = 1U;
|
||||
|
||||
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
|
||||
|
||||
msg.arg = (void *)net_buf_ref(buf);
|
||||
bt_mesh_task_post(&msg, portMAX_DELAY);
|
||||
}
|
||||
@ -472,7 +501,7 @@ const bt_mesh_addr_t *bt_mesh_pba_get_addr(void)
|
||||
return dev_addr;
|
||||
}
|
||||
|
||||
#if (CONFIG_BLE_MESH_PROVISIONER && COFNIG_BLE_MESH_PB_GATT) || \
|
||||
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
|
||||
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
|
||||
static bool bt_mesh_is_adv_flags_valid(struct net_buf_simple *buf)
|
||||
{
|
||||
@ -575,7 +604,7 @@ static void bt_mesh_adv_srv_data_recv(struct net_buf_simple *buf, const bt_mesh_
|
||||
static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi,
|
||||
u8_t adv_type, struct net_buf_simple *buf)
|
||||
{
|
||||
#if (CONFIG_BLE_MESH_PROVISIONER && COFNIG_BLE_MESH_PB_GATT) || \
|
||||
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
|
||||
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
|
||||
u16_t uuid;
|
||||
#endif
|
||||
@ -649,7 +678,7 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi,
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#if (CONFIG_BLE_MESH_PROVISIONER && COFNIG_BLE_MESH_PB_GATT) || \
|
||||
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
|
||||
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
|
||||
case BLE_MESH_DATA_FLAGS:
|
||||
if (!bt_mesh_is_adv_flags_valid(buf)) {
|
||||
|
@ -63,6 +63,15 @@ typedef struct bt_mesh_adv *(*bt_mesh_adv_alloc_t)(int id);
|
||||
struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit,
|
||||
s32_t timeout);
|
||||
|
||||
typedef enum {
|
||||
BLE_MESH_BUF_REF_EQUAL,
|
||||
BLE_MESH_BUF_REF_SMALL,
|
||||
BLE_MESH_BUF_REF_MAX,
|
||||
} bt_mesh_buf_ref_flag_t;
|
||||
|
||||
void bt_mesh_adv_buf_ref_debug(const char *func, struct net_buf *buf,
|
||||
u8_t ref_cmp, bt_mesh_buf_ref_flag_t flag);
|
||||
|
||||
struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *pool,
|
||||
bt_mesh_adv_alloc_t get_id,
|
||||
enum bt_mesh_adv_type type,
|
||||
|
@ -1894,7 +1894,7 @@ int bt_mesh_update_exceptional_list(u8_t sub_code, u8_t type, void *info)
|
||||
BT_ERR("%s, NULL Provisioning Link ID", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(value, info, sizeof(u32_t));
|
||||
sys_memcpy_swap(value, info, sizeof(u32_t));
|
||||
}
|
||||
|
||||
BT_DBG("%s, %s type 0x%x", __func__, sub_code ? "Remove" : "Add", type);
|
||||
|
@ -168,7 +168,10 @@ static void friend_clear(struct bt_mesh_friend *frnd, u8_t reason)
|
||||
if (frnd->last) {
|
||||
/* Cancel the sending if necessary */
|
||||
if (frnd->pending_buf) {
|
||||
bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 2U, BLE_MESH_BUF_REF_EQUAL);
|
||||
BLE_MESH_ADV(frnd->last)->busy = 0U;
|
||||
} else {
|
||||
bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 1U, BLE_MESH_BUF_REF_EQUAL);
|
||||
}
|
||||
|
||||
net_buf_unref(frnd->last);
|
||||
|
@ -260,14 +260,9 @@ static void free_segments(void)
|
||||
}
|
||||
|
||||
link.tx.buf[i] = NULL;
|
||||
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
|
||||
/* Mark as canceled */
|
||||
BLE_MESH_ADV(buf)->busy = 0U;
|
||||
/** Changed by Espressif. Add this to avoid buf->ref is 2 which will
|
||||
* cause lack of buf.
|
||||
*/
|
||||
if (buf->ref > 1) {
|
||||
buf->ref = 1;
|
||||
}
|
||||
net_buf_unref(buf);
|
||||
}
|
||||
}
|
||||
@ -1311,7 +1306,7 @@ static void link_open(struct prov_rx *rx, struct net_buf_simple *buf)
|
||||
BT_DBG("Resending link ack");
|
||||
bearer_ctl_send(LINK_ACK, NULL, 0);
|
||||
} else {
|
||||
BT_WARN("Ignoring bearer open: link already active");
|
||||
BT_INFO("Ignoring bearer open: link already active");
|
||||
}
|
||||
|
||||
return;
|
||||
@ -1436,19 +1431,11 @@ static void gen_prov_cont(struct prov_rx *rx, struct net_buf_simple *buf)
|
||||
BT_DBG("len %u, seg_index %u", buf->len, seg);
|
||||
|
||||
if (!link.rx.seg && link.rx.prev_id == rx->xact_id) {
|
||||
BT_WARN("Resending ack");
|
||||
BT_INFO("Resending ack");
|
||||
gen_prov_ack_send(rx->xact_id);
|
||||
return;
|
||||
}
|
||||
|
||||
/* An issue here:
|
||||
* If the Transaction Start PDU is lost and the device receives corresponding
|
||||
* Transaction Continuation PDU fist, this will trigger the following error -
|
||||
* handling code to be executed and the device must wait for the timeout of
|
||||
* PB-ADV provisioning procedure. Then another provisioning procedure can be
|
||||
* started (link.rx.id will be reset after each provisioning PDU is received
|
||||
* completely). This issue also exists in Provisioner.
|
||||
*/
|
||||
if (rx->xact_id != link.rx.id) {
|
||||
BT_WARN("Data for unknown transaction (%u != %u)",
|
||||
rx->xact_id, link.rx.id);
|
||||
@ -1473,7 +1460,7 @@ static void gen_prov_cont(struct prov_rx *rx, struct net_buf_simple *buf)
|
||||
}
|
||||
|
||||
if (!(link.rx.seg & BIT(seg))) {
|
||||
BT_WARN("Ignoring already received segment");
|
||||
BT_INFO("Ignoring already received segment");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1501,12 +1488,12 @@ static void gen_prov_ack(struct prov_rx *rx, struct net_buf_simple *buf)
|
||||
static void gen_prov_start(struct prov_rx *rx, struct net_buf_simple *buf)
|
||||
{
|
||||
if (link.rx.seg) {
|
||||
BT_WARN("Got Start while there are unreceived segments");
|
||||
BT_INFO("Got Start while there are unreceived segments");
|
||||
return;
|
||||
}
|
||||
|
||||
if (link.rx.prev_id == rx->xact_id) {
|
||||
BT_WARN("Resending ack");
|
||||
BT_INFO("Resending ack");
|
||||
gen_prov_ack_send(rx->xact_id);
|
||||
return;
|
||||
}
|
||||
|
@ -1096,14 +1096,9 @@ static void free_segments(const u8_t idx)
|
||||
}
|
||||
|
||||
link[idx].tx.buf[i] = NULL;
|
||||
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
|
||||
/* Mark as canceled */
|
||||
BLE_MESH_ADV(buf)->busy = 0;
|
||||
/** Change by Espressif. Add this to avoid buf->ref is 2 which will
|
||||
* cause lack of buf.
|
||||
*/
|
||||
if (buf->ref > 1) {
|
||||
buf->ref = 1;
|
||||
}
|
||||
BLE_MESH_ADV(buf)->busy = 0U;
|
||||
net_buf_unref(buf);
|
||||
}
|
||||
}
|
||||
@ -2550,7 +2545,7 @@ static void link_ack(const u8_t idx, struct prov_rx *rx, struct net_buf_simple *
|
||||
}
|
||||
|
||||
if (link[idx].expect == PROV_CAPABILITIES) {
|
||||
BT_WARN("%s, Link ACK is already received", __func__);
|
||||
BT_INFO("%s, Link ACK is already received", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2652,7 +2647,7 @@ static void gen_prov_cont(const u8_t idx, struct prov_rx *rx, struct net_buf_sim
|
||||
BT_DBG("len %u, seg_index %u", buf->len, seg);
|
||||
|
||||
if (!link[idx].rx.seg && link[idx].rx.prev_id == rx->xact_id) {
|
||||
BT_WARN("%s, Resending ack", __func__);
|
||||
BT_INFO("%s, Resending ack", __func__);
|
||||
gen_prov_ack_send(idx, rx->xact_id);
|
||||
return;
|
||||
}
|
||||
@ -2683,7 +2678,7 @@ static void gen_prov_cont(const u8_t idx, struct prov_rx *rx, struct net_buf_sim
|
||||
}
|
||||
|
||||
if (!(link[idx].rx.seg & BIT(seg))) {
|
||||
BT_WARN("%s, Ignore already received segment", __func__);
|
||||
BT_INFO("%s, Ignore already received segment", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2736,12 +2731,12 @@ static void gen_prov_ack(const u8_t idx, struct prov_rx *rx, struct net_buf_simp
|
||||
static void gen_prov_start(const u8_t idx, struct prov_rx *rx, struct net_buf_simple *buf)
|
||||
{
|
||||
if (link[idx].rx.seg) {
|
||||
BT_WARN("%s, Get Start while there are unreceived segments", __func__);
|
||||
BT_INFO("%s, Get Start while there are unreceived segments", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (link[idx].rx.prev_id == rx->xact_id) {
|
||||
BT_WARN("%s, Resending ack", __func__);
|
||||
BT_INFO("%s, Resending ack", __func__);
|
||||
gen_prov_ack_send(idx, rx->xact_id);
|
||||
return;
|
||||
}
|
||||
|
@ -205,12 +205,8 @@ static void seg_tx_reset(struct seg_tx *tx)
|
||||
continue;
|
||||
}
|
||||
|
||||
/** Change by Espressif. Add this to avoid buf->ref is 2 which will
|
||||
* cause lack of buf.
|
||||
*/
|
||||
if (tx->seg[i]->ref > 1) {
|
||||
tx->seg[i]->ref = 1;
|
||||
}
|
||||
bt_mesh_adv_buf_ref_debug(__func__, tx->seg[i], 3U, BLE_MESH_BUF_REF_SMALL);
|
||||
BLE_MESH_ADV(tx->seg[i])->busy = 0U;
|
||||
net_buf_unref(tx->seg[i]);
|
||||
tx->seg[i] = NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user