1 /*
2  * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "mesh_common.h"
8 
9 static bt_mesh_mutex_t alarm_lock;
10 static bt_mesh_mutex_t list_lock;
11 static bt_mesh_mutex_t buf_lock;
12 static bt_mesh_mutex_t atomic_lock;
13 
bt_mesh_mutex_create(bt_mesh_mutex_t * mutex)14 void bt_mesh_mutex_create(bt_mesh_mutex_t *mutex)
15 {
16     if (!mutex) {
17         BT_ERR("Create, invalid mutex");
18         return;
19     }
20 
21 #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
22 #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
23     mutex->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
24 #elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
25     mutex->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
26 #endif
27     __ASSERT(mutex->buffer, "Failed to create mutex buffer");
28     mutex->mutex = xSemaphoreCreateMutexStatic(mutex->buffer);
29     __ASSERT(mutex->mutex, "Failed to create static mutex");
30 #else /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
31     mutex->mutex = xSemaphoreCreateMutex();
32     __ASSERT(mutex->mutex, "Failed to create mutex");
33 #endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
34 }
35 
bt_mesh_mutex_free(bt_mesh_mutex_t * mutex)36 void bt_mesh_mutex_free(bt_mesh_mutex_t *mutex)
37 {
38     if (!mutex) {
39         BT_ERR("Free, invalid mutex");
40         return;
41     }
42 
43     if (mutex->mutex) {
44         vSemaphoreDelete(mutex->mutex);
45         mutex->mutex = NULL;
46 #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
47         heap_caps_free(mutex->buffer);
48         mutex->buffer = NULL;
49 #endif
50     }
51 }
52 
bt_mesh_mutex_lock(bt_mesh_mutex_t * mutex)53 void bt_mesh_mutex_lock(bt_mesh_mutex_t *mutex)
54 {
55     if (!mutex) {
56         BT_ERR("Lock, invalid mutex");
57         return;
58     }
59 
60     if (mutex->mutex) {
61         xSemaphoreTake(mutex->mutex, portMAX_DELAY);
62     }
63 }
64 
bt_mesh_mutex_unlock(bt_mesh_mutex_t * mutex)65 void bt_mesh_mutex_unlock(bt_mesh_mutex_t *mutex)
66 {
67     if (!mutex) {
68         BT_ERR("Unlock, invalid mutex");
69         return;
70     }
71 
72     if (mutex->mutex) {
73         xSemaphoreGive(mutex->mutex);
74     }
75 }
76 
bt_mesh_alarm_mutex_new(void)77 static inline void bt_mesh_alarm_mutex_new(void)
78 {
79     if (!alarm_lock.mutex) {
80         bt_mesh_mutex_create(&alarm_lock);
81     }
82 }
83 
bt_mesh_alarm_lock(void)84 void bt_mesh_alarm_lock(void)
85 {
86     bt_mesh_mutex_lock(&alarm_lock);
87 }
88 
bt_mesh_alarm_unlock(void)89 void bt_mesh_alarm_unlock(void)
90 {
91     bt_mesh_mutex_unlock(&alarm_lock);
92 }
93 
bt_mesh_list_mutex_new(void)94 static inline void bt_mesh_list_mutex_new(void)
95 {
96     if (!list_lock.mutex) {
97         bt_mesh_mutex_create(&list_lock);
98     }
99 }
100 
bt_mesh_list_lock(void)101 void bt_mesh_list_lock(void)
102 {
103     bt_mesh_mutex_lock(&list_lock);
104 }
105 
bt_mesh_list_unlock(void)106 void bt_mesh_list_unlock(void)
107 {
108     bt_mesh_mutex_unlock(&list_lock);
109 }
110 
bt_mesh_buf_mutex_new(void)111 static inline void bt_mesh_buf_mutex_new(void)
112 {
113     if (!buf_lock.mutex) {
114         bt_mesh_mutex_create(&buf_lock);
115     }
116 }
117 
bt_mesh_buf_lock(void)118 void bt_mesh_buf_lock(void)
119 {
120     bt_mesh_mutex_lock(&buf_lock);
121 }
122 
bt_mesh_buf_unlock(void)123 void bt_mesh_buf_unlock(void)
124 {
125     bt_mesh_mutex_unlock(&buf_lock);
126 }
127 
bt_mesh_atomic_mutex_new(void)128 static inline void bt_mesh_atomic_mutex_new(void)
129 {
130     if (!atomic_lock.mutex) {
131         bt_mesh_mutex_create(&atomic_lock);
132     }
133 }
134 
bt_mesh_atomic_lock(void)135 void bt_mesh_atomic_lock(void)
136 {
137     bt_mesh_mutex_lock(&atomic_lock);
138 }
139 
bt_mesh_atomic_unlock(void)140 void bt_mesh_atomic_unlock(void)
141 {
142     bt_mesh_mutex_unlock(&atomic_lock);
143 }
144 
bt_mesh_mutex_init(void)145 void bt_mesh_mutex_init(void)
146 {
147     bt_mesh_alarm_mutex_new();
148     bt_mesh_list_mutex_new();
149     bt_mesh_buf_mutex_new();
150     bt_mesh_atomic_mutex_new();
151 }
152 
153 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_alarm_mutex_free(void)154 static inline void bt_mesh_alarm_mutex_free(void)
155 {
156     bt_mesh_mutex_free(&alarm_lock);
157 }
158 
bt_mesh_list_mutex_free(void)159 static inline void bt_mesh_list_mutex_free(void)
160 {
161     bt_mesh_mutex_free(&list_lock);
162 }
163 
bt_mesh_buf_mutex_free(void)164 static inline void bt_mesh_buf_mutex_free(void)
165 {
166     bt_mesh_mutex_free(&buf_lock);
167 }
168 
bt_mesh_atomic_mutex_free(void)169 static inline void bt_mesh_atomic_mutex_free(void)
170 {
171     bt_mesh_mutex_free(&atomic_lock);
172 }
173 
bt_mesh_mutex_deinit(void)174 void bt_mesh_mutex_deinit(void)
175 {
176     bt_mesh_alarm_mutex_free();
177     bt_mesh_list_mutex_free();
178     bt_mesh_buf_mutex_free();
179     bt_mesh_atomic_mutex_free();
180 }
181 #endif /* CONFIG_BLE_MESH_DEINIT */
182