X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=stack%2Fl2cap%2Fl2c_utils.c;h=ef155ff8beebb3b8132070008444db813ce5d18a;hb=0b47e0a;hp=242b25f786435c8630e8d2f235bb918f398d10cd;hpb=53c9fd05c28d035cf3d2530b586d3d02b68a9866;p=android-x86%2Fsystem-bt.git diff --git a/stack/l2cap/l2c_utils.c b/stack/l2cap/l2c_utils.c index 242b25f78..ef155ff8b 100644 --- a/stack/l2cap/l2c_utils.c +++ b/stack/l2cap/l2c_utils.c @@ -26,6 +26,8 @@ #include #include +#include "device/include/controller.h" +#include "btcore/include/counter.h" #include "gki.h" #include "bt_types.h" #include "hcimsgs.h" @@ -36,8 +38,8 @@ #include "btm_api.h" #include "btm_int.h" #include "hcidefs.h" -#include "bd.h" #include "bt_utils.h" +#include "osi/include/allocator.h" /******************************************************************************* ** @@ -84,6 +86,7 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPOR l2cb.num_links_active++; l2c_link_adjust_allocation(); } + p_lcb->link_xmit_data_q = list_new(NULL); return (p_lcb); } } @@ -174,26 +177,13 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb) } #if (BLE_INCLUDED == TRUE) - l2cb.is_ble_connecting = FALSE; + // Reset BLE connecting flag only if the address matches + if (!memcmp(l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN)) + l2cb.is_ble_connecting = FALSE; #endif #if (L2CAP_NUM_FIXED_CHNLS > 0) - { - int xx; - - for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) - { - if (p_lcb->p_fixed_ccbs[xx]) - { - l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]); - p_lcb->p_fixed_ccbs[xx] = NULL; - (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport); - } - else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL))) - && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) ) - (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport); - } - } + l2cu_process_fixed_disc_cback(p_lcb); #endif /* Ensure no CCBs left on this LCB */ @@ -209,9 +199,18 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb) #else btm_acl_removed (p_lcb->remote_bd_addr, BT_TRANSPORT_BR_EDR); #endif + /* Release any held buffers */ - while (p_lcb->link_xmit_data_q.p_first) - GKI_freebuf (GKI_dequeue (&p_lcb->link_xmit_data_q)); + if (p_lcb->link_xmit_data_q) + { + while (!list_is_empty(p_lcb->link_xmit_data_q)) { + BT_HDR *p_buf = list_front(p_lcb->link_xmit_data_q); + list_remove(p_lcb->link_xmit_data_q, p_buf); + GKI_freebuf(p_buf); + } + list_free(p_lcb->link_xmit_data_q); + p_lcb->link_xmit_data_q = NULL; + } #if (L2CAP_UCD_INCLUDED == TRUE) /* clean up any security pending UCD */ @@ -294,15 +293,6 @@ tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport) *******************************************************************************/ UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb) { - UINT8 i; - for (i = 0; i < BTM_ROLE_DEVICE_NUM; i++) { - if ((btm_cb.previous_connected_role[i] != BTM_ROLE_UNDEFINED) && - (!bdcmp(p_this_lcb->remote_bd_addr, btm_cb.previous_connected_remote_addr[i]))) { - L2CAP_TRACE_WARNING ("l2cu_get_conn_role %d", - btm_cb.previous_connected_role[i]); - return btm_cb.previous_connected_role[i]; - } - } return l2cb.desire_role; } @@ -385,11 +375,16 @@ BT_HDR *l2cu_build_header (tL2C_LCB *p_lcb, UINT16 len, UINT8 cmd, UINT8 id) #if (BLE_INCLUDED == TRUE) if (p_lcb->transport == BT_TRANSPORT_LE) { + counter_add("l2cap.ble.tx.bytes", p_buf->len); + counter_add("l2cap.ble.tx.pkts", 1); + UINT16_TO_STREAM (p, L2CAP_BLE_SIGNALLING_CID); } else #endif { + counter_add("l2cap.sig.tx.bytes", p_buf->len); + counter_add("l2cap.sig.tx.pkts", 1); UINT16_TO_STREAM (p, L2CAP_SIGNALLING_CID); } @@ -943,7 +938,7 @@ void l2cu_send_peer_disc_req (tL2C_CCB *p_ccb) */ if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE) { - while (p_ccb->xmit_hold_q.p_first) + while (GKI_getfirst(&p_ccb->xmit_hold_q)) { p_buf2 = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q); l2cu_set_acl_hci_header (p_buf2, p_ccb); @@ -1057,9 +1052,11 @@ void l2cu_send_peer_echo_rsp (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 d return; } + uint16_t acl_data_size = controller_get_interface()->get_acl_data_size_classic(); + uint16_t acl_packet_size = controller_get_interface()->get_acl_packet_size_classic(); /* Don't return data if it does not fit in ACL and L2CAP MTU */ - maxlen = (GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID) > btu_cb.hcit_acl_pkt_size) ? - btu_cb.hcit_acl_data_size : (UINT16)GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID); + maxlen = (GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID) > acl_packet_size) ? + acl_data_size : (UINT16)GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID); maxlen -= (UINT16)(BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD + L2CAP_ECHO_RSP_LEN); @@ -1523,6 +1520,7 @@ tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid) p_ccb->p_lcb = p_lcb; p_ccb->p_rcb = NULL; + p_ccb->should_free_rcb = false; /* Set priority then insert ccb into LCB queue (if we have an LCB) */ p_ccb->ccb_priority = L2CAP_CHNL_PRIORITY_LOW; @@ -1689,12 +1687,19 @@ void l2cu_release_ccb (tL2C_CCB *p_ccb) btm_sec_clr_service_by_psm(p_rcb->psm); } + if (p_ccb->should_free_rcb) + { + osi_free(p_rcb); + p_ccb->p_rcb = NULL; + p_ccb->should_free_rcb = false; + } + btm_sec_clr_temp_auth_service (p_lcb->remote_bd_addr); /* Stop the timer */ btu_stop_timer (&p_ccb->timer_entry); - while (p_ccb->xmit_hold_q.p_first) + while (!GKI_queue_is_empty(&p_ccb->xmit_hold_q)) GKI_freebuf (GKI_dequeue (&p_ccb->xmit_hold_q)); l2c_fcr_cleanup (p_ccb); @@ -2206,10 +2211,6 @@ void l2cu_device_reset (void) #endif } -#if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE) -extern UINT16 tcs_wug_get_clk_offset( BD_ADDR addr ) ; -#endif - /******************************************************************************* ** ** Function l2cu_create_conn @@ -2236,7 +2237,7 @@ BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport) if (transport == BT_TRANSPORT_LE) { - if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) + if (!controller_get_interface()->supports_ble()) return FALSE; p_lcb->ble_addr_type = addr_type; @@ -2356,35 +2357,21 @@ BOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb) p_lcb->link_state = LST_CONNECTING; - -#if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE) - if ( (clock_offset = tcs_wug_get_clk_offset( p_lcb->remote_bd_addr )) != 0 ) + /* Check with the BT manager if details about remote device are known */ + if ((p_inq_info = BTM_InqDbRead(p_lcb->remote_bd_addr)) != NULL) { - page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R0; - page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE; + page_scan_rep_mode = p_inq_info->results.page_scan_rep_mode; + page_scan_mode = p_inq_info->results.page_scan_mode; + clock_offset = (UINT16)(p_inq_info->results.clock_offset); } else { -#endif - - /* Check with the BT manager if details about remote device are known */ - if ((p_inq_info = BTM_InqDbRead(p_lcb->remote_bd_addr)) != NULL) - { - page_scan_rep_mode = p_inq_info->results.page_scan_rep_mode; - page_scan_mode = p_inq_info->results.page_scan_mode; - clock_offset = (UINT16)(p_inq_info->results.clock_offset); - } - else - { - /* No info known. Use default settings */ - page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R1; - page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE; + /* No info known. Use default settings */ + page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R1; + page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE; - clock_offset = (p_dev_rec) ? p_dev_rec->clock_offset : 0; - } -#if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE) + clock_offset = (p_dev_rec) ? p_dev_rec->clock_offset : 0; } -#endif if (!btsnd_hcic_create_conn (p_lcb->remote_bd_addr, ( HCI_PKT_TYPES_MASK_DM1 | HCI_PKT_TYPES_MASK_DH1 @@ -2401,9 +2388,7 @@ BOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb) return (FALSE); } -#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE) btm_acl_update_busy_level (BTM_BLI_PAGE_EVT); -#endif btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_CONNECT_TOUT); @@ -2829,17 +2814,18 @@ void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb) *******************************************************************************/ void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb) { - int xx; #if (BLE_INCLUDED == TRUE) /* always exclude LE fixed channel on BR/EDR fix channel capability */ if (p_lcb->transport == BT_TRANSPORT_BR_EDR) p_lcb->peer_chnl_mask[0] &= ~(L2CAP_FIXED_CHNL_ATT_BIT| \ L2CAP_FIXED_CHNL_BLE_SIG_BIT| \ L2CAP_FIXED_CHNL_SMP_BIT); + else + p_lcb->peer_chnl_mask[0] = l2cb.l2c_ble_fixed_chnls_mask; #endif /* Tell all registered fixed channels about the connection */ - for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) + for (int xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) { #if BLE_INCLUDED == TRUE /* skip sending LE fix channel callbacks on BR/EDR links */ @@ -2893,21 +2879,32 @@ void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb) void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb) { #if (L2CAP_NUM_FIXED_CHNLS > 0) - int xx; - for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) + /* Select peer channels mask to use depending on transport */ + UINT8 peer_channel_mask = p_lcb->peer_chnl_mask[0]; + + // For LE, reset the stored peer channel mask + if (p_lcb->transport == BT_TRANSPORT_LE) + p_lcb->peer_chnl_mask[0] = 0; + + for (int xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) { if (p_lcb->p_fixed_ccbs[xx]) { - l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]); - p_lcb->p_fixed_ccbs[xx] = NULL; + if (p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb) + { + tL2C_CCB *p_l2c_chnl_ctrl_block; + p_l2c_chnl_ctrl_block = p_lcb->p_fixed_ccbs[xx]; + p_lcb->p_fixed_ccbs[xx] = NULL; + l2cu_release_ccb(p_l2c_chnl_ctrl_block); #if BLE_INCLUDED == TRUE (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport); #else (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR); #endif + } } - else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL))) + else if ( (peer_channel_mask & (1 << (xx + L2CAP_FIRST_FIXED_CHNL))) && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) ) #if BLE_INCLUDED == TRUE (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport); @@ -3114,7 +3111,7 @@ static tL2C_CCB *l2cu_get_next_channel_in_rr(tL2C_LCB *p_lcb) } L2CAP_TRACE_DEBUG("RR scan pri=%d, lcid=0x%04x, q_cout=%d", - p_ccb->ccb_priority, p_ccb->local_cid, p_ccb->xmit_hold_q.count ); + p_ccb->ccb_priority, p_ccb->local_cid, GKI_queue_length(&p_ccb->xmit_hold_q)); /* store the next serving channel */ /* this channel is the last channel of its priority group */ @@ -3139,9 +3136,9 @@ static tL2C_CCB *l2cu_get_next_channel_in_rr(tL2C_LCB *p_lcb) if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy) continue; - if ( p_ccb->fcrb.retrans_q.count == 0 ) + if ( GKI_queue_is_empty(&p_ccb->fcrb.retrans_q)) { - if ( p_ccb->xmit_hold_q.count == 0 ) + if ( GKI_queue_is_empty(&p_ccb->xmit_hold_q)) continue; /* If using the common pool, should be at least 10% free. */ @@ -3155,7 +3152,7 @@ static tL2C_CCB *l2cu_get_next_channel_in_rr(tL2C_LCB *p_lcb) } else { - if (p_ccb->xmit_hold_q.count == 0) + if (GKI_queue_is_empty(&p_ccb->xmit_hold_q)) continue; } @@ -3265,9 +3262,9 @@ BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb) continue; /* No more checks needed if sending from the reatransmit queue */ - if (p_ccb->fcrb.retrans_q.count == 0) + if (GKI_queue_is_empty(&p_ccb->fcrb.retrans_q)) { - if (p_ccb->xmit_hold_q.count == 0) + if (GKI_queue_is_empty(&p_ccb->xmit_hold_q)) continue; /* If using the common pool, should be at least 10% free. */ @@ -3288,7 +3285,7 @@ BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb) } else { - if (p_ccb->xmit_hold_q.count != 0) + if (!GKI_queue_is_empty(&p_ccb->xmit_hold_q)) { p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q); if(NULL == p_buf) @@ -3362,10 +3359,11 @@ void l2cu_set_acl_hci_header (BT_HDR *p_buf, tL2C_CCB *p_ccb) { UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT)); + uint16_t acl_data_size = controller_get_interface()->get_acl_data_size_ble(); /* The HCI transport will segment the buffers. */ - if (p_buf->len > btu_cb.hcit_ble_acl_data_size) + if (p_buf->len > acl_data_size) { - UINT16_TO_STREAM (p, btu_cb.hcit_ble_acl_data_size); + UINT16_TO_STREAM (p, acl_data_size); } else { @@ -3389,10 +3387,11 @@ void l2cu_set_acl_hci_header (BT_HDR *p_buf, tL2C_CCB *p_ccb) UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)); #endif + uint16_t acl_data_size = controller_get_interface()->get_acl_data_size_classic(); /* The HCI transport will segment the buffers. */ - if (p_buf->len > btu_cb.hcit_acl_data_size) + if (p_buf->len > acl_data_size) { - UINT16_TO_STREAM (p, btu_cb.hcit_acl_data_size); + UINT16_TO_STREAM (p, acl_data_size); } else { @@ -3414,7 +3413,7 @@ void l2cu_set_acl_hci_header (BT_HDR *p_buf, tL2C_CCB *p_ccb) *******************************************************************************/ void l2cu_check_channel_congestion (tL2C_CCB *p_ccb) { - UINT16 q_count = p_ccb->xmit_hold_q.count; + UINT16 q_count = GKI_queue_length(&p_ccb->xmit_hold_q); #if (L2CAP_UCD_INCLUDED == TRUE) if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )