From ee29c25b29eaa4fac4e897442634b69ecc8d8125 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Thu, 28 Mar 2024 14:32:49 +1100 Subject: Fork ESP-IDF's bluetooth component i want better sbc encoding, and no cla will stop me --- lib/bt/esp_ble_mesh/common/timer.c | 247 +++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 lib/bt/esp_ble_mesh/common/timer.c (limited to 'lib/bt/esp_ble_mesh/common/timer.c') diff --git a/lib/bt/esp_ble_mesh/common/timer.c b/lib/bt/esp_ble_mesh/common/timer.c new file mode 100644 index 00000000..0d65bd3a --- /dev/null +++ b/lib/bt/esp_ble_mesh/common/timer.c @@ -0,0 +1,247 @@ +/* + * SPDX-FileCopyrightText: 2016 Intel Corporation + * SPDX-FileCopyrightText: 2016 Wind River Systems, Inc. + * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "osi/hash_map.h" +#include "osi/alarm.h" +#include "osi/hash_functions.h" + +#include "mesh/config.h" +#include "mesh/common.h" + +static hash_map_t *bm_alarm_hash_map; +static const size_t BLE_MESH_ALARM_HASH_MAP_SIZE = 20 + CONFIG_BLE_MESH_PBA_SAME_TIME + + CONFIG_BLE_MESH_PBG_SAME_TIME; + +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; + +int64_t k_uptime_get(void) +{ + /* k_uptime_get_32 is in in milliseconds, + * but esp_timer_get_time is in microseconds + */ + return (esp_timer_get_time() / 1000); +} + +uint32_t k_uptime_get_32(void) +{ + /* k_uptime_get_32 is in in milliseconds, + * but esp_timer_get_time is in microseconds + */ + return (uint32_t)(esp_timer_get_time() / 1000); +} + +void bt_mesh_timer_init(void) +{ + bm_alarm_hash_map = hash_map_new(BLE_MESH_ALARM_HASH_MAP_SIZE, + hash_function_pointer, NULL, + (data_free_fn)osi_alarm_free, NULL); + __ASSERT(bm_alarm_hash_map, "Failed to create hash map"); +} + +#if CONFIG_BLE_MESH_DEINIT +void bt_mesh_timer_deinit(void) +{ + if (bm_alarm_hash_map) { + hash_map_free(bm_alarm_hash_map); + bm_alarm_hash_map = NULL; + } +} +#endif /* CONFIG_BLE_MESH_DEINIT */ + +int k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler) +{ + osi_alarm_t *alarm = NULL; + + if (!work || !bm_alarm_hash_map) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + k_work_init(&work->work, handler); + + bt_mesh_alarm_lock(); + + alarm = hash_map_get(bm_alarm_hash_map, work); + 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); + if (alarm == NULL) { + 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"); + bt_mesh_alarm_unlock(); + return -EIO; + } + + // Just init the work timer only, don't start it. + osi_alarm_cancel(alarm); + + bt_mesh_alarm_unlock(); + + return 0; +} + +int k_delayed_work_submit(struct k_delayed_work *work, int32_t delay) +{ + osi_alarm_t *alarm = NULL; + + if (!work || !bm_alarm_hash_map) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + /* If delay is 0, call the corresponding timeout handler. */ + if (delay == 0) { + k_work_submit(&work->work); + return 0; + } + + bt_mesh_alarm_lock(); + + alarm = hash_map_get(bm_alarm_hash_map, (void *)work); + if (alarm == NULL) { + BT_WARN("Submit, alarm not found"); + bt_mesh_alarm_unlock(); + return -EINVAL; + } + + // Cancel the alarm first, before start the alarm. + osi_alarm_cancel(alarm); + osi_alarm_set(alarm, delay); + + bt_mesh_alarm_unlock(); + + return 0; +} + +int k_delayed_work_submit_periodic(struct k_delayed_work *work, int32_t period) +{ + osi_alarm_t *alarm = NULL; + + if (!work || !bm_alarm_hash_map) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + /* If period is 0, call the corresponding timeout handler. */ + if (period == 0) { + k_work_submit(&work->work); + return 0; + } + + bt_mesh_alarm_lock(); + + alarm = hash_map_get(bm_alarm_hash_map, (void *)work); + if (alarm == NULL) { + BT_WARN("Submit, alarm not found"); + bt_mesh_alarm_unlock(); + return -EINVAL; + } + + /* Cancel the alarm first before starting it. */ + osi_alarm_cancel(alarm); + osi_alarm_set_periodic(alarm, period); + + bt_mesh_alarm_unlock(); + + return 0; +} + +int k_delayed_work_cancel(struct k_delayed_work *work) +{ + osi_alarm_t *alarm = NULL; + + if (!work || !bm_alarm_hash_map) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + bt_mesh_alarm_lock(); + + alarm = hash_map_get(bm_alarm_hash_map, (void *)work); + if (alarm == NULL) { + BT_WARN("Cancel, alarm not found"); + bt_mesh_alarm_unlock(); + return -EINVAL; + } + + osi_alarm_cancel(alarm); + alarm->deadline_us = 0; + + bt_mesh_alarm_unlock(); + + return 0; +} + +int k_delayed_work_free(struct k_delayed_work *work) +{ + osi_alarm_t *alarm = NULL; + + if (!work || !bm_alarm_hash_map) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + bt_mesh_alarm_lock(); + + alarm = hash_map_get(bm_alarm_hash_map, work); + if (alarm == NULL) { + BT_DBG("Free, alarm not found"); + bt_mesh_alarm_unlock(); + return -EINVAL; + } + + osi_alarm_cancel(alarm); + hash_map_erase(bm_alarm_hash_map, work); + + bt_mesh_alarm_unlock(); + + return 0; +} + +int32_t k_delayed_work_remaining_get(struct k_delayed_work *work) +{ + osi_alarm_t *alarm = NULL; + int32_t time = 0; + + if (!work || !bm_alarm_hash_map) { + BT_ERR("%s, Invalid parameter", __func__); + return 0; + } + + bt_mesh_alarm_lock(); + + alarm = hash_map_get(bm_alarm_hash_map, (void *)work); + if (alarm == NULL) { + BT_WARN("Get time, alarm not found"); + bt_mesh_alarm_unlock(); + return 0; + } + + time = osi_alarm_get_remaining_ms(alarm); + + bt_mesh_alarm_unlock(); + + return time; +} -- cgit v1.2.3