ble_mesh: Fix adv buf unref and link_id in exceptional list

This commit is contained in:
lly 2019-11-26 20:14:31 +08:00
parent 4100f2e84f
commit c354b0993d
7 changed files with 57 additions and 38 deletions

View File

@ -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(&param, &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);
}

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}