blob: e18b4ed2575774b6e48c6fde967301a54a233a85 [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
2 *
3 * Copyright (C) 1999-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 * This file contains the main Bluetooth Upper Layer processing loop.
22 * The Broadcom implementations of L2CAP RFCOMM, SDP and the BTIf run as one
23 * GKI task. This btu_task switches between them.
24 *
25 * Note that there will always be an L2CAP, but there may or may not be an
26 * RFCOMM or SDP. Whether these layers are present or not is determined by
27 * compile switches.
28 *
29 ******************************************************************************/
30
31#include <stdlib.h>
32#include <string.h>
33#include <stdio.h>
34
35#include "bt_target.h"
36#include "gki.h"
37#include "bt_types.h"
38#include "hcimsgs.h"
39#include "l2c_int.h"
40#include "btu.h"
41#include "bt_utils.h"
42
43#include "sdpint.h"
44
45#if ( defined(RFCOMM_INCLUDED) && RFCOMM_INCLUDED == TRUE )
46#include "port_api.h"
47#include "port_ext.h"
48#endif
49
50#include "btm_api.h"
51#include "btm_int.h"
52
53#if (defined(EVAL) && EVAL == TRUE)
54#include "btu_eval.h"
55#endif
56
57#if GAP_INCLUDED == TRUE
58#include "gap_int.h"
59#endif
60
61#if (defined(OBX_INCLUDED) && OBX_INCLUDED == TRUE)
62#include "obx_int.h"
63
64#if (defined(BIP_INCLUDED) && BIP_INCLUDED == TRUE)
65#include "bip_int.h"
66#endif /* BIP */
67
68#if (BPP_SND_INCLUDED == TRUE || BPP_INCLUDED == TRUE)
69#include "bpp_int.h"
70#endif /* BPP */
71
72#endif /* OBX */
73
74#include "bt_trace.h"
75
76/* BTE application task */
77#if APPL_INCLUDED == TRUE
78#include "bte_appl.h"
79#endif
80
81#if (defined(RPC_INCLUDED) && RPC_INCLUDED == TRUE)
82#include "rpct_main.h"
83#endif
84
85#if (defined(BNEP_INCLUDED) && BNEP_INCLUDED == TRUE)
86#include "bnep_int.h"
87#endif
88
89#if (defined(PAN_INCLUDED) && PAN_INCLUDED == TRUE)
90#include "pan_int.h"
91#endif
92
93#if (defined(SAP_SERVER_INCLUDED) && SAP_SERVER_INCLUDED == TRUE)
94#include "sap_int.h"
95#endif
96
97#if (defined(HID_DEV_INCLUDED) && HID_DEV_INCLUDED == TRUE )
98#include "hidd_int.h"
99#endif
100
101#if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE )
102#include "hidh_int.h"
103#endif
104
105#if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
106#include "avdt_int.h"
107#else
108extern void avdt_rcv_sync_info (BT_HDR *p_buf); /* this is for hci_test */
109#endif
110
111#if (defined(MCA_INCLUDED) && MCA_INCLUDED == TRUE)
112#include "mca_api.h"
113#include "mca_defs.h"
114#include "mca_int.h"
115#endif
116
117
118#if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)
119#include "bta_sys.h"
120#endif
121
122#if (BLE_INCLUDED == TRUE)
123#include "gatt_int.h"
124#if (SMP_INCLUDED == TRUE)
125#include "smp_int.h"
126#endif
127#include "btm_ble_int.h"
128#endif
129
130#ifdef __cplusplus
131extern "C"
132{
133#endif
134
135BT_API extern void BTE_InitStack(void);
136
137#ifdef __cplusplus
138}
139#endif
140
141/* Define BTU storage area
142*/
143#if BTU_DYNAMIC_MEMORY == FALSE
144tBTU_CB btu_cb;
145#endif
146
147
148/* Define a function prototype to allow a generic timeout handler */
149typedef void (tUSER_TIMEOUT_FUNC) (TIMER_LIST_ENT *p_tle);
150
151/*******************************************************************************
152**
153** Function btu_task
154**
155** Description This is the main task of the Bluetooth Upper Layers unit.
156** It sits in a loop waiting for messages, and dispatches them
157** to the appropiate handlers.
158**
159** Returns should never return
160**
161*******************************************************************************/
162BTU_API UINT32 btu_task (UINT32 param)
163{
164 UINT16 event;
165 BT_HDR *p_msg;
166 UINT8 i;
167 UINT16 mask;
168 BOOLEAN handled;
169
170#if (defined(HCISU_H4_INCLUDED) && HCISU_H4_INCLUDED == TRUE)
171 /* wait an event that HCISU is ready */
YK Jeffrey Chao48ebe2c2013-04-24 11:38:06 -0700172 BT_TRACE_0(TRACE_LAYER_BTU, TRACE_TYPE_API,
173 "btu_task pending for preload complete event");
174
175 for (;;)
176 {
177 event = GKI_wait (0xFFFF, 0);
178 if (event & EVENT_MASK(GKI_SHUTDOWN_EVT))
179 {
180 /* indicates BT ENABLE abort */
181 BT_TRACE_0(TRACE_LAYER_BTU, TRACE_TYPE_WARNING,
182 "btu_task start abort!");
183 return (0);
184 }
185 else if (event & BT_EVT_PRELOAD_CMPL)
186 {
187 break;
188 }
189 else
190 {
191 BT_TRACE_1(TRACE_LAYER_BTU, TRACE_TYPE_WARNING,
192 "btu_task ignore evt %04x while pending for preload complete",
193 event);
194 }
195 }
196
197 BT_TRACE_0(TRACE_LAYER_BTU, TRACE_TYPE_API,
198 "btu_task received preload complete event");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800199#endif
YK Jeffrey Chao48ebe2c2013-04-24 11:38:06 -0700200
The Android Open Source Project5738f832012-12-12 16:00:35 -0800201 /* Initialize the mandatory core stack control blocks
202 (BTU, BTM, L2CAP, and SDP)
203 */
204 btu_init_core();
205
206 /* Initialize any optional stack components */
207 BTE_InitStack();
208
209#if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)
210 bta_sys_init();
211#endif
212
213 /* Initialise platform trace levels at this point as BTE_InitStack() and bta_sys_init()
214 * reset the control blocks and preset the trace level with XXX_INITIAL_TRACE_LEVEL
215 */
216#if ( BT_USE_TRACES==TRUE )
217 BTE_InitTraceLevels();
218#endif
219
220 /* Send a startup evt message to BTIF_TASK to kickstart the init procedure */
221 GKI_send_event(BTIF_TASK, BT_EVT_TRIGGER_STACK_INIT);
222
223 raise_priority_a2dp(TASK_HIGH_BTU);
224
225 /* Wait for, and process, events */
226 for (;;)
227 {
228 event = GKI_wait (0xFFFF, 0);
229
230 if (event & TASK_MBOX_0_EVT_MASK)
231 {
232 /* Process all messages in the queue */
233 while ((p_msg = (BT_HDR *) GKI_read_mbox (BTU_HCI_RCV_MBOX)) != NULL)
234 {
235 /* Determine the input message type. */
236 switch (p_msg->event & BT_EVT_MASK)
237 {
238 case BT_EVT_TO_BTU_HCI_ACL:
239 /* All Acl Data goes to L2CAP */
240 l2c_rcv_acl_data (p_msg);
241 break;
242
243 case BT_EVT_TO_BTU_L2C_SEG_XMIT:
244 /* L2CAP segment transmit complete */
245 l2c_link_segments_xmitted (p_msg);
246 break;
247
248 case BT_EVT_TO_BTU_HCI_SCO:
249#if BTM_SCO_INCLUDED == TRUE
250 btm_route_sco_data (p_msg);
251 break;
252#endif
253
254 case BT_EVT_TO_BTU_HCI_EVT:
255 btu_hcif_process_event ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
256 GKI_freebuf(p_msg);
257
258#if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
259 /* If host receives events which it doesn't response to, */
260 /* host should start idle timer to enter sleep mode. */
261 btu_check_bt_sleep ();
262#endif
263 break;
264
265 case BT_EVT_TO_BTU_HCI_CMD:
266 btu_hcif_send_cmd ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
267 break;
268
269#if (defined(OBX_INCLUDED) && OBX_INCLUDED == TRUE)
270#if (defined(OBX_SERVER_INCLUDED) && OBX_SERVER_INCLUDED == TRUE)
271 case BT_EVT_TO_OBX_SR_MSG:
272 obx_sr_proc_evt((tOBX_PORT_EVT *)(p_msg + 1));
273 GKI_freebuf (p_msg);
274 break;
275
276 case BT_EVT_TO_OBX_SR_L2C_MSG:
277 obx_sr_proc_l2c_evt((tOBX_L2C_EVT_MSG *)(p_msg + 1));
278 GKI_freebuf (p_msg);
279 break;
280#endif
281
282#if (defined(OBX_CLIENT_INCLUDED) && OBX_CLIENT_INCLUDED == TRUE)
283 case BT_EVT_TO_OBX_CL_MSG:
284 obx_cl_proc_evt((tOBX_PORT_EVT *)(p_msg + 1));
285 GKI_freebuf (p_msg);
286 break;
287
288 case BT_EVT_TO_OBX_CL_L2C_MSG:
289 obx_cl_proc_l2c_evt((tOBX_L2C_EVT_MSG *)(p_msg + 1));
290 GKI_freebuf (p_msg);
291 break;
292#endif
293
294#if (defined(BIP_INCLUDED) && BIP_INCLUDED == TRUE)
295 case BT_EVT_TO_BIP_CMDS :
296 bip_proc_btu_event(p_msg);
297 GKI_freebuf (p_msg);
298 break;
299#endif /* BIP */
300#if (BPP_SND_INCLUDED == TRUE || BPP_INCLUDED == TRUE)
301 case BT_EVT_TO_BPP_PR_CMDS:
302 bpp_pr_proc_event(p_msg);
303 GKI_freebuf (p_msg);
304 break;
305 case BT_EVT_TO_BPP_SND_CMDS:
306 bpp_snd_proc_event(p_msg);
307 GKI_freebuf (p_msg);
308 break;
309
310#endif /* BPP */
311
312#endif /* OBX */
313
314#if (defined(SAP_SERVER_INCLUDED) && SAP_SERVER_INCLUDED == TRUE)
315 case BT_EVT_TO_BTU_SAP :
316 sap_proc_btu_event(p_msg);
317 GKI_freebuf (p_msg);
318 break;
319#endif /* SAP */
320#if (defined(GAP_CONN_INCLUDED) && GAP_CONN_INCLUDED == TRUE && GAP_CONN_POST_EVT_INCLUDED == TRUE)
321 case BT_EVT_TO_GAP_MSG :
322 gap_proc_btu_event(p_msg);
323 GKI_freebuf (p_msg);
324 break;
325#endif
326 case BT_EVT_TO_START_TIMER :
327 /* Start free running 1 second timer for list management */
328 GKI_start_timer (TIMER_0, GKI_SECS_TO_TICKS (1), TRUE);
329 GKI_freebuf (p_msg);
330 break;
331
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800332 case BT_EVT_TO_STOP_TIMER:
333 if (btu_cb.timer_queue.p_first == NULL)
334 {
335 GKI_stop_timer(TIMER_0);
336 }
337 GKI_freebuf (p_msg);
338 break;
339
The Android Open Source Project5738f832012-12-12 16:00:35 -0800340#if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)
341 case BT_EVT_TO_START_QUICK_TIMER :
342 GKI_start_timer (TIMER_2, QUICK_TIMER_TICKS, TRUE);
343 GKI_freebuf (p_msg);
344 break;
345#endif
346
347 default:
348 i = 0;
349 mask = (UINT16) (p_msg->event & BT_EVT_MASK);
350 handled = FALSE;
351
352 for (; !handled && i < BTU_MAX_REG_EVENT; i++)
353 {
354 if (btu_cb.event_reg[i].event_cb == NULL)
355 continue;
356
357 if (mask == btu_cb.event_reg[i].event_range)
358 {
359 if (btu_cb.event_reg[i].event_cb)
360 {
361 btu_cb.event_reg[i].event_cb(p_msg);
362 handled = TRUE;
363 }
364 }
365 }
366
367 if (handled == FALSE)
368 GKI_freebuf (p_msg);
369
370 break;
371 }
372 }
373 }
374
375
376 if (event & TIMER_0_EVT_MASK)
377 {
378 TIMER_LIST_ENT *p_tle;
379
380 GKI_update_timer_list (&btu_cb.timer_queue, 1);
381
382 while ((btu_cb.timer_queue.p_first) && (!btu_cb.timer_queue.p_first->ticks))
383 {
384 p_tle = btu_cb.timer_queue.p_first;
385 GKI_remove_from_timer_list (&btu_cb.timer_queue, p_tle);
386
387 switch (p_tle->event)
388 {
389 case BTU_TTYPE_BTM_DEV_CTL:
390 btm_dev_timeout(p_tle);
391 break;
392
393 case BTU_TTYPE_BTM_ACL:
394 btm_acl_timeout(p_tle);
395 break;
396
397 case BTU_TTYPE_L2CAP_LINK:
398 case BTU_TTYPE_L2CAP_CHNL:
399 case BTU_TTYPE_L2CAP_HOLD:
400 case BTU_TTYPE_L2CAP_INFO:
401 case BTU_TTYPE_L2CAP_FCR_ACK:
402
403 l2c_process_timeout (p_tle);
404 break;
405
406 case BTU_TTYPE_SDP:
407 sdp_conn_timeout ((tCONN_CB *)p_tle->param);
408 break;
409
410 case BTU_TTYPE_BTM_RMT_NAME:
411 btm_inq_rmt_name_failed();
412 break;
413
414#if (defined(RFCOMM_INCLUDED) && RFCOMM_INCLUDED == TRUE)
415 case BTU_TTYPE_RFCOMM_MFC:
416 case BTU_TTYPE_RFCOMM_PORT:
417 rfcomm_process_timeout (p_tle);
418 break;
419
420#endif /* If defined(RFCOMM_INCLUDED) && RFCOMM_INCLUDED == TRUE */
421
422#if ((defined(BNEP_INCLUDED) && BNEP_INCLUDED == TRUE))
423 case BTU_TTYPE_BNEP:
424 bnep_process_timeout(p_tle);
425 break;
426#endif
427
428
429#if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
430 case BTU_TTYPE_AVDT_CCB_RET:
431 case BTU_TTYPE_AVDT_CCB_RSP:
432 case BTU_TTYPE_AVDT_CCB_IDLE:
433 case BTU_TTYPE_AVDT_SCB_TC:
434 avdt_process_timeout(p_tle);
435 break;
436#endif
437
438#if (defined(OBX_INCLUDED) && OBX_INCLUDED == TRUE)
439#if (defined(OBX_CLIENT_INCLUDED) && OBX_CLIENT_INCLUDED == TRUE)
440 case BTU_TTYPE_OBX_CLIENT_TO:
441 obx_cl_timeout(p_tle);
442 break;
443#endif
444#if (defined(OBX_SERVER_INCLUDED) && OBX_SERVER_INCLUDED == TRUE)
445 case BTU_TTYPE_OBX_SERVER_TO:
446 obx_sr_timeout(p_tle);
447 break;
448
449 case BTU_TTYPE_OBX_SVR_SESS_TO:
450 obx_sr_sess_timeout(p_tle);
451 break;
452#endif
453#endif
454
455#if (defined(SAP_SERVER_INCLUDED) && SAP_SERVER_INCLUDED == TRUE)
456 case BTU_TTYPE_SAP_TO:
457 sap_process_timeout(p_tle);
458 break;
459#endif
460
461 case BTU_TTYPE_BTU_CMD_CMPL:
462 btu_hcif_cmd_timeout((UINT8)(p_tle->event - BTU_TTYPE_BTU_CMD_CMPL));
463 break;
464
465#if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE)
466 case BTU_TTYPE_HID_HOST_REPAGE_TO :
467 hidh_proc_repage_timeout(p_tle);
468 break;
469#endif
470
471#if (defined(BLE_INCLUDED) && BLE_INCLUDED == TRUE)
472 case BTU_TTYPE_BLE_INQUIRY:
473 case BTU_TTYPE_BLE_GAP_LIM_DISC:
474 case BTU_TTYPE_BLE_RANDOM_ADDR:
475 btm_ble_timeout(p_tle);
476 break;
477
The Android Open Source Project5738f832012-12-12 16:00:35 -0800478 case BTU_TTYPE_ATT_WAIT_FOR_RSP:
479 gatt_rsp_timeout(p_tle);
480 break;
481
482 case BTU_TTYPE_ATT_WAIT_FOR_IND_ACK:
483 gatt_ind_ack_timeout(p_tle);
484 break;
485#if (defined(SMP_INCLUDED) && SMP_INCLUDED == TRUE)
486 case BTU_TTYPE_SMP_PAIRING_CMD:
487 smp_rsp_timeout(p_tle);
488 break;
489#endif
490
491#endif
492
493#if (MCA_INCLUDED == TRUE)
494 case BTU_TTYPE_MCA_CCB_RSP:
495 mca_process_timeout(p_tle);
496 break;
497#endif
498 case BTU_TTYPE_USER_FUNC:
499 {
500 tUSER_TIMEOUT_FUNC *p_uf = (tUSER_TIMEOUT_FUNC *)p_tle->param;
501 (*p_uf)(p_tle);
502 }
503 break;
504
505 default:
506 i = 0;
507 handled = FALSE;
508
509 for (; !handled && i < BTU_MAX_REG_TIMER; i++)
510 {
511 if (btu_cb.timer_reg[i].timer_cb == NULL)
512 continue;
513 if (btu_cb.timer_reg[i].p_tle == p_tle)
514 {
515 btu_cb.timer_reg[i].timer_cb(p_tle);
516 handled = TRUE;
517 }
518 }
519 break;
520 }
521 }
522
523 /* if timer list is empty stop periodic GKI timer */
524 if (btu_cb.timer_queue.p_first == NULL)
525 {
526 GKI_stop_timer(TIMER_0);
527 }
528 }
529
530#if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)
531 if (event & TIMER_2_EVT_MASK)
532 {
533 btu_process_quick_timer_evt();
534 }
535#endif
536
537
538#if (RPC_INCLUDED == TRUE)
539 /* if RPC message queue event */
540 if (event & RPCGEN_MSG_EVT)
541 {
542 if ((p_msg = (BT_HDR *) GKI_read_mbox(RPCGEN_MSG_MBOX)) != NULL)
543 RPCT_RpcgenMsg(p_msg); /* handle RPC message queue */
544 }
545#endif
546
547#if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)
548 if (event & TASK_MBOX_2_EVT_MASK)
549 {
550 while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)
551 {
552 bta_sys_event(p_msg);
553 }
554 }
555
556 if (event & TIMER_1_EVT_MASK)
557 {
558 bta_sys_timer_update();
559 }
560#endif
561
562 if (event & EVENT_MASK(APPL_EVT_7))
563 break;
564 }
565
566 return(0);
567}
568
569/*******************************************************************************
570**
571** Function btu_start_timer
572**
573** Description Start a timer for the specified amount of time.
574** NOTE: The timeout resolution is in SECONDS! (Even
575** though the timer structure field is ticks)
576**
577** Returns void
578**
579*******************************************************************************/
580void btu_start_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout)
581{
582 BT_HDR *p_msg;
583 /* if timer list is currently empty, start periodic GKI timer */
584 if (btu_cb.timer_queue.p_first == NULL)
585 {
586 /* if timer starts on other than BTU task */
587 if (GKI_get_taskid() != BTU_TASK)
588 {
589 /* post event to start timer in BTU task */
590 if ((p_msg = (BT_HDR *)GKI_getbuf(BT_HDR_SIZE)) != NULL)
591 {
592 p_msg->event = BT_EVT_TO_START_TIMER;
593 GKI_send_msg (BTU_TASK, TASK_MBOX_0, p_msg);
594 }
595 }
596 else
597 {
598 /* Start free running 1 second timer for list management */
599 GKI_start_timer (TIMER_0, GKI_SECS_TO_TICKS (1), TRUE);
600 }
601 }
602
603 GKI_remove_from_timer_list (&btu_cb.timer_queue, p_tle);
604
605 p_tle->event = type;
606 p_tle->ticks = timeout; /* Save the number of seconds for the timer */
607
608 GKI_add_to_timer_list (&btu_cb.timer_queue, p_tle);
609}
610
611/*******************************************************************************
612**
613** Function btu_remaining_time
614**
615** Description Return amount of time to expire
616**
617** Returns time in second
618**
619*******************************************************************************/
620UINT32 btu_remaining_time (TIMER_LIST_ENT *p_tle)
621{
622 return(GKI_get_remaining_ticks (&btu_cb.timer_queue, p_tle));
623}
624
625/*******************************************************************************
626**
627** Function btu_stop_timer
628**
629** Description Stop a timer.
630**
631** Returns void
632**
633*******************************************************************************/
634void btu_stop_timer (TIMER_LIST_ENT *p_tle)
635{
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800636 BT_HDR *p_msg;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800637 GKI_remove_from_timer_list (&btu_cb.timer_queue, p_tle);
638
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800639 /* if timer is stopped on other than BTU task */
640 if (GKI_get_taskid() != BTU_TASK)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800641 {
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800642 /* post event to stop timer in BTU task */
643 if ((p_msg = (BT_HDR *)GKI_getbuf(BT_HDR_SIZE)) != NULL)
644 {
645 p_msg->event = BT_EVT_TO_STOP_TIMER;
646 GKI_send_msg (BTU_TASK, TASK_MBOX_0, p_msg);
647 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800648 }
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800649 else
650 {
651 /* if timer list is empty stop periodic GKI timer */
652 if (btu_cb.timer_queue.p_first == NULL)
653 {
654 GKI_stop_timer(TIMER_0);
655 }
656 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800657}
658
659#if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)
660/*******************************************************************************
661**
662** Function btu_start_quick_timer
663**
664** Description Start a timer for the specified amount of time.
665** NOTE: The timeout resolution depends on including modules.
666** QUICK_TIMER_TICKS_PER_SEC should be used to convert from
667** time to ticks.
668**
669**
670** Returns void
671**
672*******************************************************************************/
673void btu_start_quick_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout)
674{
675 BT_HDR *p_msg;
676
677 /* if timer list is currently empty, start periodic GKI timer */
678 if (btu_cb.quick_timer_queue.p_first == NULL)
679 {
680 /* script test calls stack API without posting event */
681 if (GKI_get_taskid() != BTU_TASK)
682 {
683 /* post event to start timer in BTU task */
684 if ((p_msg = (BT_HDR *)GKI_getbuf(BT_HDR_SIZE)) != NULL)
685 {
686 p_msg->event = BT_EVT_TO_START_QUICK_TIMER;
687 GKI_send_msg (BTU_TASK, TASK_MBOX_0, p_msg);
688 }
689 }
690 else
691 GKI_start_timer(TIMER_2, QUICK_TIMER_TICKS, TRUE);
692 }
693
694 GKI_remove_from_timer_list (&btu_cb.quick_timer_queue, p_tle);
695
696 p_tle->event = type;
697 p_tle->ticks = timeout; /* Save the number of ticks for the timer */
698
699 GKI_add_to_timer_list (&btu_cb.quick_timer_queue, p_tle);
700}
701
702
703/*******************************************************************************
704**
705** Function btu_stop_quick_timer
706**
707** Description Stop a timer.
708**
709** Returns void
710**
711*******************************************************************************/
712void btu_stop_quick_timer (TIMER_LIST_ENT *p_tle)
713{
714 GKI_remove_from_timer_list (&btu_cb.quick_timer_queue, p_tle);
715
716 /* if timer list is empty stop periodic GKI timer */
717 if (btu_cb.quick_timer_queue.p_first == NULL)
718 {
719 GKI_stop_timer(TIMER_2);
720 }
721}
722
723/*******************************************************************************
724**
725** Function btu_process_quick_timer_evt
726**
727** Description Process quick timer event
728**
729** Returns void
730**
731*******************************************************************************/
732void btu_process_quick_timer_evt(void)
733{
734 process_quick_timer_evt(&btu_cb.quick_timer_queue);
735
736 /* if timer list is empty stop periodic GKI timer */
737 if (btu_cb.quick_timer_queue.p_first == NULL)
738 {
739 GKI_stop_timer(TIMER_2);
740 }
741}
742
743/*******************************************************************************
744**
745** Function process_quick_timer_evt
746**
747** Description Process quick timer event
748**
749** Returns void
750**
751*******************************************************************************/
752void process_quick_timer_evt(TIMER_LIST_Q *p_tlq)
753{
754 TIMER_LIST_ENT *p_tle;
755
756 GKI_update_timer_list (p_tlq, 1);
757
758 while ((p_tlq->p_first) && (!p_tlq->p_first->ticks))
759 {
760 p_tle = p_tlq->p_first;
761 GKI_remove_from_timer_list (p_tlq, p_tle);
762
763 switch (p_tle->event)
764 {
765 case BTU_TTYPE_L2CAP_CHNL: /* monitor or retransmission timer */
766 case BTU_TTYPE_L2CAP_FCR_ACK: /* ack timer */
767 l2c_process_timeout (p_tle);
768 break;
769
770 default:
771 break;
772 }
773 }
774}
775#endif /* defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0) */
776
777
778
779void btu_register_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout, tBTU_TIMER_CALLBACK timer_cb)
780{
781 UINT8 i = 0;
782 INT8 first = -1;
783 for (; i < BTU_MAX_REG_TIMER; i++)
784 {
785 if (btu_cb.timer_reg[i].p_tle == NULL && first < 0)
786 first = i;
787 if (btu_cb.timer_reg[i].p_tle == p_tle)
788 {
789 btu_cb.timer_reg[i].timer_cb = timer_cb;
790 btu_start_timer(p_tle, type, timeout);
791 first = -1;
792 break;
793 }
794 }
795
796 if (first >= 0 && first < BTU_MAX_REG_TIMER)
797 {
798 btu_cb.timer_reg[first].timer_cb = timer_cb;
799 btu_cb.timer_reg[first].p_tle = p_tle;
800 btu_start_timer(p_tle, type, timeout);
801 }
802
803}
804
805
806void btu_deregister_timer(TIMER_LIST_ENT *p_tle)
807{
808 UINT8 i = 0;
809
810 for (; i < BTU_MAX_REG_TIMER; i++)
811 {
812 if (btu_cb.timer_reg[i].p_tle == p_tle)
813 {
814 btu_stop_timer(p_tle);
815 btu_cb.timer_reg[i].timer_cb = NULL;
816 btu_cb.timer_reg[i].p_tle = NULL;
817 break;
818 }
819 }
820}
821
822void btu_register_event_range (UINT16 start, tBTU_EVENT_CALLBACK event_cb)
823{
824 UINT8 i = 0;
825 INT8 first = -1;
826
827 for (; i < BTU_MAX_REG_EVENT; i++)
828 {
829 if (btu_cb.event_reg[i].event_cb == NULL && first < 0)
830 first = i;
831
832 if (btu_cb.event_reg[i].event_range == start)
833 {
834 btu_cb.event_reg[i].event_cb = event_cb;
835
836 if (!event_cb)
837 btu_cb.event_reg[i].event_range = 0;
838
839 first = -1;
840 }
841 }
842
843 /* if not deregistering && an empty index was found in range, register */
844 if (event_cb && first >= 0 && first < BTU_MAX_REG_EVENT)
845 {
846 btu_cb.event_reg[first].event_range = start;
847 btu_cb.event_reg[first].event_cb = event_cb;
848 }
849}
850
851
852void btu_deregister_event_range (UINT16 range)
853{
854 btu_register_event_range(range, NULL);
855}
856
857#if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
858/*******************************************************************************
859**
860** Function btu_check_bt_sleep
861**
862** Description This function is called to check if controller can go to sleep.
863**
864** Returns void
865**
866*******************************************************************************/
867void btu_check_bt_sleep (void)
868{
869 if ((btu_cb.hci_cmd_cb[LOCAL_BR_EDR_CONTROLLER_ID].cmd_cmpl_q.count == 0)
870 &&(btu_cb.hci_cmd_cb[LOCAL_BR_EDR_CONTROLLER_ID].cmd_xmit_q.count == 0))
871 {
872 if (l2cb.controller_xmit_window == l2cb.num_lm_acl_bufs)
873 {
874 /* enable dev to sleep in the cmd cplt and cmd status only and num cplt packet */
875 HCI_LP_ALLOW_BT_DEVICE_SLEEP();
876 }
877 }
878}
879#endif