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