| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * 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"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-19 18:57:13 +08:00
										 |  |  | #include "mesh_common.h"
 | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  | #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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-30 18:24:59 +08:00
										 |  |  | void bt_mesh_timer_init(void) | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     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); | 
					
						
							| 
									
										
										
										
											2020-01-19 18:57:13 +08:00
										 |  |  |     __ASSERT(bm_alarm_hash_map, "%s, Failed to create hash map", __func__); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-30 18:24:59 +08:00
										 |  |  | void bt_mesh_timer_deinit(void) | 
					
						
							| 
									
										
										
										
											2020-01-19 18:57:13 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     if (bm_alarm_hash_map) { | 
					
						
							|  |  |  |         hash_map_free(bm_alarm_hash_map); | 
					
						
							|  |  |  |         bm_alarm_hash_map = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     osi_alarm_t *alarm = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-19 18:57:13 +08:00
										 |  |  |     if (!work || !bm_alarm_hash_map) { | 
					
						
							|  |  |  |         BT_ERR("%s, Invalid parameter", __func__); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     k_work_init(&work->work, handler); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-19 18:57:13 +08:00
										 |  |  |     bt_mesh_alarm_lock(); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |     if (!hash_map_has_key(bm_alarm_hash_map, (void *)work)) { | 
					
						
							| 
									
										
										
										
											2019-09-26 19:38:25 +08:00
										 |  |  |         alarm = osi_alarm_new("bt_mesh", (osi_alarm_callback_t)handler, (void *)&work->work, 0); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |         if (alarm == NULL) { | 
					
						
							|  |  |  |             BT_ERR("%s, Unable to create alarm", __func__); | 
					
						
							| 
									
										
										
										
											2020-01-19 18:57:13 +08:00
										 |  |  |             bt_mesh_alarm_unlock(); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!hash_map_set(bm_alarm_hash_map, work, (void *)alarm)) { | 
					
						
							|  |  |  |             BT_ERR("%s Unable to add the timer to hash map.", __func__); | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |             bt_mesh_alarm_unlock(); | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     alarm = hash_map_get(bm_alarm_hash_map, work); | 
					
						
							|  |  |  |     if (alarm == NULL) { | 
					
						
							|  |  |  |         BT_WARN("%s, Unable to find expected alarm in hash map", __func__); | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |         bt_mesh_alarm_unlock(); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Just init the work timer only, don't start it.
 | 
					
						
							|  |  |  |     osi_alarm_cancel(alarm); | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |     bt_mesh_alarm_unlock(); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |     return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 14:41:21 +08:00
										 |  |  | int k_delayed_work_submit(struct k_delayed_work *work, s32_t delay) | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-01-19 18:57:13 +08:00
										 |  |  |     if (!work || !bm_alarm_hash_map) { | 
					
						
							|  |  |  |         BT_ERR("%s, Invalid parameter", __func__); | 
					
						
							|  |  |  |         return -EINVAL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |     bt_mesh_alarm_lock(); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |     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__); | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |         bt_mesh_alarm_unlock(); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |         return -EINVAL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Cancel the alarm first, before start the alarm.
 | 
					
						
							|  |  |  |     osi_alarm_cancel(alarm); | 
					
						
							|  |  |  |     osi_alarm_set(alarm, delay); | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |     bt_mesh_alarm_unlock(); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 14:41:21 +08:00
										 |  |  | int k_delayed_work_submit_periodic(struct k_delayed_work *work, s32_t period) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-01-19 18:57:13 +08:00
										 |  |  |     if (!work || !bm_alarm_hash_map) { | 
					
						
							|  |  |  |         BT_ERR("%s, Invalid parameter", __func__); | 
					
						
							|  |  |  |         return -EINVAL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-12 14:41:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |     bt_mesh_alarm_lock(); | 
					
						
							| 
									
										
										
										
											2019-10-12 14:41:21 +08:00
										 |  |  |     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__); | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |         bt_mesh_alarm_unlock(); | 
					
						
							| 
									
										
										
										
											2019-10-12 14:41:21 +08:00
										 |  |  |         return -EINVAL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Cancel the alarm first before starting it. */ | 
					
						
							|  |  |  |     osi_alarm_cancel(alarm); | 
					
						
							|  |  |  |     osi_alarm_set_periodic(alarm, period); | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |     bt_mesh_alarm_unlock(); | 
					
						
							| 
									
										
										
										
											2019-10-12 14:41:21 +08:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  | int k_delayed_work_cancel(struct k_delayed_work *work) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-01-19 18:57:13 +08:00
										 |  |  |     if (!work || !bm_alarm_hash_map) { | 
					
						
							|  |  |  |         BT_ERR("%s, Invalid parameter", __func__); | 
					
						
							|  |  |  |         return -EINVAL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |     bt_mesh_alarm_lock(); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |     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__); | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |         bt_mesh_alarm_unlock(); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |         return -EINVAL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     osi_alarm_cancel(alarm); | 
					
						
							|  |  |  |     alarm->deadline_us = 0; | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |     bt_mesh_alarm_unlock(); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int k_delayed_work_free(struct k_delayed_work *work) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-01-19 18:57:13 +08:00
										 |  |  |     if (!work || !bm_alarm_hash_map) { | 
					
						
							|  |  |  |         BT_ERR("%s, Invalid parameter", __func__); | 
					
						
							|  |  |  |         return -EINVAL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |     bt_mesh_alarm_lock(); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |     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__); | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |         bt_mesh_alarm_unlock(); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |         return -EINVAL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-14 15:43:51 +08:00
										 |  |  |     osi_alarm_cancel(alarm); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |     hash_map_erase(bm_alarm_hash_map, work); | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |     bt_mesh_alarm_unlock(); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | s32_t k_delayed_work_remaining_get(struct k_delayed_work *work) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |     s32_t time = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-19 18:57:13 +08:00
										 |  |  |     if (!work || !bm_alarm_hash_map) { | 
					
						
							|  |  |  |         BT_ERR("%s, Invalid parameter", __func__); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |     bt_mesh_alarm_lock(); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |     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__); | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |         bt_mesh_alarm_unlock(); | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-03 19:08:32 +08:00
										 |  |  |     time = osi_alarm_get_remaining_ms(alarm); | 
					
						
							|  |  |  |     bt_mesh_alarm_unlock(); | 
					
						
							|  |  |  |     return time; | 
					
						
							| 
									
										
										
										
											2019-01-07 15:16:47 +08:00
										 |  |  | } |