1 // Copyright 2017-2020 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "mesh_common.h"
16 
17 static bt_mesh_mutex_t alarm_lock;
18 static bt_mesh_mutex_t list_lock;
19 static bt_mesh_mutex_t buf_lock;
20 static bt_mesh_mutex_t atomic_lock;
21 
bt_mesh_mutex_create(bt_mesh_mutex_t * mutex)22 void bt_mesh_mutex_create(bt_mesh_mutex_t *mutex)
23 {
24     if (!mutex) {
25         BT_ERR("Create, invalid mutex");
26         return;
27     }
28 
29 #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
30 #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
31     mutex->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
32 #elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
33     mutex->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
34 #endif
35     __ASSERT(mutex->buffer, "Failed to create mutex buffer");
36     mutex->mutex = xSemaphoreCreateMutexStatic(mutex->buffer);
37     __ASSERT(mutex->mutex, "Failed to create static mutex");
38 #else /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
39     mutex->mutex = xSemaphoreCreateMutex();
40     __ASSERT(mutex->mutex, "Failed to create mutex");
41 #endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
42 }
43 
bt_mesh_mutex_free(bt_mesh_mutex_t * mutex)44 void bt_mesh_mutex_free(bt_mesh_mutex_t *mutex)
45 {
46     if (!mutex) {
47         BT_ERR("Free, invalid mutex");
48         return;
49     }
50 
51     if (mutex->mutex) {
52         vSemaphoreDelete(mutex->mutex);
53         mutex->mutex = NULL;
54 #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
55         heap_caps_free(mutex->buffer);
56         mutex->buffer = NULL;
57 #endif
58     }
59 }
60 
bt_mesh_mutex_lock(bt_mesh_mutex_t * mutex)61 void bt_mesh_mutex_lock(bt_mesh_mutex_t *mutex)
62 {
63     if (!mutex) {
64         BT_ERR("Lock, invalid mutex");
65         return;
66     }
67 
68     if (mutex->mutex) {
69         xSemaphoreTake(mutex->mutex, portMAX_DELAY);
70     }
71 }
72 
bt_mesh_mutex_unlock(bt_mesh_mutex_t * mutex)73 void bt_mesh_mutex_unlock(bt_mesh_mutex_t *mutex)
74 {
75     if (!mutex) {
76         BT_ERR("Unlock, invalid mutex");
77         return;
78     }
79 
80     if (mutex->mutex) {
81         xSemaphoreGive(mutex->mutex);
82     }
83 }
84 
bt_mesh_alarm_mutex_new(void)85 static inline void bt_mesh_alarm_mutex_new(void)
86 {
87     if (!alarm_lock.mutex) {
88         bt_mesh_mutex_create(&alarm_lock);
89     }
90 }
91 
bt_mesh_alarm_lock(void)92 void bt_mesh_alarm_lock(void)
93 {
94     bt_mesh_mutex_lock(&alarm_lock);
95 }
96 
bt_mesh_alarm_unlock(void)97 void bt_mesh_alarm_unlock(void)
98 {
99     bt_mesh_mutex_unlock(&alarm_lock);
100 }
101 
bt_mesh_list_mutex_new(void)102 static inline void bt_mesh_list_mutex_new(void)
103 {
104     if (!list_lock.mutex) {
105         bt_mesh_mutex_create(&list_lock);
106     }
107 }
108 
bt_mesh_list_lock(void)109 void bt_mesh_list_lock(void)
110 {
111     bt_mesh_mutex_lock(&list_lock);
112 }
113 
bt_mesh_list_unlock(void)114 void bt_mesh_list_unlock(void)
115 {
116     bt_mesh_mutex_unlock(&list_lock);
117 }
118 
bt_mesh_buf_mutex_new(void)119 static inline void bt_mesh_buf_mutex_new(void)
120 {
121     if (!buf_lock.mutex) {
122         bt_mesh_mutex_create(&buf_lock);
123     }
124 }
125 
bt_mesh_buf_lock(void)126 void bt_mesh_buf_lock(void)
127 {
128     bt_mesh_mutex_lock(&buf_lock);
129 }
130 
bt_mesh_buf_unlock(void)131 void bt_mesh_buf_unlock(void)
132 {
133     bt_mesh_mutex_unlock(&buf_lock);
134 }
135 
bt_mesh_atomic_mutex_new(void)136 static inline void bt_mesh_atomic_mutex_new(void)
137 {
138     if (!atomic_lock.mutex) {
139         bt_mesh_mutex_create(&atomic_lock);
140     }
141 }
142 
bt_mesh_atomic_lock(void)143 void bt_mesh_atomic_lock(void)
144 {
145     bt_mesh_mutex_lock(&atomic_lock);
146 }
147 
bt_mesh_atomic_unlock(void)148 void bt_mesh_atomic_unlock(void)
149 {
150     bt_mesh_mutex_unlock(&atomic_lock);
151 }
152 
bt_mesh_mutex_init(void)153 void bt_mesh_mutex_init(void)
154 {
155     bt_mesh_alarm_mutex_new();
156     bt_mesh_list_mutex_new();
157     bt_mesh_buf_mutex_new();
158     bt_mesh_atomic_mutex_new();
159 }
160 
161 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_alarm_mutex_free(void)162 static inline void bt_mesh_alarm_mutex_free(void)
163 {
164     bt_mesh_mutex_free(&alarm_lock);
165 }
166 
bt_mesh_list_mutex_free(void)167 static inline void bt_mesh_list_mutex_free(void)
168 {
169     bt_mesh_mutex_free(&list_lock);
170 }
171 
bt_mesh_buf_mutex_free(void)172 static inline void bt_mesh_buf_mutex_free(void)
173 {
174     bt_mesh_mutex_free(&buf_lock);
175 }
176 
bt_mesh_atomic_mutex_free(void)177 static inline void bt_mesh_atomic_mutex_free(void)
178 {
179     bt_mesh_mutex_free(&atomic_lock);
180 }
181 
bt_mesh_mutex_deinit(void)182 void bt_mesh_mutex_deinit(void)
183 {
184     bt_mesh_alarm_mutex_free();
185     bt_mesh_list_mutex_free();
186     bt_mesh_buf_mutex_free();
187     bt_mesh_atomic_mutex_free();
188 }
189 #endif /* CONFIG_BLE_MESH_DEINIT */
190