Bluetooth: Mesh: Fix unable send mesh message when proxy adv pending
When Proxy advertising or PB-GATT Advertising Enabled and use a same advertising sets. As `adv_start` will call multi HCI Command will cause syswork_q yield. At same time, if another thread(BT RX) all `schedule_send` will cause unable send mesh message, because `ADV_FLAG_ACTIVE` was be set, but `ADV_FLAG_PROXY` not set currentlly. Add `ADV_FLAG_SCHEDULE_PENDING` indicate mesh buf has been pendings but not scheduled, so when proxy advertising enable, let's take again, as we can't break or terminated `adv_start`, so we must waiting proxy advertising enabled. Signed-off-by: Lingao Meng <menglingao@xiaomi.com>
This commit is contained in:
parent
3e5812cc5f
commit
8c3b244fe3
1 changed files with 20 additions and 6 deletions
|
@ -33,6 +33,8 @@ enum {
|
||||||
ADV_FLAG_PROXY,
|
ADV_FLAG_PROXY,
|
||||||
/** The send-call has been scheduled. */
|
/** The send-call has been scheduled. */
|
||||||
ADV_FLAG_SCHEDULED,
|
ADV_FLAG_SCHEDULED,
|
||||||
|
/** The send-call has been pending. */
|
||||||
|
ADV_FLAG_SCHEDULE_PENDING,
|
||||||
/** Custom adv params have been set, we need to update the parameters on
|
/** Custom adv params have been set, we need to update the parameters on
|
||||||
* the next send.
|
* the next send.
|
||||||
*/
|
*/
|
||||||
|
@ -53,6 +55,7 @@ struct bt_mesh_ext_adv {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void send_pending_adv(struct k_work *work);
|
static void send_pending_adv(struct k_work *work);
|
||||||
|
static bool schedule_send(struct bt_mesh_ext_adv *adv);
|
||||||
|
|
||||||
static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_main) = {
|
static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_main) = {
|
||||||
.tag = (BT_MESH_LOCAL_ADV |
|
.tag = (BT_MESH_LOCAL_ADV |
|
||||||
|
@ -220,12 +223,19 @@ static void send_pending_adv(struct k_work *work)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) &&
|
if (!IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) ||
|
||||||
(adv->tag & BT_MESH_PROXY_ADV) &&
|
!(adv->tag & BT_MESH_PROXY_ADV)) {
|
||||||
!bt_mesh_adv_gatt_send()) {
|
|
||||||
atomic_set_bit(adv->flags, ADV_FLAG_PROXY);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!bt_mesh_adv_gatt_send()) {
|
||||||
|
atomic_set_bit(adv->flags, ADV_FLAG_PROXY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (atomic_test_and_clear_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING)) {
|
||||||
|
schedule_send(adv);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool schedule_send(struct bt_mesh_ext_adv *adv)
|
static bool schedule_send(struct bt_mesh_ext_adv *adv)
|
||||||
|
@ -244,11 +254,15 @@ static bool schedule_send(struct bt_mesh_ext_adv *adv)
|
||||||
atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE);
|
atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atomic_test_bit(adv->flags, ADV_FLAG_ACTIVE) ||
|
if (atomic_test_bit(adv->flags, ADV_FLAG_ACTIVE)) {
|
||||||
atomic_test_and_set_bit(adv->flags, ADV_FLAG_SCHEDULED)) {
|
atomic_set_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING);
|
||||||
|
return false;
|
||||||
|
} else if (atomic_test_and_set_bit(adv->flags, ADV_FLAG_SCHEDULED)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING);
|
||||||
|
|
||||||
/* The controller will send the next advertisement immediately.
|
/* The controller will send the next advertisement immediately.
|
||||||
* Introduce a delay here to avoid sending the next mesh packet closer
|
* Introduce a delay here to avoid sending the next mesh packet closer
|
||||||
* to the previous packet than what's permitted by the specification.
|
* to the previous packet than what's permitted by the specification.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue