1 // Copyright 2015-2016 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 <stdlib.h>
16 #include <string.h>
17 #include "btc/btc_task.h"
18 #include "osi/thread.h"
19 #include "esp_log.h"
20 #include "bt_common.h"
21 #include "osi/allocator.h"
22 #include "btc/btc_alarm.h"
23
24 #include "btc/btc_manage.h"
25 #include "btc_blufi_prf.h"
26 #include "blufi_int.h"
27 #ifdef CONFIG_BT_BLUEDROID_ENABLED
28 #include "common/bt_target.h"
29 #include "btc/btc_main.h"
30 #include "btc/btc_dev.h"
31 #include "btc_gatts.h"
32 #include "btc_gattc.h"
33 #include "btc_gatt_common.h"
34 #include "btc_gap_ble.h"
35 #include "btc/btc_dm.h"
36 #include "bta/bta_gatt_api.h"
37 #if CLASSIC_BT_INCLUDED
38 #include "btc/btc_profile_queue.h"
39 #if (BTC_GAP_BT_INCLUDED == TRUE)
40 #include "btc_gap_bt.h"
41 #endif /* BTC_GAP_BT_INCLUDED == TRUE */
42 #if BTC_AV_INCLUDED
43 #include "btc_av.h"
44 #include "btc_avrc.h"
45 #include "btc_av_co.h"
46 #endif /* #if BTC_AV_INCLUDED */
47 #if (BTC_SPP_INCLUDED == TRUE)
48 #include "btc_spp.h"
49 #endif /* #if (BTC_SPP_INCLUDED == TRUE) */
50 #if BTC_HF_INCLUDED
51 #include "btc_hf_ag.h"
52 #endif/* #if BTC_HF_INCLUDED */
53 #if BTC_HF_CLIENT_INCLUDED
54 #include "btc_hf_client.h"
55 #endif /* #if BTC_HF_CLIENT_INCLUDED */
56 #if BTC_HD_INCLUDED == TRUE
57 #include "btc_hd.h"
58 #endif /* BTC_HD_INCLUDED */
59 #if BTC_HH_INCLUDED == TRUE
60 #include "btc_hh.h"
61 #endif /* BTC_HH_INCLUDED */
62 #endif /* #if CLASSIC_BT_INCLUDED */
63 #endif
64
65 #if CONFIG_BLE_MESH
66 #include "btc_ble_mesh_ble.h"
67 #include "btc_ble_mesh_prov.h"
68 #include "btc_ble_mesh_health_model.h"
69 #include "btc_ble_mesh_config_model.h"
70 #include "btc_ble_mesh_generic_model.h"
71 #include "btc_ble_mesh_lighting_model.h"
72 #include "btc_ble_mesh_sensor_model.h"
73 #include "btc_ble_mesh_time_scene_model.h"
74 #endif /* #if CONFIG_BLE_MESH */
75
76 #define BTC_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
77 #define BTC_TASK_STACK_SIZE (BT_BTC_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) //by menuconfig
78 #define BTC_TASK_NAME "BTC_TASK"
79 #define BTC_TASK_PRIO (BT_TASK_MAX_PRIORITIES - 6)
80
81 osi_thread_t *btc_thread;
82
83 static const btc_func_t profile_tab[BTC_PID_NUM] = {
84 #ifdef CONFIG_BT_BLUEDROID_ENABLED
85 [BTC_PID_MAIN_INIT] = {btc_main_call_handler, NULL },
86 [BTC_PID_DEV] = {btc_dev_call_handler, NULL },
87 #if (GATTS_INCLUDED == TRUE)
88 [BTC_PID_GATTS] = {btc_gatts_call_handler, btc_gatts_cb_handler },
89 #endif ///GATTS_INCLUDED == TRUE
90 #if (GATTC_INCLUDED == TRUE)
91 [BTC_PID_GATTC] = {btc_gattc_call_handler, btc_gattc_cb_handler },
92 #endif ///GATTC_INCLUDED == TRUE
93 #if (GATTS_INCLUDED == TRUE || GATTC_INCLUDED == TRUE)
94 [BTC_PID_GATT_COMMON] = {btc_gatt_com_call_handler, NULL },
95 #endif //GATTC_INCLUDED == TRUE || GATTS_INCLUDED == TRUE
96 #if (BLE_INCLUDED == TRUE)
97 [BTC_PID_GAP_BLE] = {btc_gap_ble_call_handler, btc_gap_ble_cb_handler },
98 #else
99 [BTC_PID_GAP_BLE] = {NULL, NULL},
100 #endif ///BLE_INCLUDED == TRUE
101 [BTC_PID_BLE_HID] = {NULL, NULL},
102 [BTC_PID_SPPLIKE] = {NULL, NULL},
103 [BTC_PID_DM_SEC] = {NULL, btc_dm_sec_cb_handler },
104 #endif
105 #if (BLUFI_INCLUDED == TRUE)
106 [BTC_PID_BLUFI] = {btc_blufi_call_handler, btc_blufi_cb_handler },
107 #endif ///BLUFI_INCLUDED == TRUE
108 [BTC_PID_ALARM] = {btc_alarm_handler, NULL },
109 #ifdef CONFIG_BT_BLUEDROID_ENABLED
110 #if CLASSIC_BT_INCLUDED
111 #if (BTC_GAP_BT_INCLUDED == TRUE)
112 [BTC_PID_GAP_BT] = {btc_gap_bt_call_handler, btc_gap_bt_cb_handler },
113 #endif /* (BTC_GAP_BT_INCLUDED == TRUE) */
114 [BTC_PID_PRF_QUE] = {btc_profile_queue_handler, NULL },
115 #if BTC_AV_INCLUDED
116 [BTC_PID_A2DP] = {btc_a2dp_call_handler, btc_a2dp_cb_handler },
117 [BTC_PID_AVRC_CT] = {btc_avrc_ct_call_handler, NULL },
118 [BTC_PID_AVRC_TG] = {btc_avrc_tg_call_handler, NULL },
119 #endif /* #if BTC_AV_INCLUDED */
120 #if (BTC_SPP_INCLUDED == TRUE)
121 [BTC_PID_SPP] = {btc_spp_call_handler, btc_spp_cb_handler },
122 #endif /* #if (BTC_SPP_INCLUDED == TRUE) */
123 #if BTC_HF_INCLUDED
124 [BTC_PID_HF] = {btc_hf_call_handler, btc_hf_cb_handler},
125 #endif /* #if BTC_HF_INCLUDED */
126 #if BTC_HF_CLIENT_INCLUDED
127 [BTC_PID_HF_CLIENT] = {btc_hf_client_call_handler, btc_hf_client_cb_handler},
128 #endif /* #if BTC_HF_CLIENT_INCLUDED */
129 #if BTC_HD_INCLUDED
130 [BTC_PID_HD] = {btc_hd_call_handler, btc_hd_cb_handler },
131 #endif
132 #if BTC_HH_INCLUDED
133 [BTC_PID_HH] = {btc_hh_call_handler, btc_hh_cb_handler },
134 #endif
135 #endif /* #if CLASSIC_BT_INCLUDED */
136 #endif
137 #if CONFIG_BLE_MESH
138 [BTC_PID_PROV] = {btc_ble_mesh_prov_call_handler, btc_ble_mesh_prov_cb_handler },
139 [BTC_PID_MODEL] = {btc_ble_mesh_model_call_handler, btc_ble_mesh_model_cb_handler },
140 #if CONFIG_BLE_MESH_HEALTH_CLI
141 [BTC_PID_HEALTH_CLIENT] = {btc_ble_mesh_health_client_call_handler, btc_ble_mesh_health_client_cb_handler },
142 #endif /* CONFIG_BLE_MESH_HEALTH_CLI */
143 #if CONFIG_BLE_MESH_HEALTH_SRV
144 [BTC_PID_HEALTH_SERVER] = {btc_ble_mesh_health_server_call_handler, btc_ble_mesh_health_server_cb_handler },
145 #endif /* CONFIG_BLE_MESH_HEALTH_SRV */
146 #if CONFIG_BLE_MESH_CFG_CLI
147 [BTC_PID_CONFIG_CLIENT] = {btc_ble_mesh_config_client_call_handler, btc_ble_mesh_config_client_cb_handler },
148 #endif /* CONFIG_BLE_MESH_CFG_CLI */
149 [BTC_PID_CONFIG_SERVER] = {NULL, btc_ble_mesh_config_server_cb_handler },
150 #if CONFIG_BLE_MESH_GENERIC_CLIENT
151 [BTC_PID_GENERIC_CLIENT] = {btc_ble_mesh_generic_client_call_handler, btc_ble_mesh_generic_client_cb_handler },
152 #endif /* CONFIG_BLE_MESH_GENERIC_CLIENT */
153 #if CONFIG_BLE_MESH_LIGHTING_CLIENT
154 [BTC_PID_LIGHTING_CLIENT] = {btc_ble_mesh_lighting_client_call_handler, btc_ble_mesh_lighting_client_cb_handler },
155 #endif /* CONFIG_BLE_MESH_LIGHTING_CLIENT */
156 #if CONFIG_BLE_MESH_SENSOR_CLI
157 [BTC_PID_SENSOR_CLIENT] = {btc_ble_mesh_sensor_client_call_handler, btc_ble_mesh_sensor_client_cb_handler },
158 #endif /* CONFIG_BLE_MESH_SENSOR_CLI */
159 #if CONFIG_BLE_MESH_TIME_SCENE_CLIENT
160 [BTC_PID_TIME_SCENE_CLIENT] = {btc_ble_mesh_time_scene_client_call_handler, btc_ble_mesh_time_scene_client_cb_handler},
161 #endif /* CONFIG_BLE_MESH_TIME_SCENE_CLIENT */
162 #if CONFIG_BLE_MESH_GENERIC_SERVER
163 [BTC_PID_GENERIC_SERVER] = {NULL, btc_ble_mesh_generic_server_cb_handler },
164 #endif /* CONFIG_BLE_MESH_GENERIC_SERVER */
165 #if CONFIG_BLE_MESH_LIGHTING_SERVER
166 [BTC_PID_LIGHTING_SERVER] = {NULL, btc_ble_mesh_lighting_server_cb_handler },
167 #endif /* CONFIG_BLE_MESH_LIGHTING_SERVER */
168 #if CONFIG_BLE_MESH_SENSOR_SERVER
169 [BTC_PID_SENSOR_SERVER] = {NULL, btc_ble_mesh_sensor_server_cb_handler },
170 #endif /* CONFIG_BLE_MESH_SENSOR_SERVER */
171 #if CONFIG_BLE_MESH_TIME_SCENE_SERVER
172 [BTC_PID_TIME_SCENE_SERVER] = {NULL, btc_ble_mesh_time_scene_server_cb_handler},
173 #endif /* CONFIG_BLE_MESH_TIME_SCENE_SERVER */
174 #if CONFIG_BLE_MESH_BLE_COEX_SUPPORT
175 [BTC_PID_BLE_MESH_BLE_COEX] = {btc_ble_mesh_ble_call_handler, btc_ble_mesh_ble_cb_handler },
176 #endif /* CONFIG_BLE_MESH_BLE_COEX_SUPPORT */
177 #endif /* #if CONFIG_BLE_MESH */
178 };
179
180 /*****************************************************************************
181 **
182 ** Function btc_task
183 **
184 ** Description Process profile Task Thread.
185 ******************************************************************************/
btc_thread_handler(void * arg)186 static void btc_thread_handler(void *arg)
187 {
188 btc_msg_t *msg = (btc_msg_t *)arg;
189
190 BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, msg->arg);
191 switch (msg->sig) {
192 case BTC_SIG_API_CALL:
193 profile_tab[msg->pid].btc_call(msg);
194 break;
195 case BTC_SIG_API_CB:
196 profile_tab[msg->pid].btc_cb(msg);
197 break;
198 default:
199 break;
200 }
201
202 if (msg->arg) {
203 osi_free(msg->arg);
204 }
205 osi_free(msg);
206 }
207
btc_task_post(btc_msg_t * msg,uint32_t timeout)208 static bt_status_t btc_task_post(btc_msg_t *msg, uint32_t timeout)
209 {
210 btc_msg_t *lmsg;
211
212 lmsg = (btc_msg_t *)osi_malloc(sizeof(btc_msg_t));
213 if (lmsg == NULL) {
214 return BT_STATUS_NOMEM;
215 }
216
217 memcpy(lmsg, msg, sizeof(btc_msg_t));
218
219 if (osi_thread_post(btc_thread, btc_thread_handler, lmsg, 0, timeout) == false) {
220 return BT_STATUS_BUSY;
221 }
222
223 return BT_STATUS_SUCCESS;
224 }
225
226 /**
227 * transfer an message to another module in the different task.
228 * @param msg message
229 * @param arg paramter
230 * @param arg_len length of paramter
231 * @param copy_func deep copy function
232 * @return BT_STATUS_SUCCESS: success
233 * others: fail
234 */
btc_transfer_context(btc_msg_t * msg,void * arg,int arg_len,btc_arg_deep_copy_t copy_func)235 bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func)
236 {
237 btc_msg_t lmsg;
238
239 if (msg == NULL) {
240 return BT_STATUS_PARM_INVALID;
241 }
242
243 BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, arg);
244
245 memcpy(&lmsg, msg, sizeof(btc_msg_t));
246 if (arg) {
247 lmsg.arg = (void *)osi_malloc(arg_len);
248 if (lmsg.arg == NULL) {
249 return BT_STATUS_NOMEM;
250 }
251 memset(lmsg.arg, 0x00, arg_len); //important, avoid arg which have no length
252 memcpy(lmsg.arg, arg, arg_len);
253 if (copy_func) {
254 copy_func(&lmsg, lmsg.arg, arg);
255 }
256 } else {
257 lmsg.arg = NULL;
258 }
259
260 return btc_task_post(&lmsg, OSI_THREAD_MAX_TIMEOUT);
261
262 }
263
264 /**
265 * transfer an message to another module in tha same task.
266 * @param msg message
267 * @param arg paramter
268 * @return BT_STATUS_SUCCESS: success
269 * others: fail
270 */
btc_inter_profile_call(btc_msg_t * msg,void * arg)271 bt_status_t btc_inter_profile_call(btc_msg_t *msg, void *arg)
272 {
273 if (msg == NULL) {
274 return BT_STATUS_PARM_INVALID;
275 }
276
277 msg->arg = arg;
278 switch (msg->sig) {
279 case BTC_SIG_API_CALL:
280 profile_tab[msg->pid].btc_call(msg);
281 break;
282 case BTC_SIG_API_CB:
283 profile_tab[msg->pid].btc_cb(msg);
284 break;
285 default:
286 break;
287 }
288 return BT_STATUS_SUCCESS;
289 }
290
291
292 #if BTC_DYNAMIC_MEMORY
293
btc_deinit_mem(void)294 static void btc_deinit_mem(void) {
295 if (btc_dm_cb_ptr) {
296 osi_free(btc_dm_cb_ptr);
297 btc_dm_cb_ptr = NULL;
298 }
299
300 if (btc_profile_cb_tab) {
301 osi_free(btc_profile_cb_tab);
302 btc_profile_cb_tab = NULL;
303 }
304
305 #if (BLE_INCLUDED == TRUE)
306 if (gl_bta_adv_data_ptr) {
307 osi_free(gl_bta_adv_data_ptr);
308 gl_bta_adv_data_ptr = NULL;
309 }
310
311 if (gl_bta_scan_rsp_data_ptr) {
312 osi_free(gl_bta_scan_rsp_data_ptr);
313 gl_bta_scan_rsp_data_ptr = NULL;
314 }
315 #endif ///BLE_INCLUDED == TRUE
316
317 #if GATTS_INCLUDED == TRUE && GATT_DYNAMIC_MEMORY == TRUE
318 if (btc_creat_tab_env_ptr) {
319 osi_free(btc_creat_tab_env_ptr);
320 btc_creat_tab_env_ptr = NULL;
321 }
322 #if (BLUFI_INCLUDED == TRUE)
323 if (blufi_env_ptr) {
324 osi_free(blufi_env_ptr);
325 blufi_env_ptr = NULL;
326 }
327 #endif
328 #endif
329
330 #if BTC_HF_CLIENT_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE
331 if (hf_client_local_param_ptr) {
332 osi_free(hf_client_local_param_ptr);
333 hf_client_local_param_ptr = NULL;
334 }
335 #endif
336
337 #if BTC_AV_INCLUDED == TRUE && AVRC_DYNAMIC_MEMORY == TRUE
338 if (btc_rc_cb_ptr) {
339 osi_free(btc_rc_cb_ptr);
340 btc_rc_cb_ptr = NULL;
341 }
342 if (bta_av_co_cb_ptr) {
343 osi_free(bta_av_co_cb_ptr);
344 bta_av_co_cb_ptr = NULL;
345 }
346 #endif
347 }
348
btc_init_mem(void)349 static bt_status_t btc_init_mem(void) {
350 if ((btc_dm_cb_ptr = (btc_dm_cb_t *)osi_malloc(sizeof(btc_dm_cb_t))) == NULL) {
351 goto error_exit;
352 }
353 memset((void *)btc_dm_cb_ptr, 0, sizeof(btc_dm_cb_t));
354
355 if ((btc_profile_cb_tab = (void **)osi_malloc(sizeof(void *) * BTC_PID_NUM)) == NULL) {
356 goto error_exit;
357 }
358 memset((void *)btc_profile_cb_tab, 0, sizeof(void *) * BTC_PID_NUM);
359
360 #if (BLE_INCLUDED == TRUE)
361 if ((gl_bta_adv_data_ptr = (tBTA_BLE_ADV_DATA *)osi_malloc(sizeof(tBTA_BLE_ADV_DATA))) == NULL) {
362 goto error_exit;
363 }
364 memset((void *)gl_bta_adv_data_ptr, 0, sizeof(tBTA_BLE_ADV_DATA));
365
366 if ((gl_bta_scan_rsp_data_ptr = (tBTA_BLE_ADV_DATA *)osi_malloc(sizeof(tBTA_BLE_ADV_DATA))) == NULL) {
367 goto error_exit;
368 }
369 memset((void *)gl_bta_scan_rsp_data_ptr, 0, sizeof(tBTA_BLE_ADV_DATA));
370 #endif ///BLE_INCLUDED == TRUE
371
372 #if GATTS_INCLUDED == TRUE && GATT_DYNAMIC_MEMORY == TRUE
373 if ((btc_creat_tab_env_ptr = (esp_btc_creat_tab_t *)osi_malloc(sizeof(esp_btc_creat_tab_t))) == NULL) {
374 goto error_exit;
375 }
376 memset((void *)btc_creat_tab_env_ptr, 0, sizeof(esp_btc_creat_tab_t));
377 #if (BLUFI_INCLUDED == TRUE)
378 if ((blufi_env_ptr = (tBLUFI_ENV *)osi_malloc(sizeof(tBLUFI_ENV))) == NULL) {
379 goto error_exit;
380 }
381 memset((void *)blufi_env_ptr, 0, sizeof(tBLUFI_ENV));
382 #endif
383 #endif
384
385 #if BTC_HF_CLIENT_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE
386 if ((hf_client_local_param_ptr = (hf_client_local_param_t *)osi_malloc(sizeof(hf_client_local_param_t))) == NULL) {
387 goto error_exit;
388 }
389 memset((void *)hf_client_local_param_ptr, 0, sizeof(hf_client_local_param_t));
390 #endif
391
392 #if BTC_AV_INCLUDED == TRUE && AVRC_DYNAMIC_MEMORY == TRUE
393 if ((btc_rc_cb_ptr = (btc_rc_cb_t *)osi_malloc(sizeof(btc_rc_cb_t))) == NULL) {
394 goto error_exit;
395 }
396 memset((void *)btc_rc_cb_ptr, 0, sizeof(btc_rc_cb_t));
397 if ((bta_av_co_cb_ptr = (tBTA_AV_CO_CB *)osi_malloc(sizeof(tBTA_AV_CO_CB))) == NULL) {
398 goto error_exit;
399 }
400 memset((void *)bta_av_co_cb_ptr, 0, sizeof(tBTA_AV_CO_CB));
401 #endif
402
403 return BT_STATUS_SUCCESS;
404
405 error_exit:;
406 btc_deinit_mem();
407 return BT_STATUS_NOMEM;
408 }
409 #endif ///BTC_DYNAMIC_MEMORY
410
btc_init(void)411 bt_status_t btc_init(void)
412 {
413 btc_thread = osi_thread_create(BTC_TASK_NAME, BTC_TASK_STACK_SIZE, BTC_TASK_PRIO, BTC_TASK_PINNED_TO_CORE, 2);
414 if (btc_thread == NULL) {
415 return BT_STATUS_NOMEM;
416 }
417
418 #if BTC_DYNAMIC_MEMORY
419 if (btc_init_mem() != BT_STATUS_SUCCESS){
420 return BT_STATUS_NOMEM;
421 }
422 #endif
423
424 #if (BLE_INCLUDED == TRUE)
425 btc_gap_callback_init();
426 #endif ///BLE_INCLUDED == TRUE
427
428 #if SCAN_QUEUE_CONGEST_CHECK
429 btc_adv_list_init();
430 #endif
431 /* TODO: initial the profile_tab */
432 return BT_STATUS_SUCCESS;
433 }
434
btc_deinit(void)435 void btc_deinit(void)
436 {
437 #if BTC_DYNAMIC_MEMORY
438 btc_deinit_mem();
439 #endif
440
441 osi_thread_free(btc_thread);
442 btc_thread = NULL;
443
444 #if SCAN_QUEUE_CONGEST_CHECK
445 btc_adv_list_deinit();
446 #endif
447 }
448
btc_check_queue_is_congest(void)449 bool btc_check_queue_is_congest(void)
450 {
451 if (osi_thread_queue_wait_size(btc_thread, 0) >= BT_QUEUE_CONGEST_SIZE) {
452 return true;
453 }
454
455 return false;
456 }
457
get_btc_work_queue_size(void)458 int get_btc_work_queue_size(void)
459 {
460 return osi_thread_queue_wait_size(btc_thread, 0);
461 }
462