mesh_timer.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * SPDX-FileCopyrightText: 2016 Intel Corporation
  3. * SPDX-FileCopyrightText: 2016 Wind River Systems, Inc.
  4. * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
  5. *
  6. * SPDX-License-Identifier: Apache-2.0
  7. */
  8. #include <errno.h>
  9. #include "osi/hash_map.h"
  10. #include "osi/alarm.h"
  11. #include "osi/hash_functions.h"
  12. #include "mesh_common.h"
  13. #include "provisioner_prov.h"
  14. static hash_map_t *bm_alarm_hash_map;
  15. static const size_t BLE_MESH_GENERAL_ALARM_HASH_MAP_SIZE = 20 + CONFIG_BLE_MESH_PBA_SAME_TIME + \
  16. CONFIG_BLE_MESH_PBG_SAME_TIME;
  17. typedef struct alarm_t {
  18. /* timer id point to here */
  19. esp_timer_handle_t alarm_hdl;
  20. osi_alarm_callback_t cb;
  21. void *cb_data;
  22. int64_t deadline_us;
  23. } osi_alarm_t;
  24. int64_t k_uptime_get(void)
  25. {
  26. /* k_uptime_get_32 is in in milliseconds,
  27. * but esp_timer_get_time is in microseconds
  28. */
  29. return (esp_timer_get_time() / 1000);
  30. }
  31. uint32_t k_uptime_get_32(void)
  32. {
  33. /* k_uptime_get_32 is in in milliseconds,
  34. * but esp_timer_get_time is in microseconds
  35. */
  36. return (uint32_t)(esp_timer_get_time() / 1000);
  37. }
  38. void bt_mesh_timer_init(void)
  39. {
  40. bm_alarm_hash_map = hash_map_new(BLE_MESH_GENERAL_ALARM_HASH_MAP_SIZE,
  41. hash_function_pointer, NULL,
  42. (data_free_fn)osi_alarm_free, NULL);
  43. __ASSERT(bm_alarm_hash_map, "Failed to create hash map");
  44. }
  45. #if CONFIG_BLE_MESH_DEINIT
  46. void bt_mesh_timer_deinit(void)
  47. {
  48. if (bm_alarm_hash_map) {
  49. hash_map_free(bm_alarm_hash_map);
  50. bm_alarm_hash_map = NULL;
  51. }
  52. }
  53. #endif /* CONFIG_BLE_MESH_DEINIT */
  54. int k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler)
  55. {
  56. osi_alarm_t *alarm = NULL;
  57. if (!work || !bm_alarm_hash_map) {
  58. BT_ERR("%s, Invalid parameter", __func__);
  59. return -EINVAL;
  60. }
  61. k_work_init(&work->work, handler);
  62. bt_mesh_alarm_lock();
  63. if (!hash_map_has_key(bm_alarm_hash_map, (void *)work)) {
  64. alarm = osi_alarm_new("bt_mesh", (osi_alarm_callback_t)handler, (void *)&work->work, 0);
  65. if (alarm == NULL) {
  66. BT_ERR("Alarm not created");
  67. bt_mesh_alarm_unlock();
  68. return -EIO;
  69. }
  70. if (!hash_map_set(bm_alarm_hash_map, work, (void *)alarm)) {
  71. BT_ERR("Alarm not set");
  72. bt_mesh_alarm_unlock();
  73. return -EIO;
  74. }
  75. }
  76. alarm = hash_map_get(bm_alarm_hash_map, work);
  77. if (alarm == NULL) {
  78. BT_ERR("Init, alarm not found");
  79. bt_mesh_alarm_unlock();
  80. return -ENODEV;
  81. }
  82. // Just init the work timer only, don't start it.
  83. osi_alarm_cancel(alarm);
  84. bt_mesh_alarm_unlock();
  85. return 0;
  86. }
  87. int k_delayed_work_submit(struct k_delayed_work *work, int32_t delay)
  88. {
  89. if (!work || !bm_alarm_hash_map) {
  90. BT_ERR("%s, Invalid parameter", __func__);
  91. return -EINVAL;
  92. }
  93. bt_mesh_alarm_lock();
  94. osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
  95. if (alarm == NULL) {
  96. BT_WARN("Submit, alarm not found");
  97. bt_mesh_alarm_unlock();
  98. return -EINVAL;
  99. }
  100. // Cancel the alarm first, before start the alarm.
  101. osi_alarm_cancel(alarm);
  102. osi_alarm_set(alarm, delay);
  103. bt_mesh_alarm_unlock();
  104. return 0;
  105. }
  106. int k_delayed_work_submit_periodic(struct k_delayed_work *work, int32_t period)
  107. {
  108. if (!work || !bm_alarm_hash_map) {
  109. BT_ERR("%s, Invalid parameter", __func__);
  110. return -EINVAL;
  111. }
  112. bt_mesh_alarm_lock();
  113. osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
  114. if (alarm == NULL) {
  115. BT_WARN("Submit, alarm not found");
  116. bt_mesh_alarm_unlock();
  117. return -EINVAL;
  118. }
  119. /* Cancel the alarm first before starting it. */
  120. osi_alarm_cancel(alarm);
  121. osi_alarm_set_periodic(alarm, period);
  122. bt_mesh_alarm_unlock();
  123. return 0;
  124. }
  125. int k_delayed_work_cancel(struct k_delayed_work *work)
  126. {
  127. if (!work || !bm_alarm_hash_map) {
  128. BT_ERR("%s, Invalid parameter", __func__);
  129. return -EINVAL;
  130. }
  131. bt_mesh_alarm_lock();
  132. osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
  133. if (alarm == NULL) {
  134. BT_WARN("Cancel, alarm not found");
  135. bt_mesh_alarm_unlock();
  136. return -EINVAL;
  137. }
  138. osi_alarm_cancel(alarm);
  139. alarm->deadline_us = 0;
  140. bt_mesh_alarm_unlock();
  141. return 0;
  142. }
  143. int k_delayed_work_free(struct k_delayed_work *work)
  144. {
  145. if (!work || !bm_alarm_hash_map) {
  146. BT_ERR("%s, Invalid parameter", __func__);
  147. return -EINVAL;
  148. }
  149. bt_mesh_alarm_lock();
  150. osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, work);
  151. if (alarm == NULL) {
  152. BT_WARN("Free, alarm not found");
  153. bt_mesh_alarm_unlock();
  154. return -EINVAL;
  155. }
  156. osi_alarm_cancel(alarm);
  157. hash_map_erase(bm_alarm_hash_map, work);
  158. bt_mesh_alarm_unlock();
  159. return 0;
  160. }
  161. int32_t k_delayed_work_remaining_get(struct k_delayed_work *work)
  162. {
  163. int32_t time = 0;
  164. if (!work || !bm_alarm_hash_map) {
  165. BT_ERR("%s, Invalid parameter", __func__);
  166. return 0;
  167. }
  168. bt_mesh_alarm_lock();
  169. osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
  170. if (alarm == NULL) {
  171. BT_WARN("Get time, alarm not found");
  172. bt_mesh_alarm_unlock();
  173. return 0;
  174. }
  175. time = osi_alarm_get_remaining_ms(alarm);
  176. bt_mesh_alarm_unlock();
  177. return time;
  178. }