btu_task.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  1. /******************************************************************************
  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. #include <string.h>
  19. #include "alarm.h"
  20. #include "thread.h"
  21. #include "bt_target.h"
  22. #include "bt_trace.h"
  23. #include "bt_types.h"
  24. #include "allocator.h"
  25. #include "btm_api.h"
  26. #include "btm_int.h"
  27. #include "btu.h"
  28. #include "fixed_queue.h"
  29. #include "gki.h"
  30. #include "hash_map.h"
  31. #include "hcimsgs.h"
  32. #include "l2c_int.h"
  33. #include "osi.h"
  34. #if (defined(SDP_INCLUDED) && SDP_INCLUDED == TRUE)
  35. #include "sdpint.h"
  36. #endif
  37. #if (defined(RFCOMM_INCLUDED) && RFCOMM_INCLUDED == TRUE)
  38. #include "port_api.h"
  39. #include "port_ext.h"
  40. #endif
  41. #if (defined(GAP_INCLUDED) && GAP_INCLUDED == TRUE)
  42. #include "gap_int.h"
  43. #endif
  44. #if (defined(BNEP_INCLUDED) && BNEP_INCLUDED == TRUE)
  45. #include "bnep_int.h"
  46. #endif
  47. #if (defined(PAN_INCLUDED) && PAN_INCLUDED == TRUE)
  48. #include "pan_int.h"
  49. #endif
  50. #if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE )
  51. #include "hidh_int.h"
  52. #endif
  53. #if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
  54. #include "avdt_int.h"
  55. #else
  56. extern void avdt_rcv_sync_info (BT_HDR *p_buf);
  57. #endif
  58. #if (defined(MCA_INCLUDED) && MCA_INCLUDED == TRUE)
  59. #include "mca_api.h"
  60. #include "mca_defs.h"
  61. #include "mca_int.h"
  62. #endif
  63. #if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
  64. #include "bta_sys.h"
  65. #endif
  66. #if (BLE_INCLUDED == TRUE)
  67. #include "gatt_int.h"
  68. #if (SMP_INCLUDED == TRUE)
  69. #include "smp_int.h"
  70. #endif
  71. #include "btm_ble_int.h"
  72. #endif
  73. //#if (defined(BT_APP_DEMO) && BT_APP_DEMO == TRUE)
  74. //#include "bt_app_common.h"
  75. //#endif
  76. extern void BTE_InitStack(void);
  77. /* Define BTU storage area
  78. */
  79. #if BTU_DYNAMIC_MEMORY == FALSE
  80. tBTU_CB btu_cb;
  81. #endif
  82. // Communication queue between btu_task and bta.
  83. extern fixed_queue_t *btu_bta_msg_queue;
  84. // alarm queue between btu_task and bta
  85. extern fixed_queue_t *btu_bta_alarm_queue;
  86. // Communication queue between btu_task and hci.
  87. extern fixed_queue_t *btu_hci_msg_queue;
  88. // General timer queue.
  89. extern fixed_queue_t *btu_general_alarm_queue;
  90. extern hash_map_t *btu_general_alarm_hash_map;
  91. extern pthread_mutex_t btu_general_alarm_lock;
  92. // Oneshot timer queue.
  93. extern fixed_queue_t *btu_oneshot_alarm_queue;
  94. extern hash_map_t *btu_oneshot_alarm_hash_map;
  95. extern pthread_mutex_t btu_oneshot_alarm_lock;
  96. // l2cap timer queue.
  97. extern fixed_queue_t *btu_l2cap_alarm_queue;
  98. extern hash_map_t *btu_l2cap_alarm_hash_map;
  99. extern pthread_mutex_t btu_l2cap_alarm_lock;
  100. extern fixed_queue_t *event_queue;
  101. //extern fixed_queue_t *btif_msg_queue;
  102. //extern thread_t *bt_workqueue_thread;
  103. extern xTaskHandle xBtuTaskHandle;
  104. extern xQueueHandle xBtuQueue;
  105. extern bluedroid_init_done_cb_t bluedroid_init_done_cb;
  106. /* Define a function prototype to allow a generic timeout handler */
  107. typedef void (tUSER_TIMEOUT_FUNC) (TIMER_LIST_ENT *p_tle);
  108. static void btu_l2cap_alarm_process(TIMER_LIST_ENT *p_tle);
  109. static void btu_general_alarm_process(TIMER_LIST_ENT *p_tle);
  110. static void btu_hci_msg_process(BT_HDR *p_msg);
  111. #if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
  112. static void btu_bta_alarm_process(TIMER_LIST_ENT *p_tle);
  113. #endif
  114. void btu_hci_msg_ready(fixed_queue_t *queue)
  115. {
  116. BT_HDR *p_msg;
  117. while (!fixed_queue_is_empty(queue)) {
  118. p_msg = (BT_HDR *)fixed_queue_dequeue(queue);
  119. btu_hci_msg_process(p_msg);
  120. }
  121. }
  122. void btu_general_alarm_ready(fixed_queue_t *queue)
  123. {
  124. TIMER_LIST_ENT *p_tle;
  125. while (!fixed_queue_is_empty(queue)) {
  126. p_tle = (TIMER_LIST_ENT *)fixed_queue_dequeue(queue);
  127. btu_general_alarm_process(p_tle);
  128. }
  129. }
  130. void btu_oneshot_alarm_ready(fixed_queue_t *queue)
  131. {
  132. TIMER_LIST_ENT *p_tle;
  133. while (!fixed_queue_is_empty(queue)) {
  134. p_tle = (TIMER_LIST_ENT *)fixed_queue_dequeue(queue);
  135. btu_general_alarm_process(p_tle);
  136. switch (p_tle->event) {
  137. #if (defined(BLE_INCLUDED) && BLE_INCLUDED == TRUE)
  138. case BTU_TTYPE_BLE_RANDOM_ADDR:
  139. btm_ble_timeout(p_tle);
  140. break;
  141. #endif
  142. case BTU_TTYPE_USER_FUNC: {
  143. tUSER_TIMEOUT_FUNC *p_uf = (tUSER_TIMEOUT_FUNC *)p_tle->param;
  144. (*p_uf)(p_tle);
  145. }
  146. break;
  147. default:
  148. // FAIL
  149. LOG_ERROR("Received unexpected oneshot timer event:0x%x\n",
  150. p_tle->event);
  151. break;
  152. }
  153. }
  154. }
  155. void btu_l2cap_alarm_ready(fixed_queue_t *queue)
  156. {
  157. TIMER_LIST_ENT *p_tle;
  158. while (!fixed_queue_is_empty(queue)) {
  159. p_tle = (TIMER_LIST_ENT *)fixed_queue_dequeue(queue);
  160. btu_l2cap_alarm_process(p_tle);
  161. }
  162. }
  163. #if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
  164. void btu_bta_msg_ready(fixed_queue_t *queue)
  165. {
  166. BT_HDR *p_msg;
  167. while (!fixed_queue_is_empty(queue)) {
  168. p_msg = (BT_HDR *)fixed_queue_dequeue(queue);
  169. bta_sys_event(p_msg);
  170. }
  171. }
  172. void btu_bta_alarm_ready(fixed_queue_t *queue)
  173. {
  174. TIMER_LIST_ENT *p_tle;
  175. while (!fixed_queue_is_empty(queue)) {
  176. p_tle = (TIMER_LIST_ENT *)fixed_queue_dequeue(queue);
  177. btu_bta_alarm_process(p_tle);
  178. }
  179. }
  180. #endif
  181. static void btu_hci_msg_process(BT_HDR *p_msg)
  182. {
  183. /* Determine the input message type. */
  184. switch (p_msg->event & BT_EVT_MASK) {
  185. case BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK: // TODO(zachoverflow): remove this
  186. ((post_to_task_hack_t *)(&p_msg->data[0]))->callback(p_msg);
  187. break;
  188. case BT_EVT_TO_BTU_HCI_ACL:
  189. /* All Acl Data goes to L2CAP */
  190. l2c_rcv_acl_data (p_msg);
  191. break;
  192. case BT_EVT_TO_BTU_L2C_SEG_XMIT:
  193. /* L2CAP segment transmit complete */
  194. l2c_link_segments_xmitted (p_msg);
  195. break;
  196. case BT_EVT_TO_BTU_HCI_SCO:
  197. #if BTM_SCO_INCLUDED == TRUE
  198. btm_route_sco_data (p_msg);
  199. break;
  200. #endif
  201. case BT_EVT_TO_BTU_HCI_EVT:
  202. btu_hcif_process_event ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
  203. GKI_freebuf(p_msg);
  204. #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
  205. /* If host receives events which it doesn't response to, */
  206. /* host should start idle timer to enter sleep mode. */
  207. btu_check_bt_sleep ();
  208. #endif
  209. break;
  210. case BT_EVT_TO_BTU_HCI_CMD:
  211. btu_hcif_send_cmd ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
  212. break;
  213. default:;
  214. int i = 0;
  215. uint16_t mask = (UINT16) (p_msg->event & BT_EVT_MASK);
  216. BOOLEAN handled = FALSE;
  217. for (; !handled && i < BTU_MAX_REG_EVENT; i++) {
  218. if (btu_cb.event_reg[i].event_cb == NULL) {
  219. continue;
  220. }
  221. if (mask == btu_cb.event_reg[i].event_range) {
  222. if (btu_cb.event_reg[i].event_cb) {
  223. btu_cb.event_reg[i].event_cb(p_msg);
  224. handled = TRUE;
  225. }
  226. }
  227. }
  228. if (handled == FALSE) {
  229. GKI_freebuf (p_msg);
  230. }
  231. break;
  232. }
  233. }
  234. #if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
  235. static void btu_bta_alarm_process(TIMER_LIST_ENT *p_tle)
  236. {
  237. // call timer callback
  238. if (p_tle->p_cback) {
  239. (*p_tle->p_cback)(p_tle);
  240. } else if (p_tle->event) {
  241. BT_HDR *p_msg;
  242. if ((p_msg = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
  243. p_msg->event = p_tle->event;
  244. p_msg->layer_specific = 0;
  245. //GKI_freebuf(p_msg);
  246. bta_sys_sendmsg(p_msg);
  247. }
  248. }
  249. }
  250. #endif
  251. /*****************************************************************************
  252. **
  253. ** Function btu_task_thread_handler
  254. **
  255. ** Description Process BTU Task Thread.
  256. ******************************************************************************/
  257. void btu_task_thread_handler(void *arg)
  258. {
  259. BtTaskEvt_t e;
  260. for (;;) {
  261. if (pdTRUE == xQueueReceive(xBtuQueue, &e, (portTickType)portMAX_DELAY)) {
  262. if (e.sig == SIG_BTU_WORK) {
  263. fixed_queue_process(btu_hci_msg_queue);
  264. #if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
  265. fixed_queue_process(btu_bta_msg_queue);
  266. fixed_queue_process(btu_bta_alarm_queue);
  267. #endif
  268. fixed_queue_process(btu_general_alarm_queue);
  269. fixed_queue_process(btu_oneshot_alarm_queue);
  270. fixed_queue_process(btu_l2cap_alarm_queue);
  271. } else if (e.sig == SIG_BTU_START_UP) {
  272. btu_task_start_up();
  273. }
  274. }
  275. }
  276. }
  277. void btu_task_post(uint32_t sig)
  278. {
  279. BtTaskEvt_t evt;
  280. evt.sig = sig;
  281. evt.par = 0;
  282. if (xQueueSend(xBtuQueue, &evt, 10 / portTICK_PERIOD_MS) != pdTRUE) {
  283. LOG_ERROR("xBtuQueue failed\n");
  284. }
  285. }
  286. void btu_task_start_up(void)
  287. {
  288. #if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
  289. fixed_queue_register_dequeue(btu_bta_msg_queue, btu_bta_msg_ready);
  290. #endif
  291. fixed_queue_register_dequeue(btu_hci_msg_queue, btu_hci_msg_ready);
  292. fixed_queue_register_dequeue(btu_general_alarm_queue, btu_general_alarm_ready);
  293. fixed_queue_register_dequeue(btu_oneshot_alarm_queue, btu_oneshot_alarm_ready);
  294. fixed_queue_register_dequeue(btu_l2cap_alarm_queue, btu_l2cap_alarm_ready);
  295. /* Initialize the mandatory core stack control blocks
  296. (BTU, BTM, L2CAP, and SDP)
  297. */
  298. btu_init_core();
  299. /* Initialize any optional stack components */
  300. BTE_InitStack();
  301. #if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
  302. bta_sys_init();
  303. #endif
  304. // Inform the bt jni thread initialization is ok.
  305. // btif_transfer_context(btif_init_ok, 0, NULL, 0, NULL);
  306. #if(defined(BT_APP_DEMO) && BT_APP_DEMO == TRUE)
  307. if (bluedroid_init_done_cb) {
  308. bluedroid_init_done_cb();
  309. }
  310. #endif
  311. }
  312. void btu_task_shut_down(void)
  313. {
  314. fixed_queue_unregister_dequeue(btu_general_alarm_queue);
  315. fixed_queue_unregister_dequeue(btu_oneshot_alarm_queue);
  316. fixed_queue_unregister_dequeue(btu_l2cap_alarm_queue);
  317. #if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
  318. fixed_queue_unregister_dequeue(btu_bta_msg_queue);
  319. bta_sys_free();
  320. #endif
  321. btu_free_core();
  322. }
  323. /*******************************************************************************
  324. **
  325. ** Function btu_start_timer
  326. **
  327. ** Description Start a timer for the specified amount of time.
  328. ** NOTE: The timeout resolution is in SECONDS! (Even
  329. ** though the timer structure field is ticks)
  330. **
  331. ** Returns void
  332. **
  333. *******************************************************************************/
  334. static void btu_general_alarm_process(TIMER_LIST_ENT *p_tle)
  335. {
  336. assert(p_tle != NULL);
  337. switch (p_tle->event) {
  338. case BTU_TTYPE_BTM_DEV_CTL:
  339. btm_dev_timeout(p_tle);
  340. break;
  341. case BTU_TTYPE_L2CAP_LINK:
  342. case BTU_TTYPE_L2CAP_CHNL:
  343. case BTU_TTYPE_L2CAP_HOLD:
  344. case BTU_TTYPE_L2CAP_INFO:
  345. case BTU_TTYPE_L2CAP_FCR_ACK:
  346. l2c_process_timeout (p_tle);
  347. break;
  348. #if (defined(SDP_INCLUDED) && SDP_INCLUDED == TRUE)
  349. case BTU_TTYPE_SDP:
  350. sdp_conn_timeout ((tCONN_CB *)p_tle->param);
  351. break;
  352. #endif
  353. case BTU_TTYPE_BTM_RMT_NAME:
  354. btm_inq_rmt_name_failed();
  355. break;
  356. #if (defined(RFCOMM_INCLUDED) && RFCOMM_INCLUDED == TRUE)
  357. case BTU_TTYPE_RFCOMM_MFC:
  358. case BTU_TTYPE_RFCOMM_PORT:
  359. rfcomm_process_timeout (p_tle);
  360. break;
  361. #endif
  362. #if ((defined(BNEP_INCLUDED) && BNEP_INCLUDED == TRUE))
  363. case BTU_TTYPE_BNEP:
  364. bnep_process_timeout(p_tle);
  365. break;
  366. #endif
  367. #if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
  368. case BTU_TTYPE_AVDT_CCB_RET:
  369. case BTU_TTYPE_AVDT_CCB_RSP:
  370. case BTU_TTYPE_AVDT_CCB_IDLE:
  371. case BTU_TTYPE_AVDT_SCB_TC:
  372. avdt_process_timeout(p_tle);
  373. break;
  374. #endif
  375. #if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE)
  376. case BTU_TTYPE_HID_HOST_REPAGE_TO :
  377. hidh_proc_repage_timeout(p_tle);
  378. break;
  379. #endif
  380. #if (defined(BLE_INCLUDED) && BLE_INCLUDED == TRUE)
  381. case BTU_TTYPE_BLE_INQUIRY:
  382. case BTU_TTYPE_BLE_GAP_LIM_DISC:
  383. case BTU_TTYPE_BLE_RANDOM_ADDR:
  384. case BTU_TTYPE_BLE_GAP_FAST_ADV:
  385. case BTU_TTYPE_BLE_OBSERVE:
  386. btm_ble_timeout(p_tle);
  387. break;
  388. case BTU_TTYPE_ATT_WAIT_FOR_RSP:
  389. gatt_rsp_timeout(p_tle);
  390. break;
  391. case BTU_TTYPE_ATT_WAIT_FOR_IND_ACK:
  392. gatt_ind_ack_timeout(p_tle);
  393. break;
  394. #if (defined(SMP_INCLUDED) && SMP_INCLUDED == TRUE)
  395. case BTU_TTYPE_SMP_PAIRING_CMD:
  396. smp_rsp_timeout(p_tle);
  397. break;
  398. #endif
  399. #endif
  400. #if (MCA_INCLUDED == TRUE)
  401. case BTU_TTYPE_MCA_CCB_RSP:
  402. mca_process_timeout(p_tle);
  403. break;
  404. #endif
  405. case BTU_TTYPE_USER_FUNC: {
  406. tUSER_TIMEOUT_FUNC *p_uf = (tUSER_TIMEOUT_FUNC *)p_tle->param;
  407. (*p_uf)(p_tle);
  408. }
  409. break;
  410. default:;
  411. int i = 0;
  412. BOOLEAN handled = FALSE;
  413. for (; !handled && i < BTU_MAX_REG_TIMER; i++) {
  414. if (btu_cb.timer_reg[i].timer_cb == NULL) {
  415. continue;
  416. }
  417. if (btu_cb.timer_reg[i].p_tle == p_tle) {
  418. btu_cb.timer_reg[i].timer_cb(p_tle);
  419. handled = TRUE;
  420. }
  421. }
  422. break;
  423. }
  424. }
  425. void btu_general_alarm_cb(void *data)
  426. {
  427. assert(data != NULL);
  428. TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
  429. fixed_queue_enqueue(btu_general_alarm_queue, p_tle);
  430. //ke_event_set(KE_EVENT_BTU_TASK_THREAD);
  431. btu_task_post(SIG_BTU_WORK);
  432. }
  433. void btu_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec)
  434. {
  435. osi_alarm_t *alarm = NULL;
  436. assert(p_tle != NULL);
  437. // Get the alarm for the timer list entry.
  438. pthread_mutex_lock(&btu_general_alarm_lock);
  439. if (!hash_map_has_key(btu_general_alarm_hash_map, p_tle)) {
  440. alarm = osi_alarm_new("btu_gen", btu_general_alarm_cb, (void *)p_tle, 0);
  441. hash_map_set(btu_general_alarm_hash_map, p_tle, alarm);
  442. }
  443. pthread_mutex_unlock(&btu_general_alarm_lock);
  444. alarm = hash_map_get(btu_general_alarm_hash_map, p_tle);
  445. if (alarm == NULL) {
  446. LOG_ERROR("%s Unable to create alarm", __func__);
  447. return;
  448. }
  449. osi_alarm_cancel(alarm);
  450. p_tle->event = type;
  451. // NOTE: This value is in seconds but stored in a ticks field.
  452. p_tle->ticks = timeout_sec;
  453. p_tle->in_use = TRUE;
  454. osi_alarm_set(alarm, (period_ms_t)(timeout_sec * 1000));
  455. }
  456. /*******************************************************************************
  457. **
  458. ** Function btu_stop_timer
  459. **
  460. ** Description Stop a timer.
  461. **
  462. ** Returns void
  463. **
  464. *******************************************************************************/
  465. void btu_stop_timer(TIMER_LIST_ENT *p_tle)
  466. {
  467. assert(p_tle != NULL);
  468. if (p_tle->in_use == FALSE) {
  469. return;
  470. }
  471. p_tle->in_use = FALSE;
  472. // Get the alarm for the timer list entry.
  473. osi_alarm_t *alarm = hash_map_get(btu_general_alarm_hash_map, p_tle);
  474. if (alarm == NULL) {
  475. LOG_WARN("%s Unable to find expected alarm in hashmap", __func__);
  476. return;
  477. }
  478. osi_alarm_cancel(alarm);
  479. }
  480. #if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)
  481. /*******************************************************************************
  482. **
  483. ** Function btu_start_quick_timer
  484. **
  485. ** Description Start a timer for the specified amount of time in ticks.
  486. **
  487. ** Returns void
  488. **
  489. *******************************************************************************/
  490. static void btu_l2cap_alarm_process(TIMER_LIST_ENT *p_tle)
  491. {
  492. assert(p_tle != NULL);
  493. switch (p_tle->event) {
  494. case BTU_TTYPE_L2CAP_CHNL: /* monitor or retransmission timer */
  495. case BTU_TTYPE_L2CAP_FCR_ACK: /* ack timer */
  496. l2c_process_timeout (p_tle);
  497. break;
  498. default:
  499. break;
  500. }
  501. }
  502. static void btu_l2cap_alarm_cb(void *data)
  503. {
  504. assert(data != NULL);
  505. TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
  506. fixed_queue_enqueue(btu_l2cap_alarm_queue, p_tle);
  507. //ke_event_set(KE_EVENT_BTU_TASK_THREAD);
  508. btu_task_post(SIG_BTU_WORK);
  509. }
  510. void btu_start_quick_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_ticks)
  511. {
  512. osi_alarm_t *alarm = NULL;
  513. assert(p_tle != NULL);
  514. // Get the alarm for the timer list entry.
  515. pthread_mutex_lock(&btu_l2cap_alarm_lock);
  516. if (!hash_map_has_key(btu_l2cap_alarm_hash_map, p_tle)) {
  517. alarm = osi_alarm_new("btu_l2cap", btu_l2cap_alarm_cb, (void *)p_tle, 0);
  518. hash_map_set(btu_l2cap_alarm_hash_map, p_tle, (void *)alarm);
  519. }
  520. pthread_mutex_unlock(&btu_l2cap_alarm_lock);
  521. alarm = hash_map_get(btu_l2cap_alarm_hash_map, p_tle);
  522. if (alarm == NULL) {
  523. LOG_ERROR("%s Unable to create alarm", __func__);
  524. return;
  525. }
  526. osi_alarm_cancel(alarm);
  527. p_tle->event = type;
  528. p_tle->ticks = timeout_ticks;
  529. p_tle->in_use = TRUE;
  530. // The quick timer ticks are 100ms long.
  531. osi_alarm_set(alarm, (period_ms_t)(timeout_ticks * 100));
  532. }
  533. /*******************************************************************************
  534. **
  535. ** Function btu_stop_quick_timer
  536. **
  537. ** Description Stop a timer.
  538. **
  539. ** Returns void
  540. **
  541. *******************************************************************************/
  542. void btu_stop_quick_timer(TIMER_LIST_ENT *p_tle)
  543. {
  544. assert(p_tle != NULL);
  545. if (p_tle->in_use == FALSE) {
  546. return;
  547. }
  548. p_tle->in_use = FALSE;
  549. // Get the alarm for the timer list entry.
  550. osi_alarm_t *alarm = hash_map_get(btu_l2cap_alarm_hash_map, p_tle);
  551. if (alarm == NULL) {
  552. LOG_WARN("%s Unable to find expected alarm in hashmap", __func__);
  553. return;
  554. }
  555. osi_alarm_cancel(alarm);
  556. }
  557. #endif /* defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0) */
  558. void btu_oneshot_alarm_cb(void *data)
  559. {
  560. assert(data != NULL);
  561. TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
  562. btu_stop_timer_oneshot(p_tle);
  563. fixed_queue_enqueue(btu_oneshot_alarm_queue, p_tle);
  564. //ke_event_set(KE_EVENT_BTU_TASK_THREAD);
  565. btu_task_post(SIG_BTU_WORK);
  566. }
  567. /*
  568. * Starts a oneshot timer with a timeout in seconds.
  569. */
  570. void btu_start_timer_oneshot(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec)
  571. {
  572. osi_alarm_t *alarm = NULL;
  573. assert(p_tle != NULL);
  574. // Get the alarm for the timer list entry.
  575. pthread_mutex_lock(&btu_oneshot_alarm_lock);
  576. if (!hash_map_has_key(btu_oneshot_alarm_hash_map, p_tle)) {
  577. alarm = osi_alarm_new("btu_oneshot", btu_oneshot_alarm_cb, (void *)p_tle, 0);
  578. hash_map_set(btu_oneshot_alarm_hash_map, p_tle, alarm);
  579. }
  580. pthread_mutex_unlock(&btu_oneshot_alarm_lock);
  581. alarm = hash_map_get(btu_oneshot_alarm_hash_map, p_tle);
  582. if (alarm == NULL) {
  583. LOG_ERROR("%s Unable to create alarm", __func__);
  584. return;
  585. }
  586. osi_alarm_cancel(alarm);
  587. p_tle->event = type;
  588. p_tle->in_use = TRUE;
  589. // NOTE: This value is in seconds but stored in a ticks field.
  590. p_tle->ticks = timeout_sec;
  591. osi_alarm_set(alarm, (period_ms_t)(timeout_sec * 1000));
  592. }
  593. void btu_stop_timer_oneshot(TIMER_LIST_ENT *p_tle)
  594. {
  595. assert(p_tle != NULL);
  596. if (p_tle->in_use == FALSE) {
  597. return;
  598. }
  599. p_tle->in_use = FALSE;
  600. // Get the alarm for the timer list entry.
  601. osi_alarm_t *alarm = hash_map_get(btu_oneshot_alarm_hash_map, p_tle);
  602. if (alarm == NULL) {
  603. LOG_WARN("%s Unable to find expected alarm in hashmap", __func__);
  604. return;
  605. }
  606. osi_alarm_cancel(alarm);
  607. }
  608. #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
  609. /*******************************************************************************
  610. **
  611. ** Function btu_check_bt_sleep
  612. **
  613. ** Description This function is called to check if controller can go to sleep.
  614. **
  615. ** Returns void
  616. **
  617. *******************************************************************************/
  618. void btu_check_bt_sleep (void)
  619. {
  620. // TODO(zachoverflow) take pending commands into account?
  621. if (l2cb.controller_xmit_window == l2cb.num_lm_acl_bufs) {
  622. bte_main_lpm_allow_bt_device_sleep();
  623. }
  624. }
  625. #endif