/******************************************************************************* ** ** Function nfc_process_timer_evt ** ** Description Process nfc GKI timer event ** ** Returns void ** *******************************************************************************/ void nfc_process_timer_evt (void) { TIMER_LIST_ENT *p_tle; GKI_update_timer_list (&nfc_cb.timer_queue, 1); while ((nfc_cb.timer_queue.p_first) && (!nfc_cb.timer_queue.p_first->ticks)) { p_tle = nfc_cb.timer_queue.p_first; GKI_remove_from_timer_list (&nfc_cb.timer_queue, p_tle); switch (p_tle->event) { case NFC_TTYPE_NCI_WAIT_RSP: nfc_ncif_cmd_timeout(); break; case NFC_TTYPE_WAIT_2_DEACTIVATE: nfc_wait_2_deactivate_timeout (); break; default: NFC_TRACE_DEBUG2 ("nfc_process_timer_evt: timer:0x%x event (0x%04x)", p_tle, p_tle->event); NFC_TRACE_DEBUG1 ("nfc_process_timer_evt: unhandled timer event (0x%04x)", p_tle->event); } } /* if timer list is empty stop periodic GKI timer */ if (nfc_cb.timer_queue.p_first == NULL) { GKI_stop_timer (NFC_TIMER_ID); } }
/******************************************************************************* ** ** Function nfa_sys_ptim_timer_update ** ** Description Update the protocol timer list and handle expired timers. ** This function is called from the task running the protocol ** timers when the periodic GKI timer expires. ** ** Returns void ** *******************************************************************************/ void nfa_sys_ptim_timer_update (tPTIM_CB *p_cb) { TIMER_LIST_ENT *p_tle; BT_HDR *p_msg; UINT32 new_ticks_count; INT32 period_in_ticks; /* To handle the case when the function is called less frequently than the period we must convert determine the number of ticks since the last update, then convert back to milliseconds before updating timer list */ new_ticks_count = GKI_get_tick_count (); /* Check for wrapped condition */ if (new_ticks_count >= p_cb->last_gki_ticks) { period_in_ticks = (INT32) (new_ticks_count - p_cb->last_gki_ticks); } else { period_in_ticks = (INT32) (((UINT32) 0xffffffff - p_cb->last_gki_ticks) + new_ticks_count + 1); } /* update timer list */ GKI_update_timer_list (&p_cb->timer_queue, GKI_TICKS_TO_MS (period_in_ticks)); p_cb->last_gki_ticks = new_ticks_count; /* while there are expired timers */ while ((p_cb->timer_queue.p_first) && (p_cb->timer_queue.p_first->ticks <= 0)) { /* removed expired timer from list */ p_tle = p_cb->timer_queue.p_first; NFA_TRACE_DEBUG1 ("nfa_sys_ptim_timer_update expired: %08x", p_tle); GKI_remove_from_timer_list (&p_cb->timer_queue, p_tle); /* call timer callback */ if (p_tle->p_cback) { (*p_tle->p_cback) (p_tle); } else if (p_tle->event) { if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL) { p_msg->event = p_tle->event; p_msg->layer_specific = 0; nfa_sys_sendmsg (p_msg); } } } /* if timer list is empty stop periodic GKI timer */ if (p_cb->timer_queue.p_first == NULL) { NFA_TRACE_DEBUG0 ("ptim timer stop"); GKI_stop_timer (p_cb->timer_id); } }
/******************************************************************************* ** ** Function nfc_process_quick_timer_evt ** ** Description Process quick timer event ** ** Returns void ** *******************************************************************************/ void nfc_process_quick_timer_evt (void) { TIMER_LIST_ENT *p_tle; GKI_update_timer_list (&nfc_cb.quick_timer_queue, 1); while ((nfc_cb.quick_timer_queue.p_first) && (!nfc_cb.quick_timer_queue.p_first->ticks)) { p_tle = nfc_cb.quick_timer_queue.p_first; GKI_remove_from_timer_list (&nfc_cb.quick_timer_queue, p_tle); switch (p_tle->event) { #if (NFC_RW_ONLY == FALSE) case NFC_TTYPE_LLCP_LINK_MANAGER: case NFC_TTYPE_LLCP_LINK_INACT: case NFC_TTYPE_LLCP_DATA_LINK: case NFC_TTYPE_LLCP_DELAY_FIRST_PDU: llcp_process_timeout (p_tle); break; #endif case NFC_TTYPE_RW_T1T_RESPONSE: rw_t1t_process_timeout (p_tle); break; case NFC_TTYPE_RW_T2T_RESPONSE: rw_t2t_process_timeout (p_tle); break; case NFC_TTYPE_RW_T3T_RESPONSE: rw_t3t_process_timeout (p_tle); break; case NFC_TTYPE_RW_T4T_RESPONSE: rw_t4t_process_timeout (p_tle); break; case NFC_TTYPE_RW_I93_RESPONSE: rw_i93_process_timeout (p_tle); break; #if (NFC_RW_ONLY == FALSE) case NFC_TTYPE_CE_T4T_UPDATE: ce_t4t_process_timeout (p_tle); break; #endif default: NFC_TRACE_DEBUG1 ("nfc_process_quick_timer_evt: unhandled timer event (0x%04x)", p_tle->event); break; } } /* if timer list is empty stop periodic GKI timer */ if (nfc_cb.quick_timer_queue.p_first == NULL) { GKI_stop_timer (NFC_QUICK_TIMER_ID); } }
/******************************************************************************* ** ** Function nfc_process_timer_evt ** ** Description Process nfc GKI timer event ** ** Returns void ** *******************************************************************************/ void nfc_process_timer_evt (void) { TIMER_LIST_ENT *p_tle; GKI_update_timer_list (&nfc_cb.timer_queue, 1); while ((nfc_cb.timer_queue.p_first) && (!nfc_cb.timer_queue.p_first->ticks)) { p_tle = nfc_cb.timer_queue.p_first; GKI_remove_from_timer_list (&nfc_cb.timer_queue, p_tle); switch (p_tle->event) { case NFC_TTYPE_NCI_WAIT_RSP: nfc_ncif_cmd_timeout(); break; case NFC_TTYPE_WAIT_2_DEACTIVATE: nfc_wait_2_deactivate_timeout (); break; case NFC_TTYPE_NCI_WAIT_DATA_NTF: { nfc_cb.i2c_data_t.nci_cmd_channel_busy = 0; nfc_cb.i2c_data_t.data_stored = 0; nfc_ncif_credit_ntf_timeout(); break; } #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) case NFC_TTYPE_LISTEN_ACTIVATION: { extern UINT8 sListenActivated; sListenActivated = FALSE; nfc_ncif_cmd_timeout(); } break; #endif default: NFC_TRACE_DEBUG2 ("nfc_process_timer_evt: timer:0x%x event (0x%04x)", p_tle, p_tle->event); NFC_TRACE_DEBUG1 ("nfc_process_timer_evt: unhandled timer event (0x%04x)", p_tle->event); } } /* if timer list is empty stop periodic GKI timer */ if (nfc_cb.timer_queue.p_first == NULL) { GKI_stop_timer (NFC_TIMER_ID); } }
/******************************************************************************* ** ** Function nfc_hal_main_process_quick_timer_evt ** ** Description Process quick timer event ** ** Returns void ** *******************************************************************************/ static void nfc_hal_main_process_quick_timer_evt (void) { TIMER_LIST_ENT *p_tle; GKI_update_timer_list (&nfc_hal_cb.quick_timer_queue, 1); while ((nfc_hal_cb.quick_timer_queue.p_first) && (!nfc_hal_cb.quick_timer_queue.p_first->ticks)) { p_tle = nfc_hal_cb.quick_timer_queue.p_first; GKI_remove_from_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle); if (p_tle->p_cback) { (*p_tle->p_cback) (p_tle); } } /* if timer list is empty stop periodic GKI timer */ if (nfc_hal_cb.quick_timer_queue.p_first == NULL) { GKI_stop_timer (NFC_HAL_QUICK_TIMER_ID); } }
/******************************************************************************* ** ** Function process_quick_timer_evt ** ** Description Process quick timer event ** ** Returns void ** *******************************************************************************/ void process_quick_timer_evt(TIMER_LIST_Q *p_tlq) { TIMER_LIST_ENT *p_tle; GKI_update_timer_list (p_tlq, 1); while ((p_tlq->p_first) && (!p_tlq->p_first->ticks)) { p_tle = p_tlq->p_first; GKI_remove_from_timer_list (p_tlq, p_tle); switch (p_tle->event) { case BTU_TTYPE_L2CAP_CHNL: /* monitor or retransmission timer */ case BTU_TTYPE_L2CAP_FCR_ACK: /* ack timer */ l2c_process_timeout (p_tle); break; default: break; } } }
/******************************************************************************* ** ** Function btu_task ** ** Description This is the main task of the Bluetooth Upper Layers unit. ** It sits in a loop waiting for messages, and dispatches them ** to the appropiate handlers. ** ** Returns should never return ** *******************************************************************************/ BTU_API UINT32 btu_task (UINT32 param) { UINT16 event; BT_HDR *p_msg; UINT8 i; UINT16 mask; BOOLEAN handled; #if (defined(HCISU_H4_INCLUDED) && HCISU_H4_INCLUDED == TRUE) /* wait an event that HCISU is ready */ GKI_wait(0xFFFF, 0); #endif /* Initialize the mandatory core stack control blocks (BTU, BTM, L2CAP, and SDP) */ btu_init_core(); /* Initialize any optional stack components */ BTE_InitStack(); #if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE) bta_sys_init(); #endif /* Initialise platform trace levels at this point as BTE_InitStack() and bta_sys_init() * reset the control blocks and preset the trace level with XXX_INITIAL_TRACE_LEVEL */ #if ( BT_USE_TRACES==TRUE ) BTE_InitTraceLevels(); #endif /* Send a startup evt message to BTIF_TASK to kickstart the init procedure */ GKI_send_event(BTIF_TASK, BT_EVT_TRIGGER_STACK_INIT); raise_priority_a2dp(TASK_HIGH_BTU); /* Wait for, and process, events */ for (;;) { event = GKI_wait (0xFFFF, 0); if (event & TASK_MBOX_0_EVT_MASK) { /* Process all messages in the queue */ while ((p_msg = (BT_HDR *) GKI_read_mbox (BTU_HCI_RCV_MBOX)) != NULL) { /* Determine the input message type. */ switch (p_msg->event & BT_EVT_MASK) { case BT_EVT_TO_BTU_HCI_ACL: /* All Acl Data goes to L2CAP */ l2c_rcv_acl_data (p_msg); break; case BT_EVT_TO_BTU_L2C_SEG_XMIT: /* L2CAP segment transmit complete */ l2c_link_segments_xmitted (p_msg); break; case BT_EVT_TO_BTU_HCI_SCO: #if BTM_SCO_INCLUDED == TRUE btm_route_sco_data (p_msg); break; #endif case BT_EVT_TO_BTU_HCI_EVT: btu_hcif_process_event ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg); GKI_freebuf(p_msg); #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE) /* If host receives events which it doesn't response to, */ /* host should start idle timer to enter sleep mode. */ btu_check_bt_sleep (); #endif break; case BT_EVT_TO_BTU_HCI_CMD: btu_hcif_send_cmd ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg); break; #if (defined(OBX_INCLUDED) && OBX_INCLUDED == TRUE) #if (defined(OBX_SERVER_INCLUDED) && OBX_SERVER_INCLUDED == TRUE) case BT_EVT_TO_OBX_SR_MSG: obx_sr_proc_evt((tOBX_PORT_EVT *)(p_msg + 1)); GKI_freebuf (p_msg); break; case BT_EVT_TO_OBX_SR_L2C_MSG: obx_sr_proc_l2c_evt((tOBX_L2C_EVT_MSG *)(p_msg + 1)); GKI_freebuf (p_msg); break; #endif #if (defined(OBX_CLIENT_INCLUDED) && OBX_CLIENT_INCLUDED == TRUE) case BT_EVT_TO_OBX_CL_MSG: obx_cl_proc_evt((tOBX_PORT_EVT *)(p_msg + 1)); GKI_freebuf (p_msg); break; case BT_EVT_TO_OBX_CL_L2C_MSG: obx_cl_proc_l2c_evt((tOBX_L2C_EVT_MSG *)(p_msg + 1)); GKI_freebuf (p_msg); break; #endif #if (defined(BIP_INCLUDED) && BIP_INCLUDED == TRUE) case BT_EVT_TO_BIP_CMDS : bip_proc_btu_event(p_msg); GKI_freebuf (p_msg); break; #endif /* BIP */ #if (BPP_SND_INCLUDED == TRUE || BPP_INCLUDED == TRUE) case BT_EVT_TO_BPP_PR_CMDS: bpp_pr_proc_event(p_msg); GKI_freebuf (p_msg); break; case BT_EVT_TO_BPP_SND_CMDS: bpp_snd_proc_event(p_msg); GKI_freebuf (p_msg); break; #endif /* BPP */ #endif /* OBX */ #if (defined(SAP_SERVER_INCLUDED) && SAP_SERVER_INCLUDED == TRUE) case BT_EVT_TO_BTU_SAP : sap_proc_btu_event(p_msg); GKI_freebuf (p_msg); break; #endif /* SAP */ #if (defined(GAP_CONN_INCLUDED) && GAP_CONN_INCLUDED == TRUE && GAP_CONN_POST_EVT_INCLUDED == TRUE) case BT_EVT_TO_GAP_MSG : gap_proc_btu_event(p_msg); GKI_freebuf (p_msg); break; #endif case BT_EVT_TO_START_TIMER : /* Start free running 1 second timer for list management */ GKI_start_timer (TIMER_0, GKI_SECS_TO_TICKS (1), TRUE); GKI_freebuf (p_msg); break; #if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0) case BT_EVT_TO_START_QUICK_TIMER : GKI_start_timer (TIMER_2, QUICK_TIMER_TICKS, TRUE); GKI_freebuf (p_msg); break; #endif default: i = 0; mask = (UINT16) (p_msg->event & BT_EVT_MASK); handled = FALSE; for (; !handled && i < BTU_MAX_REG_EVENT; i++) { if (btu_cb.event_reg[i].event_cb == NULL) continue; if (mask == btu_cb.event_reg[i].event_range) { if (btu_cb.event_reg[i].event_cb) { btu_cb.event_reg[i].event_cb(p_msg); handled = TRUE; } } } if (handled == FALSE) GKI_freebuf (p_msg); break; } } } if (event & TIMER_0_EVT_MASK) { TIMER_LIST_ENT *p_tle; GKI_update_timer_list (&btu_cb.timer_queue, 1); while ((btu_cb.timer_queue.p_first) && (!btu_cb.timer_queue.p_first->ticks)) { p_tle = btu_cb.timer_queue.p_first; GKI_remove_from_timer_list (&btu_cb.timer_queue, p_tle); switch (p_tle->event) { case BTU_TTYPE_BTM_DEV_CTL: btm_dev_timeout(p_tle); break; case BTU_TTYPE_BTM_ACL: btm_acl_timeout(p_tle); break; case BTU_TTYPE_L2CAP_LINK: case BTU_TTYPE_L2CAP_CHNL: case BTU_TTYPE_L2CAP_HOLD: case BTU_TTYPE_L2CAP_INFO: case BTU_TTYPE_L2CAP_FCR_ACK: l2c_process_timeout (p_tle); break; case BTU_TTYPE_SDP: sdp_conn_timeout ((tCONN_CB *)p_tle->param); break; case BTU_TTYPE_BTM_RMT_NAME: btm_inq_rmt_name_failed(); break; #if (defined(RFCOMM_INCLUDED) && RFCOMM_INCLUDED == TRUE) case BTU_TTYPE_RFCOMM_MFC: case BTU_TTYPE_RFCOMM_PORT: rfcomm_process_timeout (p_tle); break; #endif /* If defined(RFCOMM_INCLUDED) && RFCOMM_INCLUDED == TRUE */ #if ((defined(BNEP_INCLUDED) && BNEP_INCLUDED == TRUE)) case BTU_TTYPE_BNEP: bnep_process_timeout(p_tle); break; #endif #if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE) case BTU_TTYPE_AVDT_CCB_RET: case BTU_TTYPE_AVDT_CCB_RSP: case BTU_TTYPE_AVDT_CCB_IDLE: case BTU_TTYPE_AVDT_SCB_TC: avdt_process_timeout(p_tle); break; #endif #if (defined(OBX_INCLUDED) && OBX_INCLUDED == TRUE) #if (defined(OBX_CLIENT_INCLUDED) && OBX_CLIENT_INCLUDED == TRUE) case BTU_TTYPE_OBX_CLIENT_TO: obx_cl_timeout(p_tle); break; #endif #if (defined(OBX_SERVER_INCLUDED) && OBX_SERVER_INCLUDED == TRUE) case BTU_TTYPE_OBX_SERVER_TO: obx_sr_timeout(p_tle); break; case BTU_TTYPE_OBX_SVR_SESS_TO: obx_sr_sess_timeout(p_tle); break; #endif #endif #if (defined(SAP_SERVER_INCLUDED) && SAP_SERVER_INCLUDED == TRUE) case BTU_TTYPE_SAP_TO: sap_process_timeout(p_tle); break; #endif case BTU_TTYPE_BTU_CMD_CMPL: btu_hcif_cmd_timeout((UINT8)(p_tle->event - BTU_TTYPE_BTU_CMD_CMPL)); break; #if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE) case BTU_TTYPE_HID_HOST_REPAGE_TO : hidh_proc_repage_timeout(p_tle); break; #endif #if (defined(BLE_INCLUDED) && BLE_INCLUDED == TRUE) case BTU_TTYPE_BLE_INQUIRY: case BTU_TTYPE_BLE_GAP_LIM_DISC: case BTU_TTYPE_BLE_RANDOM_ADDR: btm_ble_timeout(p_tle); break; case BTU_TTYPE_BLE_SCAN_PARAM_IDLE: btm_ble_scan_param_idle(); break; case BTU_TTYPE_ATT_WAIT_FOR_RSP: gatt_rsp_timeout(p_tle); break; case BTU_TTYPE_ATT_WAIT_FOR_IND_ACK: gatt_ind_ack_timeout(p_tle); break; #if (defined(SMP_INCLUDED) && SMP_INCLUDED == TRUE) case BTU_TTYPE_SMP_PAIRING_CMD: smp_rsp_timeout(p_tle); break; #endif #endif #if (MCA_INCLUDED == TRUE) case BTU_TTYPE_MCA_CCB_RSP: mca_process_timeout(p_tle); break; #endif case BTU_TTYPE_USER_FUNC: { tUSER_TIMEOUT_FUNC *p_uf = (tUSER_TIMEOUT_FUNC *)p_tle->param; (*p_uf)(p_tle); } break; default: i = 0; handled = FALSE; for (; !handled && i < BTU_MAX_REG_TIMER; i++) { if (btu_cb.timer_reg[i].timer_cb == NULL) continue; if (btu_cb.timer_reg[i].p_tle == p_tle) { btu_cb.timer_reg[i].timer_cb(p_tle); handled = TRUE; } } break; } } /* if timer list is empty stop periodic GKI timer */ if (btu_cb.timer_queue.p_first == NULL) { GKI_stop_timer(TIMER_0); } } #if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0) if (event & TIMER_2_EVT_MASK) { btu_process_quick_timer_evt(); } #endif #if (RPC_INCLUDED == TRUE) /* if RPC message queue event */ if (event & RPCGEN_MSG_EVT) { if ((p_msg = (BT_HDR *) GKI_read_mbox(RPCGEN_MSG_MBOX)) != NULL) RPCT_RpcgenMsg(p_msg); /* handle RPC message queue */ } #endif #if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE) if (event & TASK_MBOX_2_EVT_MASK) { while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL) { bta_sys_event(p_msg); } } if (event & TIMER_1_EVT_MASK) { bta_sys_timer_update(); } #endif if (event & EVENT_MASK(APPL_EVT_7)) break; } return(0); }