Bluetooth: Mesh: Add delay for Proxy Service registration

When settings_load() is not called from system workqueue, but still
called from a cooperative thread, rescheduling during the settings
loading can wake up system workqueue and try to register the Mesh
Proxy Service, which can not be allowed yet. This is the case for bsim
tests.

Postpone registering the service with some small timeout.

Signed-off-by: Pavel Vasilyev <pavel.vasilyev@nordicsemi.no>
This commit is contained in:
Pavel Vasilyev 2023-07-25 15:58:31 +02:00 committed by Fabio Baltieri
commit ad0ea14b2f

View file

@ -36,6 +36,9 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_mesh_gatt);
#define PROXY_SVC_INIT_TIMEOUT K_MSEC(10)
#define PROXY_SVC_REG_ATTEMPTS 5
/* Interval to update random value in (10 minutes).
*
* Defined in the Bluetooth Mesh Specification v1.1, Section 7.2.2.2.4.
@ -887,10 +890,24 @@ static struct bt_gatt_attr proxy_attrs[] = {
};
static struct bt_gatt_service proxy_svc = BT_GATT_SERVICE(proxy_attrs);
static void svc_reg_work_handler(struct k_work *work);
static struct k_work_delayable svc_reg_work = Z_WORK_DELAYABLE_INITIALIZER(svc_reg_work_handler);
static uint32_t svc_reg_attempts;
static void svc_reg_work_handler(struct k_work *work)
{
(void)bt_gatt_service_register(&proxy_svc);
int err;
err = bt_gatt_service_register(&proxy_svc);
if ((err == -EINVAL) && ((--svc_reg_attempts) > 0)) {
/* settings_load() didn't finish yet. Try again. */
(void)k_work_schedule(&svc_reg_work, PROXY_SVC_INIT_TIMEOUT);
return;
} else if (err) {
LOG_ERR("Unable to register Mesh Proxy Service (err %d)", err);
return;
}
service_registered = true;
for (int i = 0; i < ARRAY_SIZE(clients); i++) {
@ -902,8 +919,6 @@ static void svc_reg_work_handler(struct k_work *work)
bt_mesh_adv_gatt_update();
}
static struct k_work svc_reg_work = Z_WORK_INITIALIZER(svc_reg_work_handler);
int bt_mesh_proxy_gatt_enable(void)
{
LOG_DBG("");
@ -916,7 +931,8 @@ int bt_mesh_proxy_gatt_enable(void)
return -EBUSY;
}
return k_work_submit(&svc_reg_work);
svc_reg_attempts = PROXY_SVC_REG_ATTEMPTS;
return k_work_schedule(&svc_reg_work, PROXY_SVC_INIT_TIMEOUT);
}
void bt_mesh_proxy_gatt_disconnect(void)