2019-01-07 02:16:47 -05:00
|
|
|
/*
|
2021-10-26 04:24:54 -04:00
|
|
|
* SPDX-FileCopyrightText: 2016 Intel Corporation
|
|
|
|
* SPDX-FileCopyrightText: 2016 Wind River Systems, Inc.
|
|
|
|
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
2019-01-07 02:16:47 -05:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include "osi/hash_map.h"
|
|
|
|
#include "osi/alarm.h"
|
|
|
|
#include "osi/hash_functions.h"
|
|
|
|
|
2023-08-28 04:09:37 -04:00
|
|
|
#include "mesh/config.h"
|
2023-08-25 02:28:44 -04:00
|
|
|
#include "mesh/common.h"
|
2019-01-07 02:16:47 -05:00
|
|
|
|
|
|
|
static hash_map_t *bm_alarm_hash_map;
|
2023-08-28 04:09:37 -04:00
|
|
|
static const size_t BLE_MESH_ALARM_HASH_MAP_SIZE = 20 + CONFIG_BLE_MESH_PBA_SAME_TIME +
|
|
|
|
CONFIG_BLE_MESH_PBG_SAME_TIME;
|
2019-01-07 02:16:47 -05:00
|
|
|
|
|
|
|
typedef struct alarm_t {
|
|
|
|
/* timer id point to here */
|
|
|
|
esp_timer_handle_t alarm_hdl;
|
|
|
|
osi_alarm_callback_t cb;
|
|
|
|
void *cb_data;
|
|
|
|
int64_t deadline_us;
|
|
|
|
} osi_alarm_t;
|
|
|
|
|
2020-12-07 04:03:11 -05:00
|
|
|
int64_t k_uptime_get(void)
|
2019-01-07 02:16:47 -05:00
|
|
|
{
|
2020-12-07 04:03:11 -05:00
|
|
|
/* k_uptime_get_32 is in in milliseconds,
|
2019-01-07 02:16:47 -05:00
|
|
|
* but esp_timer_get_time is in microseconds
|
|
|
|
*/
|
|
|
|
return (esp_timer_get_time() / 1000);
|
|
|
|
}
|
|
|
|
|
2020-12-07 04:03:11 -05:00
|
|
|
uint32_t k_uptime_get_32(void)
|
2019-01-07 02:16:47 -05:00
|
|
|
{
|
2020-12-07 04:03:11 -05:00
|
|
|
/* k_uptime_get_32 is in in milliseconds,
|
2019-01-07 02:16:47 -05:00
|
|
|
* but esp_timer_get_time is in microseconds
|
|
|
|
*/
|
2020-12-07 04:03:11 -05:00
|
|
|
return (uint32_t)(esp_timer_get_time() / 1000);
|
2019-01-07 02:16:47 -05:00
|
|
|
}
|
|
|
|
|
2020-03-30 06:24:59 -04:00
|
|
|
void bt_mesh_timer_init(void)
|
2019-01-07 02:16:47 -05:00
|
|
|
{
|
2023-08-28 04:09:37 -04:00
|
|
|
bm_alarm_hash_map = hash_map_new(BLE_MESH_ALARM_HASH_MAP_SIZE,
|
2019-01-07 02:16:47 -05:00
|
|
|
hash_function_pointer, NULL,
|
|
|
|
(data_free_fn)osi_alarm_free, NULL);
|
2020-07-04 06:35:08 -04:00
|
|
|
__ASSERT(bm_alarm_hash_map, "Failed to create hash map");
|
2020-01-19 05:57:13 -05:00
|
|
|
}
|
|
|
|
|
2020-10-15 22:19:31 -04:00
|
|
|
#if CONFIG_BLE_MESH_DEINIT
|
2020-03-30 06:24:59 -04:00
|
|
|
void bt_mesh_timer_deinit(void)
|
2020-01-19 05:57:13 -05:00
|
|
|
{
|
|
|
|
if (bm_alarm_hash_map) {
|
|
|
|
hash_map_free(bm_alarm_hash_map);
|
|
|
|
bm_alarm_hash_map = NULL;
|
|
|
|
}
|
2019-01-07 02:16:47 -05:00
|
|
|
}
|
2020-10-15 22:19:31 -04:00
|
|
|
#endif /* CONFIG_BLE_MESH_DEINIT */
|
2019-01-07 02:16:47 -05:00
|
|
|
|
2020-05-27 00:26:25 -04:00
|
|
|
int k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler)
|
2019-01-07 02:16:47 -05:00
|
|
|
{
|
|
|
|
osi_alarm_t *alarm = NULL;
|
|
|
|
|
2020-01-19 05:57:13 -05:00
|
|
|
if (!work || !bm_alarm_hash_map) {
|
|
|
|
BT_ERR("%s, Invalid parameter", __func__);
|
2020-05-27 00:26:25 -04:00
|
|
|
return -EINVAL;
|
2020-01-19 05:57:13 -05:00
|
|
|
}
|
2019-01-07 02:16:47 -05:00
|
|
|
|
|
|
|
k_work_init(&work->work, handler);
|
|
|
|
|
2020-01-19 05:57:13 -05:00
|
|
|
bt_mesh_alarm_lock();
|
2019-01-07 02:16:47 -05:00
|
|
|
|
|
|
|
alarm = hash_map_get(bm_alarm_hash_map, work);
|
2023-08-28 04:09:37 -04:00
|
|
|
if (alarm) {
|
|
|
|
BT_ERR("Init, alarm already exists");
|
|
|
|
bt_mesh_alarm_unlock();
|
|
|
|
return -EEXIST;
|
|
|
|
}
|
|
|
|
|
|
|
|
alarm = osi_alarm_new("bt_mesh", (osi_alarm_callback_t)handler, (void *)&work->work, 0);
|
2019-01-07 02:16:47 -05:00
|
|
|
if (alarm == NULL) {
|
2023-08-28 04:09:37 -04:00
|
|
|
BT_ERR("Init, alarm not created");
|
|
|
|
bt_mesh_alarm_unlock();
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!hash_map_set(bm_alarm_hash_map, work, (void *)alarm)) {
|
|
|
|
BT_ERR("Init, alarm not set");
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_unlock();
|
2023-08-28 04:09:37 -04:00
|
|
|
return -EIO;
|
2019-01-07 02:16:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Just init the work timer only, don't start it.
|
|
|
|
osi_alarm_cancel(alarm);
|
2023-08-28 04:09:37 -04:00
|
|
|
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_unlock();
|
2023-08-28 04:09:37 -04:00
|
|
|
|
2020-05-27 00:26:25 -04:00
|
|
|
return 0;
|
2019-01-07 02:16:47 -05:00
|
|
|
}
|
|
|
|
|
2020-12-07 04:03:11 -05:00
|
|
|
int k_delayed_work_submit(struct k_delayed_work *work, int32_t delay)
|
2019-01-07 02:16:47 -05:00
|
|
|
{
|
2023-08-28 04:09:37 -04:00
|
|
|
osi_alarm_t *alarm = NULL;
|
|
|
|
|
2020-01-19 05:57:13 -05:00
|
|
|
if (!work || !bm_alarm_hash_map) {
|
|
|
|
BT_ERR("%s, Invalid parameter", __func__);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2019-01-07 02:16:47 -05:00
|
|
|
|
2023-08-28 04:09:37 -04:00
|
|
|
/* If delay is 0, call the corresponding timeout handler. */
|
|
|
|
if (delay == 0) {
|
|
|
|
k_work_submit(&work->work);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_lock();
|
2023-08-28 04:09:37 -04:00
|
|
|
|
|
|
|
alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
|
2019-01-07 02:16:47 -05:00
|
|
|
if (alarm == NULL) {
|
2020-07-04 06:35:08 -04:00
|
|
|
BT_WARN("Submit, alarm not found");
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_unlock();
|
2019-01-07 02:16:47 -05:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cancel the alarm first, before start the alarm.
|
|
|
|
osi_alarm_cancel(alarm);
|
|
|
|
osi_alarm_set(alarm, delay);
|
2023-08-28 04:09:37 -04:00
|
|
|
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_unlock();
|
2023-08-28 04:09:37 -04:00
|
|
|
|
2019-01-07 02:16:47 -05:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-12-07 04:03:11 -05:00
|
|
|
int k_delayed_work_submit_periodic(struct k_delayed_work *work, int32_t period)
|
2019-10-12 02:41:21 -04:00
|
|
|
{
|
2023-08-28 04:09:37 -04:00
|
|
|
osi_alarm_t *alarm = NULL;
|
|
|
|
|
2020-01-19 05:57:13 -05:00
|
|
|
if (!work || !bm_alarm_hash_map) {
|
|
|
|
BT_ERR("%s, Invalid parameter", __func__);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2019-10-12 02:41:21 -04:00
|
|
|
|
2023-08-28 04:09:37 -04:00
|
|
|
/* If period is 0, call the corresponding timeout handler. */
|
|
|
|
if (period == 0) {
|
|
|
|
k_work_submit(&work->work);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_lock();
|
2023-08-28 04:09:37 -04:00
|
|
|
|
|
|
|
alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
|
2019-10-12 02:41:21 -04:00
|
|
|
if (alarm == NULL) {
|
2020-07-04 06:35:08 -04:00
|
|
|
BT_WARN("Submit, alarm not found");
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_unlock();
|
2019-10-12 02:41:21 -04:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Cancel the alarm first before starting it. */
|
|
|
|
osi_alarm_cancel(alarm);
|
|
|
|
osi_alarm_set_periodic(alarm, period);
|
2023-08-28 04:09:37 -04:00
|
|
|
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_unlock();
|
2023-08-28 04:09:37 -04:00
|
|
|
|
2019-10-12 02:41:21 -04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-01-07 02:16:47 -05:00
|
|
|
int k_delayed_work_cancel(struct k_delayed_work *work)
|
|
|
|
{
|
2023-08-28 04:09:37 -04:00
|
|
|
osi_alarm_t *alarm = NULL;
|
|
|
|
|
2020-01-19 05:57:13 -05:00
|
|
|
if (!work || !bm_alarm_hash_map) {
|
|
|
|
BT_ERR("%s, Invalid parameter", __func__);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2019-01-07 02:16:47 -05:00
|
|
|
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_lock();
|
2023-08-28 04:09:37 -04:00
|
|
|
|
|
|
|
alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
|
2019-01-07 02:16:47 -05:00
|
|
|
if (alarm == NULL) {
|
2020-07-04 06:35:08 -04:00
|
|
|
BT_WARN("Cancel, alarm not found");
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_unlock();
|
2019-01-07 02:16:47 -05:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
osi_alarm_cancel(alarm);
|
|
|
|
alarm->deadline_us = 0;
|
2023-08-28 04:09:37 -04:00
|
|
|
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_unlock();
|
2023-08-28 04:09:37 -04:00
|
|
|
|
2019-01-07 02:16:47 -05:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int k_delayed_work_free(struct k_delayed_work *work)
|
|
|
|
{
|
2023-08-28 04:09:37 -04:00
|
|
|
osi_alarm_t *alarm = NULL;
|
|
|
|
|
2020-01-19 05:57:13 -05:00
|
|
|
if (!work || !bm_alarm_hash_map) {
|
|
|
|
BT_ERR("%s, Invalid parameter", __func__);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2019-01-07 02:16:47 -05:00
|
|
|
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_lock();
|
2023-08-28 04:09:37 -04:00
|
|
|
|
|
|
|
alarm = hash_map_get(bm_alarm_hash_map, work);
|
2019-01-07 02:16:47 -05:00
|
|
|
if (alarm == NULL) {
|
2020-07-04 06:35:08 -04:00
|
|
|
BT_WARN("Free, alarm not found");
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_unlock();
|
2019-01-07 02:16:47 -05:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2019-12-14 02:43:51 -05:00
|
|
|
osi_alarm_cancel(alarm);
|
2019-01-07 02:16:47 -05:00
|
|
|
hash_map_erase(bm_alarm_hash_map, work);
|
2023-08-28 04:09:37 -04:00
|
|
|
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_unlock();
|
2023-08-28 04:09:37 -04:00
|
|
|
|
2019-01-07 02:16:47 -05:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-12-07 04:03:11 -05:00
|
|
|
int32_t k_delayed_work_remaining_get(struct k_delayed_work *work)
|
2019-01-07 02:16:47 -05:00
|
|
|
{
|
2023-08-28 04:09:37 -04:00
|
|
|
osi_alarm_t *alarm = NULL;
|
2020-12-07 04:03:11 -05:00
|
|
|
int32_t time = 0;
|
2020-03-03 06:08:32 -05:00
|
|
|
|
2020-01-19 05:57:13 -05:00
|
|
|
if (!work || !bm_alarm_hash_map) {
|
|
|
|
BT_ERR("%s, Invalid parameter", __func__);
|
|
|
|
return 0;
|
|
|
|
}
|
2019-01-07 02:16:47 -05:00
|
|
|
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_lock();
|
2023-08-28 04:09:37 -04:00
|
|
|
|
|
|
|
alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
|
2019-01-07 02:16:47 -05:00
|
|
|
if (alarm == NULL) {
|
2020-07-04 06:35:08 -04:00
|
|
|
BT_WARN("Get time, alarm not found");
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_unlock();
|
2019-01-07 02:16:47 -05:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-03-03 06:08:32 -05:00
|
|
|
time = osi_alarm_get_remaining_ms(alarm);
|
2023-08-28 04:09:37 -04:00
|
|
|
|
2020-03-03 06:08:32 -05:00
|
|
|
bt_mesh_alarm_unlock();
|
2023-08-28 04:09:37 -04:00
|
|
|
|
2020-03-03 06:08:32 -05:00
|
|
|
return time;
|
2019-01-07 02:16:47 -05:00
|
|
|
}
|