1 /******************************************************************************
2 *
3 * Copyright (C) 2009-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * Filename: bte_main.c
22 *
23 * Description: Contains BTE core stack initialization and shutdown code
24 *
25 ******************************************************************************/
26 #include <fcntl.h>
27 #include <stdlib.h>
28 #include <assert.h>
29
30 #include "gki.h"
31 #include "bd.h"
32 #include "btu.h"
33 #include "bte.h"
34 #include "bta_api.h"
35 #include "bt_hci_lib.h"
36
37 /*******************************************************************************
38 ** Constants & Macros
39 *******************************************************************************/
40
41 /* Run-time configuration file */
42 #ifndef BTE_STACK_CONF_FILE
43 #define BTE_STACK_CONF_FILE "/etc/bluetooth/bt_stack.conf"
44 #endif
45
46 /* if not specified in .txt file then use this as default */
47 #ifndef HCI_LOGGING_FILENAME
48 #define HCI_LOGGING_FILENAME "/data/misc/bluedroid/btsnoop_hci.log"
49 #endif
50
51 /*******************************************************************************
52 ** Local type definitions
53 *******************************************************************************/
54
55 /******************************************************************************
56 ** Variables
57 ******************************************************************************/
58 BOOLEAN hci_logging_enabled = FALSE; /* by default, turn hci log off */
59 char hci_logfile[256] = HCI_LOGGING_FILENAME;
60
61
62 /*******************************************************************************
63 ** Static variables
64 *******************************************************************************/
65 static bt_hc_interface_t *bt_hc_if=NULL;
66 static const bt_hc_callbacks_t hc_callbacks;
67 static BOOLEAN lpm_enabled = FALSE;
68
69 /*******************************************************************************
70 ** Static functions
71 *******************************************************************************/
72 static void bte_main_in_hw_init(void);
73
74 /*******************************************************************************
75 ** Externs
76 *******************************************************************************/
77 BTU_API extern UINT32 btu_task (UINT32 param);
78 BTU_API extern void BTE_Init (void);
79 BT_API extern void BTE_LoadStack(void);
80 BT_API void BTE_UnloadStack(void);
81 extern void scru_flip_bda (BD_ADDR dst, const BD_ADDR src);
82 extern void bte_load_conf(const char *p_path);
83
84
85 /*******************************************************************************
86 ** System Task Configuration
87 *******************************************************************************/
88
89 /* bluetooth protocol stack (BTU) task */
90 #ifndef BTE_BTU_STACK_SIZE
91 #define BTE_BTU_STACK_SIZE 0//0x2000 /* In bytes */
92 #endif
93 #define BTE_BTU_TASK_STR ((INT8 *) "BTU")
94 UINT32 bte_btu_stack[(BTE_BTU_STACK_SIZE + 3) / 4];
95
96 /******************************************************************************
97 **
98 ** Function bte_main_in_hw_init
99 **
100 ** Description Internal helper function for chip hardware init
101 **
102 ** Returns None
103 **
104 ******************************************************************************/
bte_main_in_hw_init(void)105 void bte_main_in_hw_init(void)
106 {
107 if ( (bt_hc_if = (bt_hc_interface_t *) bt_hc_get_interface()) \
108 == NULL)
109 {
110 APPL_TRACE_ERROR0("!!! Failed to get BtHostControllerInterface !!!");
111 }
112 }
113
114 /******************************************************************************
115 **
116 ** Function bte_main_boot_entry
117 **
118 ** Description BTE MAIN API - Entry point for BTE chip/stack initialization
119 **
120 ** Returns None
121 **
122 ******************************************************************************/
bte_main_boot_entry(void)123 void bte_main_boot_entry(void)
124 {
125 /* initialize OS */
126 GKI_init();
127
128 bte_main_in_hw_init();
129
130 bte_load_conf(BTE_STACK_CONF_FILE);
131
132 #if (BTTRC_INCLUDED == TRUE)
133 /* Initialize trace feature */
134 BTTRC_TraceInit(MAX_TRACE_RAM_SIZE, &BTE_TraceLogBuf[0], BTTRC_METHOD_RAM);
135 #endif
136 }
137
138 /******************************************************************************
139 **
140 ** Function bte_main_shutdown
141 **
142 ** Description BTE MAIN API - Shutdown code for BTE chip/stack
143 **
144 ** Returns None
145 **
146 ******************************************************************************/
bte_main_shutdown()147 void bte_main_shutdown()
148 {
149 GKI_shutdown();
150 }
151
152 /******************************************************************************
153 **
154 ** Function bte_main_enable
155 **
156 ** Description BTE MAIN API - Creates all the BTE tasks. Should be called
157 ** part of the Bluetooth stack enable sequence
158 **
159 ** Returns None
160 **
161 ******************************************************************************/
bte_main_enable(uint8_t * local_addr)162 void bte_main_enable(uint8_t *local_addr)
163 {
164 APPL_TRACE_DEBUG1("%s", __FUNCTION__);
165
166 /* Initialize BTE control block */
167 BTE_Init();
168
169 lpm_enabled = FALSE;
170
171 if (bt_hc_if)
172 {
173 int result = bt_hc_if->init(&hc_callbacks, local_addr);
174 APPL_TRACE_EVENT1("libbt-hci init returns %d", result);
175
176 assert(result == BT_HC_STATUS_SUCCESS);
177
178 if (hci_logging_enabled == TRUE)
179 bt_hc_if->logging(BT_HC_LOGGING_ON, hci_logfile);
180
181 #if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE)
182 APPL_TRACE_DEBUG1("%s Not Turninig Off the BT before Turninig ON", __FUNCTION__);
183
184 /* Do not power off the chip before powering on if BT_CLEAN_TURN_ON_DISABLED flag
185 is defined and set to TRUE to avoid below mentioned issue.
186
187 Wingray kernel driver maintains a combined counter to keep track of
188 BT-Wifi state. Invoking set_power(BT_HC_CHIP_PWR_OFF) when the BT is already
189 in OFF state causes this counter to be incorrectly decremented and results in undesired
190 behavior of the chip.
191
192 This is only a workaround and when the issue is fixed in the kernel this work around
193 should be removed. */
194 #else
195 /* toggle chip power to ensure we will reset chip in case
196 a previous stack shutdown wasn't completed gracefully */
197 bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF);
198 #endif
199 bt_hc_if->set_power(BT_HC_CHIP_PWR_ON);
200
201 bt_hc_if->preload(NULL);
202 }
203
204 GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,
205 (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),
206 sizeof(bte_btu_stack));
207
208 GKI_run(0);
209 }
210
211 /******************************************************************************
212 **
213 ** Function bte_main_disable
214 **
215 ** Description BTE MAIN API - Destroys all the BTE tasks. Should be called
216 ** part of the Bluetooth stack disable sequence
217 **
218 ** Returns None
219 **
220 ******************************************************************************/
bte_main_disable(void)221 void bte_main_disable(void)
222 {
223 APPL_TRACE_DEBUG1("%s", __FUNCTION__);
224
225 if (bt_hc_if)
226 {
227 bt_hc_if->cleanup();
228 bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF);
229 }
230
231 GKI_destroy_task(BTU_TASK);
232
233 GKI_freeze();
234 }
235
236 /******************************************************************************
237 **
238 ** Function bte_main_postload_cfg
239 **
240 ** Description BTE MAIN API - Stack postload configuration
241 **
242 ** Returns None
243 **
244 ******************************************************************************/
bte_main_postload_cfg(void)245 void bte_main_postload_cfg(void)
246 {
247 if (bt_hc_if)
248 bt_hc_if->postload(NULL);
249 }
250
251 #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
252 /******************************************************************************
253 **
254 ** Function bte_main_enable_lpm
255 **
256 ** Description BTE MAIN API - Enable/Disable low power mode operation
257 **
258 ** Returns None
259 **
260 ******************************************************************************/
bte_main_enable_lpm(BOOLEAN enable)261 void bte_main_enable_lpm(BOOLEAN enable)
262 {
263 int result = -1;
264
265 if (bt_hc_if)
266 result = bt_hc_if->lpm( \
267 (enable == TRUE) ? BT_HC_LPM_ENABLE : BT_HC_LPM_DISABLE \
268 );
269
270 APPL_TRACE_EVENT2("HC lib lpm enable=%d return %d", enable, result);
271 }
272
273 /******************************************************************************
274 **
275 ** Function bte_main_lpm_allow_bt_device_sleep
276 **
277 ** Description BTE MAIN API - Allow BT controller goest to sleep
278 **
279 ** Returns None
280 **
281 ******************************************************************************/
bte_main_lpm_allow_bt_device_sleep()282 void bte_main_lpm_allow_bt_device_sleep()
283 {
284 int result = -1;
285
286 if ((bt_hc_if) && (lpm_enabled == TRUE))
287 result = bt_hc_if->lpm(BT_HC_LPM_WAKE_DEASSERT);
288
289 APPL_TRACE_DEBUG1("HC lib lpm deassertion return %d", result);
290 }
291
292 /******************************************************************************
293 **
294 ** Function bte_main_lpm_wake_bt_device
295 **
296 ** Description BTE MAIN API - Wake BT controller up if it is in sleep mode
297 **
298 ** Returns None
299 **
300 ******************************************************************************/
bte_main_lpm_wake_bt_device()301 void bte_main_lpm_wake_bt_device()
302 {
303 int result = -1;
304
305 if ((bt_hc_if) && (lpm_enabled == TRUE))
306 result = bt_hc_if->lpm(BT_HC_LPM_WAKE_ASSERT);
307
308 APPL_TRACE_DEBUG1("HC lib lpm assertion return %d", result);
309 }
310 #endif // HCILP_INCLUDED
311
312 /******************************************************************************
313 **
314 ** Function bte_main_hci_send
315 **
316 ** Description BTE MAIN API - This function is called by the upper stack to
317 ** send an HCI message. The function displays a protocol trace
318 ** message (if enabled), and then calls the 'transmit' function
319 ** associated with the currently selected HCI transport
320 **
321 ** Returns None
322 **
323 ******************************************************************************/
bte_main_hci_send(BT_HDR * p_msg,UINT16 event)324 void bte_main_hci_send (BT_HDR *p_msg, UINT16 event)
325 {
326 UINT16 sub_event = event & BT_SUB_EVT_MASK; /* local controller ID */
327
328 p_msg->event = event;
329
330
331 if((sub_event == LOCAL_BR_EDR_CONTROLLER_ID) || \
332 (sub_event == LOCAL_BLE_CONTROLLER_ID))
333 {
334 if (bt_hc_if)
335 bt_hc_if->transmit_buf((TRANSAC)p_msg, \
336 (char *) (p_msg + 1), \
337 p_msg->len);
338 else
339 GKI_freebuf(p_msg);
340 }
341 else
342 {
343 APPL_TRACE_ERROR0("Invalid Controller ID. Discarding message.");
344 GKI_freebuf(p_msg);
345 }
346 }
347
348 /******************************************************************************
349 **
350 ** Function bte_main_post_reset_init
351 **
352 ** Description BTE MAIN API - This function is mapped to BTM_APP_DEV_INIT
353 ** and shall be automatically called from BTE after HCI_Reset
354 **
355 ** Returns None
356 **
357 ******************************************************************************/
bte_main_post_reset_init()358 void bte_main_post_reset_init()
359 {
360 BTM_ContinueReset();
361 }
362
363 /*****************************************************************************
364 **
365 ** libbt-hci Callback Functions
366 **
367 *****************************************************************************/
368
369 /******************************************************************************
370 **
371 ** Function preload_cb
372 **
373 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called
374 ** when the libbt-hci completed stack preload process
375 **
376 ** Returns None
377 **
378 ******************************************************************************/
preload_cb(TRANSAC transac,bt_hc_preload_result_t result)379 static void preload_cb(TRANSAC transac, bt_hc_preload_result_t result)
380 {
381 APPL_TRACE_EVENT1("HC preload_cb %d [0:SUCCESS 1:FAIL]", result);
382
383 /* notify BTU task that libbt-hci is ready */
384 /* even if PRELOAD process failed */
385 GKI_send_event(BTU_TASK, TASK_MBOX_0_EVT_MASK);
386 }
387
388 /******************************************************************************
389 **
390 ** Function postload_cb
391 **
392 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called
393 ** when the libbt-hci lib completed stack postload process
394 **
395 ** Returns None
396 **
397 ******************************************************************************/
postload_cb(TRANSAC transac,bt_hc_postload_result_t result)398 static void postload_cb(TRANSAC transac, bt_hc_postload_result_t result)
399 {
400 APPL_TRACE_EVENT1("HC postload_cb %d", result);
401 }
402
403 /******************************************************************************
404 **
405 ** Function lpm_cb
406 **
407 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called
408 ** back from the libbt-hci to indicate the current LPM state
409 **
410 ** Returns None
411 **
412 ******************************************************************************/
lpm_cb(bt_hc_lpm_request_result_t result)413 static void lpm_cb(bt_hc_lpm_request_result_t result)
414 {
415 APPL_TRACE_EVENT1("HC lpm_result_cb %d", result);
416 lpm_enabled = (result == BT_HC_LPM_ENABLED) ? TRUE : FALSE;
417 }
418
419 /******************************************************************************
420 **
421 ** Function hostwake_ind
422 **
423 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called
424 ** from the libbt-hci to indicate the HostWake event
425 **
426 ** Returns None
427 **
428 ******************************************************************************/
hostwake_ind(bt_hc_low_power_event_t event)429 static void hostwake_ind(bt_hc_low_power_event_t event)
430 {
431 APPL_TRACE_EVENT1("HC hostwake_ind %d", event);
432 }
433
434 /******************************************************************************
435 **
436 ** Function alloc
437 **
438 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called
439 ** from the libbt-hci to request for data buffer allocation
440 **
441 ** Returns NULL / pointer to allocated buffer
442 **
443 ******************************************************************************/
alloc(int size)444 static char *alloc(int size)
445 {
446 BT_HDR *p_hdr = NULL;
447
448 /*
449 APPL_TRACE_DEBUG1("HC alloc size=%d", size);
450 */
451
452 p_hdr = (BT_HDR *) GKI_getbuf ((UINT16) size);
453
454 if (p_hdr == NULL)
455 {
456 APPL_TRACE_WARNING0("alloc returns NO BUFFER!");
457 }
458
459 return ((char *) p_hdr);
460 }
461
462 /******************************************************************************
463 **
464 ** Function dealloc
465 **
466 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called
467 ** from the libbt-hci to release the data buffer allocated
468 ** through the alloc call earlier
469 **
470 ** Bluedroid libbt-hci library uses 'transac' parameter to
471 ** pass data-path buffer/packet across bt_hci_lib interface
472 ** boundary. The 'p_buf' is not intended to be used here
473 ** but might point to data portion of data-path buffer.
474 **
475 ** Returns bt_hc_status_t
476 **
477 ******************************************************************************/
dealloc(TRANSAC transac,char * p_buf)478 static int dealloc(TRANSAC transac, char *p_buf)
479 {
480 GKI_freebuf(transac);
481 return BT_HC_STATUS_SUCCESS;
482 }
483
484 /******************************************************************************
485 **
486 ** Function data_ind
487 **
488 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called
489 ** from the libbt-hci to pass in the received HCI packets
490 **
491 ** The core stack is responsible for releasing the data buffer
492 ** passed in from the libbt-hci once the core stack has done
493 ** with it.
494 **
495 ** Bluedroid libbt-hci library uses 'transac' parameter to
496 ** pass data-path buffer/packet across bt_hci_lib interface
497 ** boundary. The 'p_buf' and 'len' parameters are not intended
498 ** to be used here but might point to data portion in data-
499 ** path buffer and length of valid data respectively.
500 **
501 ** Returns bt_hc_status_t
502 **
503 ******************************************************************************/
data_ind(TRANSAC transac,char * p_buf,int len)504 static int data_ind(TRANSAC transac, char *p_buf, int len)
505 {
506 BT_HDR *p_msg = (BT_HDR *) transac;
507
508 /*
509 APPL_TRACE_DEBUG2("HC data_ind event=0x%04X (len=%d)", p_msg->event, len);
510 */
511
512 GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac);
513 return BT_HC_STATUS_SUCCESS;
514 }
515
516 /******************************************************************************
517 **
518 ** Function tx_result
519 **
520 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called
521 ** from the libbt-hci once it has processed/sent the prior data
522 ** buffer which core stack passed to it through transmit_buf
523 ** call earlier.
524 **
525 ** The core stack is responsible for releasing the data buffer
526 ** if it has been completedly processed.
527 **
528 ** Bluedroid libbt-hci library uses 'transac' parameter to
529 ** pass data-path buffer/packet across bt_hci_lib interface
530 ** boundary. The 'p_buf' is not intended to be used here
531 ** but might point to data portion in data-path buffer.
532 **
533 ** Returns bt_hc_status_t
534 **
535 ******************************************************************************/
tx_result(TRANSAC transac,char * p_buf,bt_hc_transmit_result_t result)536 static int tx_result(TRANSAC transac, char *p_buf, \
537 bt_hc_transmit_result_t result)
538 {
539 /*
540 APPL_TRACE_DEBUG2("HC tx_result %d (event=%04X)", result, \
541 ((BT_HDR *)transac)->event);
542 */
543
544 if (result == BT_HC_TX_FRAGMENT)
545 {
546 GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac);
547 }
548 else
549 {
550 GKI_freebuf(transac);
551 }
552
553 return BT_HC_STATUS_SUCCESS;
554 }
555
556 /*****************************************************************************
557 ** The libbt-hci Callback Functions Table
558 *****************************************************************************/
559 static const bt_hc_callbacks_t hc_callbacks = {
560 sizeof(bt_hc_callbacks_t),
561 preload_cb,
562 postload_cb,
563 lpm_cb,
564 hostwake_ind,
565 alloc,
566 dealloc,
567 data_ind,
568 tx_result
569 };
570
571