mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-31 07:01:43 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			214 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			214 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2016 Intel Corporation
 | |
|  * Copyright (c) 2016 Wind River Systems, Inc.
 | |
|  * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE 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_common.h"
 | |
| #include "provisioner_prov.h"
 | |
| 
 | |
| static hash_map_t *bm_alarm_hash_map;
 | |
| static const size_t BLE_MESH_GENERAL_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;
 | |
| 
 | |
| s64_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);
 | |
| }
 | |
| 
 | |
| u32_t k_uptime_get_32(void)
 | |
| {
 | |
|     /** k_uptime_get_32 is in in milliseconds,
 | |
|      * but esp_timer_get_time is in microseconds
 | |
|      */
 | |
|     return (u32_t)(esp_timer_get_time() / 1000);
 | |
| }
 | |
| 
 | |
| void k_sleep(s32_t duration)
 | |
| {
 | |
|     vTaskDelay(duration / portTICK_PERIOD_MS);
 | |
|     return;
 | |
| }
 | |
| 
 | |
| void bt_mesh_timer_init(void)
 | |
| {
 | |
|     bm_alarm_hash_map = hash_map_new(BLE_MESH_GENERAL_ALARM_HASH_MAP_SIZE,
 | |
|                                      hash_function_pointer, NULL,
 | |
|                                      (data_free_fn)osi_alarm_free, NULL);
 | |
|     __ASSERT(bm_alarm_hash_map, "%s, Failed to create hash map", __func__);
 | |
| }
 | |
| 
 | |
| void bt_mesh_timer_deinit(void)
 | |
| {
 | |
|     if (bm_alarm_hash_map) {
 | |
|         hash_map_free(bm_alarm_hash_map);
 | |
|         bm_alarm_hash_map = NULL;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void 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;
 | |
|     }
 | |
| 
 | |
|     k_work_init(&work->work, handler);
 | |
| 
 | |
|     bt_mesh_alarm_lock();
 | |
|     if (!hash_map_has_key(bm_alarm_hash_map, (void *)work)) {
 | |
|         alarm = osi_alarm_new("bt_mesh", (osi_alarm_callback_t)handler, (void *)&work->work, 0);
 | |
|         if (alarm == NULL) {
 | |
|             BT_ERR("%s, Unable to create alarm", __func__);
 | |
|             bt_mesh_alarm_unlock();
 | |
|             return;
 | |
|         }
 | |
|         if (!hash_map_set(bm_alarm_hash_map, work, (void *)alarm)) {
 | |
|             BT_ERR("%s Unable to add the timer to hash map.", __func__);
 | |
|             bt_mesh_alarm_unlock();
 | |
|             return;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     alarm = hash_map_get(bm_alarm_hash_map, work);
 | |
|     if (alarm == NULL) {
 | |
|         BT_WARN("%s, Unable to find expected alarm in hash map", __func__);
 | |
|         bt_mesh_alarm_unlock();
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     // Just init the work timer only, don't start it.
 | |
|     osi_alarm_cancel(alarm);
 | |
|     bt_mesh_alarm_unlock();
 | |
|     return;
 | |
| }
 | |
| 
 | |
| int k_delayed_work_submit(struct k_delayed_work *work, s32_t delay)
 | |
| {
 | |
|     if (!work || !bm_alarm_hash_map) {
 | |
|         BT_ERR("%s, Invalid parameter", __func__);
 | |
|         return -EINVAL;
 | |
|     }
 | |
| 
 | |
|     bt_mesh_alarm_lock();
 | |
|     osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
 | |
|     if (alarm == NULL) {
 | |
|         BT_WARN("%s, Unable to find expected alarm in hash map", __func__);
 | |
|         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, s32_t period)
 | |
| {
 | |
|     if (!work || !bm_alarm_hash_map) {
 | |
|         BT_ERR("%s, Invalid parameter", __func__);
 | |
|         return -EINVAL;
 | |
|     }
 | |
| 
 | |
|     bt_mesh_alarm_lock();
 | |
|     osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
 | |
|     if (alarm == NULL) {
 | |
|         BT_WARN("%s, Unable to find expected alarm in hash map", __func__);
 | |
|         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)
 | |
| {
 | |
|     if (!work || !bm_alarm_hash_map) {
 | |
|         BT_ERR("%s, Invalid parameter", __func__);
 | |
|         return -EINVAL;
 | |
|     }
 | |
| 
 | |
|     bt_mesh_alarm_lock();
 | |
|     osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
 | |
|     if (alarm == NULL) {
 | |
|         BT_WARN("%s, Unable to find expected alarm in hash map", __func__);
 | |
|         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)
 | |
| {
 | |
|     if (!work || !bm_alarm_hash_map) {
 | |
|         BT_ERR("%s, Invalid parameter", __func__);
 | |
|         return -EINVAL;
 | |
|     }
 | |
| 
 | |
|     bt_mesh_alarm_lock();
 | |
|     osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, work);
 | |
|     if (alarm == NULL) {
 | |
|         BT_WARN("%s Unable to find expected alarm in hash map", __func__);
 | |
|         bt_mesh_alarm_unlock();
 | |
|         return -EINVAL;
 | |
|     }
 | |
| 
 | |
|     osi_alarm_cancel(alarm);
 | |
|     hash_map_erase(bm_alarm_hash_map, work);
 | |
|     bt_mesh_alarm_unlock();
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| s32_t k_delayed_work_remaining_get(struct k_delayed_work *work)
 | |
| {
 | |
|     s32_t time = 0;
 | |
| 
 | |
|     if (!work || !bm_alarm_hash_map) {
 | |
|         BT_ERR("%s, Invalid parameter", __func__);
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
|     bt_mesh_alarm_lock();
 | |
|     osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
 | |
|     if (alarm == NULL) {
 | |
|         BT_WARN("%s Unable to find expected alarm in hash map", __func__);
 | |
|         bt_mesh_alarm_unlock();
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
|     time = osi_alarm_get_remaining_ms(alarm);
 | |
|     bt_mesh_alarm_unlock();
 | |
|     return time;
 | |
| }
 |