]> granicus.if.org Git - esp-idf/blob - components/bt/bluedroid/bta/sys/bta_sys_main.c
component/bt : run astyle handle the code files
[esp-idf] / components / bt / bluedroid / bta / sys / bta_sys_main.c
1 /******************************************************************************
2  *
3  *  Copyright (C) 2003-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 is the main implementation file for the BTA system manager.
22  *
23  ******************************************************************************/
24 #define LOG_TAG "bt_bta_sys_main"
25
26 // #include <assert.h>
27 #include <string.h>
28
29 #include "alarm.h"
30 #include "thread.h"
31 #include "btm_api.h"
32 #include "bta_api.h"
33 #include "bta_sys.h"
34 #include "bta_sys_int.h"
35
36 #include "fixed_queue.h"
37 #include "gki.h"
38 #include "hash_map.h"
39 #include "osi.h"
40 #include "hash_functions.h"
41 // #include "osi/include/log.h"
42 // #include "osi/include/thread.h"
43 #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
44 #include "bta_ar_api.h"
45 #endif
46 #include "utl.h"
47
48
49 /* system manager control block definition */
50 #if BTA_DYNAMIC_MEMORY == FALSE
51 tBTA_SYS_CB bta_sys_cb;
52 #endif
53
54 fixed_queue_t *btu_bta_alarm_queue;
55 static hash_map_t *bta_alarm_hash_map;
56 static const size_t BTA_ALARM_HASH_MAP_SIZE = 17;
57 static pthread_mutex_t bta_alarm_lock;
58 // extern thread_t *bt_workqueue_thread;
59
60 /* trace level */
61 /* TODO Bluedroid - Hard-coded trace levels -  Needs to be configurable */
62 UINT8 appl_trace_level = BT_TRACE_LEVEL_WARNING; //APPL_INITIAL_TRACE_LEVEL;
63 UINT8 btif_trace_level = BT_TRACE_LEVEL_WARNING;
64
65 // Communication queue between btu_task and bta.
66 extern fixed_queue_t *btu_bta_msg_queue;
67 void btu_bta_alarm_ready(fixed_queue_t *queue);
68
69 static const tBTA_SYS_REG bta_sys_hw_reg = {
70     bta_sys_sm_execute,
71     NULL
72 };
73
74
75 /* type for action functions */
76 typedef void (*tBTA_SYS_ACTION)(tBTA_SYS_HW_MSG *p_data);
77
78 /* action function list */
79 const tBTA_SYS_ACTION bta_sys_action[] = {
80     /* device manager local device API events - cf bta_sys.h for events */
81     bta_sys_hw_api_enable,             /* 0  BTA_SYS_HW_API_ENABLE_EVT    */
82     bta_sys_hw_evt_enabled,           /* 1  BTA_SYS_HW_EVT_ENABLED_EVT */
83     bta_sys_hw_evt_stack_enabled,       /* 2  BTA_SYS_HW_EVT_STACK_ENABLED_EVT */
84     bta_sys_hw_api_disable,             /* 3  BTA_SYS_HW_API_DISABLE_EVT     */
85     bta_sys_hw_evt_disabled,           /* 4  BTA_SYS_HW_EVT_DISABLED_EVT  */
86     bta_sys_hw_error                        /* 5   BTA_SYS_HW_ERROR_EVT  */
87 };
88
89 /* state machine action enumeration list */
90 enum {
91     /* device manager local device API events */
92     BTA_SYS_HW_API_ENABLE,
93     BTA_SYS_HW_EVT_ENABLED,
94     BTA_SYS_HW_EVT_STACK_ENABLED,
95     BTA_SYS_HW_API_DISABLE,
96     BTA_SYS_HW_EVT_DISABLED,
97     BTA_SYS_HW_ERROR
98 };
99
100 #define BTA_SYS_NUM_ACTIONS  (BTA_SYS_MAX_EVT & 0x00ff)
101 #define BTA_SYS_IGNORE       BTA_SYS_NUM_ACTIONS
102
103 /* state table information */
104 #define BTA_SYS_ACTIONS              2       /* number of actions */
105 #define BTA_SYS_NEXT_STATE           2       /* position of next state */
106 #define BTA_SYS_NUM_COLS             3       /* number of columns in state tables */
107
108
109 /* state table for OFF state */
110 const UINT8 bta_sys_hw_off[][BTA_SYS_NUM_COLS] = {
111     /* Event                    Action 1               Action 2             Next State */
112     /* API_ENABLE    */  {BTA_SYS_HW_API_ENABLE,    BTA_SYS_IGNORE,     BTA_SYS_HW_STARTING},
113     /* EVT_ENABLED   */  {BTA_SYS_IGNORE,           BTA_SYS_IGNORE,     BTA_SYS_HW_STARTING},
114     /* STACK_ENABLED */  {BTA_SYS_IGNORE,           BTA_SYS_IGNORE,     BTA_SYS_HW_ON},
115     /* API_DISABLE   */  {BTA_SYS_HW_EVT_DISABLED,  BTA_SYS_IGNORE,     BTA_SYS_HW_OFF},
116     /* EVT_DISABLED  */  {BTA_SYS_IGNORE,           BTA_SYS_IGNORE,     BTA_SYS_HW_OFF},
117     /* EVT_ERROR     */  {BTA_SYS_IGNORE,           BTA_SYS_IGNORE,     BTA_SYS_HW_OFF}
118 };
119
120 const UINT8 bta_sys_hw_starting[][BTA_SYS_NUM_COLS] = {
121     /* Event                    Action 1                   Action 2               Next State */
122     /* API_ENABLE    */  {BTA_SYS_IGNORE,               BTA_SYS_IGNORE,         BTA_SYS_HW_STARTING}, /* wait for completion event */
123     /* EVT_ENABLED   */  {BTA_SYS_HW_EVT_ENABLED,       BTA_SYS_IGNORE,         BTA_SYS_HW_STARTING},
124     /* STACK_ENABLED */  {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_IGNORE,         BTA_SYS_HW_ON},
125     /* API_DISABLE   */  {BTA_SYS_IGNORE,               BTA_SYS_IGNORE,         BTA_SYS_HW_STOPPING}, /* successive disable/enable: change state wait for completion to disable */
126     /* EVT_DISABLED  */  {BTA_SYS_HW_EVT_DISABLED,      BTA_SYS_HW_API_ENABLE,  BTA_SYS_HW_STARTING}, /* successive enable/disable: notify, then restart HW */
127     /* EVT_ERROR */      {BTA_SYS_HW_ERROR,             BTA_SYS_IGNORE,         BTA_SYS_HW_ON}
128 };
129
130 const UINT8 bta_sys_hw_on[][BTA_SYS_NUM_COLS] = {
131     /* Event                    Action 1                   Action 2               Next State */
132     /* API_ENABLE    */  {BTA_SYS_HW_API_ENABLE,        BTA_SYS_IGNORE,         BTA_SYS_HW_ON},
133     /* EVT_ENABLED   */  {BTA_SYS_IGNORE,               BTA_SYS_IGNORE,         BTA_SYS_HW_ON},
134     /* STACK_ENABLED */  {BTA_SYS_IGNORE,               BTA_SYS_IGNORE,         BTA_SYS_HW_ON},
135     /* API_DISABLE   */  {BTA_SYS_HW_API_DISABLE,       BTA_SYS_IGNORE,         BTA_SYS_HW_ON}, /* don't change the state here, as some other modules might be active */
136     /* EVT_DISABLED */   {BTA_SYS_HW_ERROR,             BTA_SYS_IGNORE,         BTA_SYS_HW_ON},
137     /* EVT_ERROR */      {BTA_SYS_HW_ERROR,             BTA_SYS_IGNORE,         BTA_SYS_HW_ON}
138 };
139
140 const UINT8 bta_sys_hw_stopping[][BTA_SYS_NUM_COLS] = {
141     /* Event                    Action 1                   Action 2               Next State */
142     /* API_ENABLE    */  {BTA_SYS_IGNORE,               BTA_SYS_IGNORE,         BTA_SYS_HW_STARTING}, /* change state, and wait for completion event to enable */
143     /* EVT_ENABLED   */  {BTA_SYS_HW_EVT_ENABLED,       BTA_SYS_IGNORE,         BTA_SYS_HW_STOPPING}, /* successive enable/disable: finish the enable before disabling */
144     /* STACK_ENABLED */  {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_HW_API_DISABLE, BTA_SYS_HW_STOPPING}, /* successive enable/disable: notify, then stop */
145     /* API_DISABLE   */  {BTA_SYS_IGNORE,               BTA_SYS_IGNORE,         BTA_SYS_HW_STOPPING}, /* wait for completion event */
146     /* EVT_DISABLED  */  {BTA_SYS_HW_EVT_DISABLED,      BTA_SYS_IGNORE,         BTA_SYS_HW_OFF},
147     /* EVT_ERROR     */  {BTA_SYS_HW_API_DISABLE,       BTA_SYS_IGNORE,         BTA_SYS_HW_STOPPING}
148 };
149
150 typedef const UINT8 (*tBTA_SYS_ST_TBL)[BTA_SYS_NUM_COLS];
151
152 /* state table */
153 const tBTA_SYS_ST_TBL bta_sys_st_tbl[] = {
154     bta_sys_hw_off,
155     bta_sys_hw_starting,
156     bta_sys_hw_on,
157     bta_sys_hw_stopping
158 };
159
160 /*******************************************************************************
161 **
162 ** Function         bta_sys_init
163 **
164 ** Description      BTA initialization; called from task initialization.
165 **
166 **
167 ** Returns          void
168 **
169 *******************************************************************************/
170 void bta_sys_init(void)
171 {
172     memset(&bta_sys_cb, 0, sizeof(tBTA_SYS_CB));
173
174     pthread_mutex_init(&bta_alarm_lock, NULL);
175
176     bta_alarm_hash_map = hash_map_new(BTA_ALARM_HASH_MAP_SIZE,
177                                       hash_function_pointer, NULL, (data_free_fn)osi_alarm_free, NULL);
178     btu_bta_alarm_queue = fixed_queue_new(SIZE_MAX);
179
180     fixed_queue_register_dequeue(btu_bta_alarm_queue,
181                                  btu_bta_alarm_ready);
182
183     appl_trace_level = APPL_INITIAL_TRACE_LEVEL;
184
185     /* register BTA SYS message handler */
186     bta_sys_register( BTA_ID_SYS,  &bta_sys_hw_reg);
187
188     /* register for BTM notifications */
189     BTM_RegisterForDeviceStatusNotif ((tBTM_DEV_STATUS_CB *)&bta_sys_hw_btm_cback );
190
191 #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
192     bta_ar_init();
193 #endif
194
195 }
196
197 void bta_sys_free(void)
198 {
199     fixed_queue_free(btu_bta_alarm_queue, NULL);
200     hash_map_free(bta_alarm_hash_map);
201     pthread_mutex_destroy(&bta_alarm_lock);
202 }
203
204 /*******************************************************************************
205 **
206 ** Function         bta_dm_sm_execute
207 **
208 ** Description      State machine event handling function for DM
209 **
210 **
211 ** Returns          void
212 **
213 *******************************************************************************/
214 BOOLEAN bta_sys_sm_execute(BT_HDR *p_msg)
215 {
216     BOOLEAN freebuf = TRUE;
217     tBTA_SYS_ST_TBL      state_table;
218     UINT8               action;
219     int                 i;
220
221     APPL_TRACE_EVENT("bta_sys_sm_execute state:%d, event:0x%x\n",  bta_sys_cb.state, p_msg->event);
222
223     /* look up the state table for the current state */
224     state_table = bta_sys_st_tbl[bta_sys_cb.state];
225     /* update state */
226     bta_sys_cb.state = state_table[p_msg->event & 0x00ff][BTA_SYS_NEXT_STATE];
227
228     /* execute action functions */
229     for (i = 0; i < BTA_SYS_ACTIONS; i++) {
230         if ((action = state_table[p_msg->event & 0x00ff][i]) != BTA_SYS_IGNORE) {
231             (*bta_sys_action[action])( (tBTA_SYS_HW_MSG *) p_msg);
232         } else {
233             break;
234         }
235     }
236     return freebuf;
237
238 }
239
240
241 void bta_sys_hw_register( tBTA_SYS_HW_MODULE module, tBTA_SYS_HW_CBACK *cback)
242 {
243     bta_sys_cb.sys_hw_cback[module] = cback;
244 }
245
246
247 void bta_sys_hw_unregister( tBTA_SYS_HW_MODULE module )
248 {
249     bta_sys_cb.sys_hw_cback[module] = NULL;
250 }
251
252 /*******************************************************************************
253 **
254 ** Function         bta_sys_hw_btm_cback
255 **
256 ** Description     This function is registered by BTA SYS to BTM in order to get status notifications
257 **
258 **
259 ** Returns
260 **
261 *******************************************************************************/
262 void bta_sys_hw_btm_cback( tBTM_DEV_STATUS status )
263 {
264
265     tBTA_SYS_HW_MSG *sys_event;
266
267     APPL_TRACE_DEBUG(" bta_sys_hw_btm_cback was called with parameter: %i" , status );
268
269     /* send a message to BTA SYS */
270     if ((sys_event = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL) {
271         if (status == BTM_DEV_STATUS_UP) {
272             sys_event->hdr.event = BTA_SYS_EVT_STACK_ENABLED_EVT;
273         } else if (status == BTM_DEV_STATUS_DOWN) {
274             sys_event->hdr.event = BTA_SYS_ERROR_EVT;
275         } else {
276             /* BTM_DEV_STATUS_CMD_TOUT is ignored for now. */
277             GKI_freebuf (sys_event);
278             sys_event = NULL;
279         }
280
281         if (sys_event) {
282             bta_sys_sendmsg(sys_event);
283         }
284     } else {
285         APPL_TRACE_DEBUG("ERROR bta_sys_hw_btm_cback couldn't send msg" );
286     }
287 }
288
289
290
291 /*******************************************************************************
292 **
293 ** Function         bta_sys_hw_error
294 **
295 ** Description     In case the HW device stops answering... Try to turn it off, then re-enable all
296 **                      previously active SW modules.
297 **
298 ** Returns          success or failure
299 **
300 *******************************************************************************/
301 void bta_sys_hw_error(tBTA_SYS_HW_MSG *p_sys_hw_msg)
302 {
303     UINT8 module_index;
304     UNUSED(p_sys_hw_msg);
305
306     APPL_TRACE_DEBUG("%s\n", __FUNCTION__);
307
308     for (module_index = 0; module_index < BTA_SYS_MAX_HW_MODULES; module_index++) {
309         if ( bta_sys_cb.sys_hw_module_active &  ((UINT32)1 << module_index )) {
310             switch ( module_index) {
311             case BTA_SYS_HW_BLUETOOTH:
312                 /* Send BTA_SYS_HW_ERROR_EVT to DM */
313                 if (bta_sys_cb.sys_hw_cback[module_index] != NULL) {
314                     bta_sys_cb.sys_hw_cback[module_index] (BTA_SYS_HW_ERROR_EVT);
315                 }
316                 break;
317             default:
318                 /* not yet supported */
319                 break;
320             }
321         }
322     }
323 }
324
325
326
327 /*******************************************************************************
328 **
329 ** Function         bta_sys_hw_enable
330 **
331 ** Description     this function is called after API enable and HW has been turned on
332 **
333 **
334 ** Returns          success or failure
335 **
336 *******************************************************************************/
337
338 void bta_sys_hw_api_enable( tBTA_SYS_HW_MSG *p_sys_hw_msg )
339 {
340     if ((!bta_sys_cb.sys_hw_module_active) && (bta_sys_cb.state != BTA_SYS_HW_ON)) {
341         /* register which HW module was turned on */
342         bta_sys_cb.sys_hw_module_active |=  ((UINT32)1 << p_sys_hw_msg->hw_module );
343
344         tBTA_SYS_HW_MSG *p_msg;
345         if ((p_msg = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL) {
346             p_msg->hdr.event = BTA_SYS_EVT_ENABLED_EVT;
347             p_msg->hw_module = p_sys_hw_msg->hw_module;
348
349             bta_sys_sendmsg(p_msg);
350         }
351     } else {
352         /* register which HW module was turned on */
353         bta_sys_cb.sys_hw_module_active |=  ((UINT32)1 << p_sys_hw_msg->hw_module );
354
355         /* HW already in use, so directly notify the caller */
356         if (bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ] != NULL ) {
357             bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ](  BTA_SYS_HW_ON_EVT   );
358         }
359     }
360
361     APPL_TRACE_EVENT ("bta_sys_hw_api_enable for %d, active modules 0x%04X\n",
362                       p_sys_hw_msg->hw_module, bta_sys_cb.sys_hw_module_active);
363
364 }
365
366 /*******************************************************************************
367 **
368 ** Function         bta_sys_hw_disable
369 **
370 ** Description     if no other module is using the HW, this function will call ( if defined ) a user-macro to turn off the HW
371 **
372 **
373 ** Returns          success or failure
374 **
375 *******************************************************************************/
376 void bta_sys_hw_api_disable(tBTA_SYS_HW_MSG *p_sys_hw_msg)
377 {
378     APPL_TRACE_DEBUG("bta_sys_hw_api_disable for %d, active modules: 0x%04X\n",
379                      p_sys_hw_msg->hw_module, bta_sys_cb.sys_hw_module_active );
380
381     /* make sure the related SW blocks were stopped */
382     bta_sys_disable( p_sys_hw_msg->hw_module );
383
384
385     /* register which module we turn off */
386     bta_sys_cb.sys_hw_module_active &=  ~((UINT32)1 << p_sys_hw_msg->hw_module );
387
388
389     /* if there are still some SW modules using the HW, just provide an answer to the calling */
390     if ( bta_sys_cb.sys_hw_module_active != 0  ) {
391         /*  if there are still some SW modules using the HW,  directly notify the caller */
392         if ( bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ] != NULL ) {
393             bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ](  BTA_SYS_HW_OFF_EVT   );
394         }
395     } else {
396         /* manually update the state of our system */
397         bta_sys_cb.state = BTA_SYS_HW_STOPPING;
398
399         tBTA_SYS_HW_MSG *p_msg;
400         if ((p_msg = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL) {
401             p_msg->hdr.event = BTA_SYS_EVT_DISABLED_EVT;
402             p_msg->hw_module = p_sys_hw_msg->hw_module;
403
404             bta_sys_sendmsg(p_msg);
405         }
406     }
407
408 }
409
410
411 /*******************************************************************************
412 **
413 ** Function         bta_sys_hw_event_enabled
414 **
415 ** Description
416 **
417 **
418 ** Returns          success or failure
419 **
420 *******************************************************************************/
421 void bta_sys_hw_evt_enabled(tBTA_SYS_HW_MSG *p_sys_hw_msg)
422 {
423     APPL_TRACE_EVENT("bta_sys_hw_evt_enabled for %i\n", p_sys_hw_msg->hw_module);
424     BTM_DeviceReset( NULL );
425 }
426
427
428 /*******************************************************************************
429 **
430 ** Function         bta_sys_hw_event_disabled
431 **
432 ** Description
433 **
434 **
435 ** Returns          success or failure
436 **
437 *******************************************************************************/
438 void bta_sys_hw_evt_disabled(tBTA_SYS_HW_MSG *p_sys_hw_msg)
439 {
440     UINT8 hw_module_index;
441
442     APPL_TRACE_DEBUG("bta_sys_hw_evt_disabled - module 0x%X\n", p_sys_hw_msg->hw_module);
443
444     for (hw_module_index = 0; hw_module_index < BTA_SYS_MAX_HW_MODULES; hw_module_index++) {
445         if (bta_sys_cb.sys_hw_cback[hw_module_index] != NULL) {
446             bta_sys_cb.sys_hw_cback[hw_module_index] (BTA_SYS_HW_OFF_EVT);
447         }
448     }
449 }
450
451 /*******************************************************************************
452 **
453 ** Function         bta_sys_hw_event_stack_enabled
454 **
455 ** Description     we receive this event once the SW side is ready ( stack, FW download,... ),
456 **                       i.e. we can really start using the device. So notify the app.
457 **
458 ** Returns          success or failure
459 **
460 *******************************************************************************/
461 void bta_sys_hw_evt_stack_enabled(tBTA_SYS_HW_MSG *p_sys_hw_msg)
462 {
463     UINT8 hw_module_index;
464     UNUSED(p_sys_hw_msg);
465
466     APPL_TRACE_DEBUG(" bta_sys_hw_evt_stack_enabled!notify the callers\n");
467
468     for (hw_module_index = 0; hw_module_index < BTA_SYS_MAX_HW_MODULES; hw_module_index++ ) {
469         if (bta_sys_cb.sys_hw_cback[hw_module_index] != NULL) {
470             bta_sys_cb.sys_hw_cback[hw_module_index] (BTA_SYS_HW_ON_EVT);
471         }
472     }
473 }
474
475
476
477
478 /*******************************************************************************
479 **
480 ** Function         bta_sys_event
481 **
482 ** Description      BTA event handler; called from task event handler.
483 **
484 **
485 ** Returns          void
486 **
487 *******************************************************************************/
488 void bta_sys_event(BT_HDR *p_msg)
489 {
490     UINT8       id;
491     BOOLEAN     freebuf = TRUE;
492
493     APPL_TRACE_EVENT("BTA got event 0x%x\n", p_msg->event);
494
495     /* get subsystem id from event */
496     id = (UINT8) (p_msg->event >> 8);
497
498     /* verify id and call subsystem event handler */
499     if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL)) {
500         freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
501     } else {
502         APPL_TRACE_WARNING("BTA got unregistered event id %d\n", id);
503     }
504
505     if (freebuf) {
506         GKI_freebuf(p_msg);
507     }
508
509 }
510
511 /*******************************************************************************
512 **
513 ** Function         bta_sys_register
514 **
515 ** Description      Called by other BTA subsystems to register their event
516 **                  handler.
517 **
518 **
519 ** Returns          void
520 **
521 *******************************************************************************/
522 void bta_sys_register(UINT8 id, const tBTA_SYS_REG *p_reg)
523 {
524     bta_sys_cb.reg[id] = (tBTA_SYS_REG *) p_reg;
525     bta_sys_cb.is_reg[id] = TRUE;
526 }
527
528 /*******************************************************************************
529 **
530 ** Function         bta_sys_deregister
531 **
532 ** Description      Called by other BTA subsystems to de-register
533 **                  handler.
534 **
535 **
536 ** Returns          void
537 **
538 *******************************************************************************/
539 void bta_sys_deregister(UINT8 id)
540 {
541     bta_sys_cb.is_reg[id] = FALSE;
542 }
543
544 /*******************************************************************************
545 **
546 ** Function         bta_sys_is_register
547 **
548 ** Description      Called by other BTA subsystems to get registeration
549 **                  status.
550 **
551 **
552 ** Returns          void
553 **
554 *******************************************************************************/
555 BOOLEAN bta_sys_is_register(UINT8 id)
556 {
557     return bta_sys_cb.is_reg[id];
558 }
559
560 /*******************************************************************************
561 **
562 ** Function         bta_sys_sendmsg
563 **
564 ** Description      Send a GKI message to BTA.  This function is designed to
565 **                  optimize sending of messages to BTA.  It is called by BTA
566 **                  API functions and call-in functions.
567 **
568 **
569 ** Returns          void
570 **
571 *******************************************************************************/
572 void bta_sys_sendmsg(void *p_msg)
573 {
574     // There is a race condition that occurs if the stack is shut down while
575     // there is a procedure in progress that can schedule a task via this
576     // message queue. This causes |btu_bta_msg_queue| to get cleaned up before
577     // it gets used here; hence we check for NULL before using it.
578     if (btu_bta_msg_queue) {
579         fixed_queue_enqueue(btu_bta_msg_queue, p_msg);
580         //ke_event_set(KE_EVENT_BTU_TASK_THREAD);
581         btu_task_post(SIG_BTU_WORK);
582     }
583 }
584
585 /*******************************************************************************
586 **
587 ** Function         bta_sys_start_timer
588 **
589 ** Description      Start a protocol timer for the specified amount
590 **                  of time in milliseconds.
591 **
592 ** Returns          void
593 **
594 *******************************************************************************/
595 void bta_alarm_cb(void *data)
596 {
597     assert(data != NULL);
598     TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
599
600     fixed_queue_enqueue(btu_bta_alarm_queue, p_tle);
601 }
602
603 void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms)
604 {
605     assert(p_tle != NULL);
606
607     // Get the alarm for this p_tle.
608     pthread_mutex_lock(&bta_alarm_lock);
609     if (!hash_map_has_key(bta_alarm_hash_map, p_tle)) {
610         hash_map_set(bta_alarm_hash_map, p_tle, osi_alarm_new("bta_sys", bta_alarm_cb, p_tle, 0));
611     }
612     pthread_mutex_unlock(&bta_alarm_lock);
613
614     osi_alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle);
615     if (alarm == NULL) {
616         LOG_ERROR("%s unable to create alarm.", __func__);
617         return;
618     }
619
620     p_tle->event = type;
621     p_tle->ticks = timeout_ms;
622     //osi_alarm_set(alarm, (period_ms_t)timeout_ms, bta_alarm_cb, p_tle);
623     osi_alarm_set(alarm, (period_ms_t)timeout_ms);
624 }
625
626 bool hash_iter_ro_cb(hash_map_entry_t *hash_map_entry, void *context)
627 {
628     osi_alarm_t *alarm = (osi_alarm_t *)hash_map_entry->data;
629     period_ms_t *p_remaining_ms = (period_ms_t *)context;
630     *p_remaining_ms += osi_alarm_get_remaining_ms(alarm);
631     return true;
632 }
633
634 UINT32 bta_sys_get_remaining_ticks(TIMER_LIST_ENT *p_target_tle)
635 {
636     period_ms_t remaining_ms = 0;
637     pthread_mutex_lock(&bta_alarm_lock);
638     // Get the alarm for this p_tle
639     hash_map_foreach(bta_alarm_hash_map, hash_iter_ro_cb, &remaining_ms);
640     pthread_mutex_unlock(&bta_alarm_lock);
641     return remaining_ms;
642 }
643
644
645 /*******************************************************************************
646 **
647 ** Function         bta_sys_stop_timer
648 **
649 ** Description      Stop a BTA timer.
650 **
651 ** Returns          void
652 **
653 *******************************************************************************/
654 void bta_sys_stop_timer(TIMER_LIST_ENT *p_tle)
655 {
656     assert(p_tle != NULL);
657
658     osi_alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle);
659     if (alarm == NULL) {
660         LOG_DEBUG("%s expected alarm was not in bta alarm hash map.", __func__);
661         return;
662     }
663     osi_alarm_cancel(alarm);
664 }
665
666 /*******************************************************************************
667 **
668 ** Function         bta_sys_disable
669 **
670 ** Description      For each registered subsystem execute its disable function.
671 **
672 ** Returns          void
673 **
674 *******************************************************************************/
675 void bta_sys_disable(tBTA_SYS_HW_MODULE module)
676 {
677     int bta_id = 0;
678     int bta_id_max = 0;
679
680     APPL_TRACE_DEBUG("bta_sys_disable: module %i", module);
681
682     switch ( module ) {
683     case BTA_SYS_HW_BLUETOOTH:
684         bta_id = BTA_ID_DM;
685         bta_id_max = BTA_ID_BLUETOOTH_MAX;
686         break;
687     default:
688         APPL_TRACE_WARNING("bta_sys_disable: unkown module");
689         return;
690     }
691
692     for ( ; bta_id <= bta_id_max; bta_id++) {
693         if (bta_sys_cb.reg[bta_id] != NULL) {
694             if (bta_sys_cb.is_reg[bta_id] == TRUE  &&  bta_sys_cb.reg[bta_id]->disable != NULL) {
695                 (*bta_sys_cb.reg[bta_id]->disable)();
696             }
697         }
698     }
699 }
700
701 /*******************************************************************************
702 **
703 ** Function         bta_sys_set_trace_level
704 **
705 ** Description      Set trace level for BTA
706 **
707 ** Returns          void
708 **
709 *******************************************************************************/
710 void bta_sys_set_trace_level(UINT8 level)
711 {
712     appl_trace_level = level;
713 }
714
715 /*******************************************************************************
716 **
717 ** Function         bta_sys_get_sys_features
718 **
719 ** Description      Returns sys_features to other BTA modules.
720 **
721 ** Returns          sys_features
722 **
723 *******************************************************************************/
724 UINT16 bta_sys_get_sys_features (void)
725 {
726     return bta_sys_cb.sys_features;
727 }