| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- /*
- * 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 <errno.h>
- #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;
- }
|