Loading system/stack/l2cap/l2c_int.h +12 −1 Original line number Diff line number Diff line Loading @@ -546,6 +546,14 @@ typedef struct { typedef void(tL2C_FCR_MGMT_EVT_HDLR)(uint8_t, tL2C_CCB*); /* Necessary info for postponed TX completion callback */ typedef struct { uint16_t local_cid; uint16_t num_sdu; tL2CA_TX_COMPLETE_CB* cb; } tL2C_TX_COMPLETE_CB_INFO; /* The offset in a buffer that L2CAP will use when building commands. */ #define L2CAP_SEND_CMD_OFFSET 0 Loading Loading @@ -631,6 +639,8 @@ extern void l2cu_set_acl_hci_header(BT_HDR* p_buf, tL2C_CCB* p_ccb); extern void l2cu_check_channel_congestion(tL2C_CCB* p_ccb); extern void l2cu_disconnect_chnl(tL2C_CCB* p_ccb); extern void l2cu_tx_complete(tL2C_TX_COMPLETE_CB_INFO* p_cbi); #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) extern void l2cu_set_non_flushable_pbf(bool); #endif Loading Loading @@ -701,7 +711,8 @@ extern bool l2cu_create_conn(tL2C_LCB* p_lcb, tBT_TRANSPORT transport); extern bool l2cu_create_conn(tL2C_LCB* p_lcb, tBT_TRANSPORT transport, uint8_t initiating_phys); extern bool l2cu_create_conn_after_switch(tL2C_LCB* p_lcb); extern BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb); extern BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb, tL2C_TX_COMPLETE_CB_INFO* p_cbi); extern void l2cu_resubmit_pending_sec_req(BD_ADDR p_bda); extern void l2cu_initialize_amp_ccb(tL2C_LCB* p_lcb); extern void l2cu_adjust_out_mps(tL2C_CCB* p_ccb); Loading system/stack/l2cap/l2c_link.cc +17 −11 Original line number Diff line number Diff line Loading @@ -45,7 +45,8 @@ extern fixed_queue_t* btu_general_alarm_queue; static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf); static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf, tL2C_TX_COMPLETE_CB_INFO* p_cbi); /******************************************************************************* * Loading Loading @@ -992,6 +993,9 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) { /* Loop through, starting at the next */ for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { /* Check for wraparound */ if (p_lcb == &l2cb.lcb_pool[MAX_L2CAP_LINKS]) p_lcb = &l2cb.lcb_pool[0]; /* If controller window is full, nothing to do */ if (((l2cb.controller_xmit_window == 0 || (l2cb.round_robin_unacked >= l2cb.round_robin_quota)) && Loading @@ -1001,9 +1005,6 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) { l2cb.controller_le_xmit_window == 0))) continue; /* Check for wraparound */ if (p_lcb == &l2cb.lcb_pool[MAX_L2CAP_LINKS]) p_lcb = &l2cb.lcb_pool[0]; if ((!p_lcb->in_use) || (p_lcb->partial_segment_being_sent) || (p_lcb->link_state != LST_CONNECTED) || (p_lcb->link_xmit_quota != 0) || (L2C_LINK_CHECK_POWER_MODE(p_lcb))) Loading @@ -1013,16 +1014,17 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) { if (!list_is_empty(p_lcb->link_xmit_data_q)) { p_buf = (BT_HDR*)list_front(p_lcb->link_xmit_data_q); list_remove(p_lcb->link_xmit_data_q, p_buf); l2c_link_send_to_lower(p_lcb, p_buf); l2c_link_send_to_lower(p_lcb, p_buf, NULL); } else if (single_write) { /* If only doing one write, break out */ break; } /* If nothing on the link queue, check the channel queue */ else { p_buf = l2cu_get_next_buffer_to_send(p_lcb); tL2C_TX_COMPLETE_CB_INFO cbi; p_buf = l2cu_get_next_buffer_to_send(p_lcb, &cbi); if (p_buf != NULL) { l2c_link_send_to_lower(p_lcb, p_buf); l2c_link_send_to_lower(p_lcb, p_buf, &cbi); } } } Loading Loading @@ -1055,7 +1057,7 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) { p_buf = (BT_HDR*)list_front(p_lcb->link_xmit_data_q); list_remove(p_lcb->link_xmit_data_q, p_buf); if (!l2c_link_send_to_lower(p_lcb, p_buf)) break; if (!l2c_link_send_to_lower(p_lcb, p_buf, NULL)) break; } if (!single_write) { Loading @@ -1065,10 +1067,11 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) { (l2cb.controller_le_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_LE))) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) { p_buf = l2cu_get_next_buffer_to_send(p_lcb); tL2C_TX_COMPLETE_CB_INFO cbi; p_buf = l2cu_get_next_buffer_to_send(p_lcb, &cbi); if (p_buf == NULL) break; if (!l2c_link_send_to_lower(p_lcb, p_buf)) break; if (!l2c_link_send_to_lower(p_lcb, p_buf, &cbi)) break; } } Loading @@ -1093,7 +1096,7 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) { * Returns true for success, false for fail * ******************************************************************************/ static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf) { static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf, tL2C_TX_COMPLETE_CB_INFO* p_cbi) { uint16_t num_segs; uint16_t xmit_window, acl_data_size; const controller_t* controller = controller_get_interface(); Loading Loading @@ -1183,6 +1186,9 @@ static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf) { } #endif if (p_cbi) l2cu_tx_complete(p_cbi); return true; } Loading system/stack/l2cap/l2c_utils.cc +14 −5 Original line number Diff line number Diff line Loading @@ -3241,6 +3241,11 @@ static tL2C_CCB* l2cu_get_next_channel(tL2C_LCB* p_lcb) { } #endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */ void l2cu_tx_complete(tL2C_TX_COMPLETE_CB_INFO* p_cbi) { if (p_cbi->cb != NULL) p_cbi->cb(p_cbi->local_cid, p_cbi->num_sdu); } /****************************************************************************** * * Function l2cu_get_next_buffer_to_send Loading @@ -3251,7 +3256,7 @@ static tL2C_CCB* l2cu_get_next_channel(tL2C_LCB* p_lcb) { * Returns pointer to buffer or NULL * ******************************************************************************/ BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb) { BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb, tL2C_TX_COMPLETE_CB_INFO* p_cbi) { tL2C_CCB* p_ccb; BT_HDR* p_buf; Loading @@ -3259,6 +3264,8 @@ BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb) { #if (L2CAP_NUM_FIXED_CHNLS > 0) int xx; p_cbi->cb = NULL; for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) { p_ccb = p_lcb->p_fixed_ccbs[xx]; if (p_ccb == NULL) continue; Loading Loading @@ -3287,12 +3294,14 @@ BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb) { if (!fixed_queue_is_empty(p_ccb->xmit_hold_q)) { p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q); if (NULL == p_buf) { L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send: No data to be sent"); L2CAP_TRACE_ERROR("%s: No data to be sent", __func__); return (NULL); } /* send tx complete */ if (l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb) (*l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb)(p_ccb->local_cid, 1); /* Prepare callback info for TX completion */ p_cbi->cb = l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb; p_cbi->local_cid = p_ccb->local_cid; p_cbi->num_sdu = 1; l2cu_check_channel_congestion(p_ccb); l2cu_set_acl_hci_header(p_buf, p_ccb); Loading Loading
system/stack/l2cap/l2c_int.h +12 −1 Original line number Diff line number Diff line Loading @@ -546,6 +546,14 @@ typedef struct { typedef void(tL2C_FCR_MGMT_EVT_HDLR)(uint8_t, tL2C_CCB*); /* Necessary info for postponed TX completion callback */ typedef struct { uint16_t local_cid; uint16_t num_sdu; tL2CA_TX_COMPLETE_CB* cb; } tL2C_TX_COMPLETE_CB_INFO; /* The offset in a buffer that L2CAP will use when building commands. */ #define L2CAP_SEND_CMD_OFFSET 0 Loading Loading @@ -631,6 +639,8 @@ extern void l2cu_set_acl_hci_header(BT_HDR* p_buf, tL2C_CCB* p_ccb); extern void l2cu_check_channel_congestion(tL2C_CCB* p_ccb); extern void l2cu_disconnect_chnl(tL2C_CCB* p_ccb); extern void l2cu_tx_complete(tL2C_TX_COMPLETE_CB_INFO* p_cbi); #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) extern void l2cu_set_non_flushable_pbf(bool); #endif Loading Loading @@ -701,7 +711,8 @@ extern bool l2cu_create_conn(tL2C_LCB* p_lcb, tBT_TRANSPORT transport); extern bool l2cu_create_conn(tL2C_LCB* p_lcb, tBT_TRANSPORT transport, uint8_t initiating_phys); extern bool l2cu_create_conn_after_switch(tL2C_LCB* p_lcb); extern BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb); extern BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb, tL2C_TX_COMPLETE_CB_INFO* p_cbi); extern void l2cu_resubmit_pending_sec_req(BD_ADDR p_bda); extern void l2cu_initialize_amp_ccb(tL2C_LCB* p_lcb); extern void l2cu_adjust_out_mps(tL2C_CCB* p_ccb); Loading
system/stack/l2cap/l2c_link.cc +17 −11 Original line number Diff line number Diff line Loading @@ -45,7 +45,8 @@ extern fixed_queue_t* btu_general_alarm_queue; static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf); static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf, tL2C_TX_COMPLETE_CB_INFO* p_cbi); /******************************************************************************* * Loading Loading @@ -992,6 +993,9 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) { /* Loop through, starting at the next */ for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { /* Check for wraparound */ if (p_lcb == &l2cb.lcb_pool[MAX_L2CAP_LINKS]) p_lcb = &l2cb.lcb_pool[0]; /* If controller window is full, nothing to do */ if (((l2cb.controller_xmit_window == 0 || (l2cb.round_robin_unacked >= l2cb.round_robin_quota)) && Loading @@ -1001,9 +1005,6 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) { l2cb.controller_le_xmit_window == 0))) continue; /* Check for wraparound */ if (p_lcb == &l2cb.lcb_pool[MAX_L2CAP_LINKS]) p_lcb = &l2cb.lcb_pool[0]; if ((!p_lcb->in_use) || (p_lcb->partial_segment_being_sent) || (p_lcb->link_state != LST_CONNECTED) || (p_lcb->link_xmit_quota != 0) || (L2C_LINK_CHECK_POWER_MODE(p_lcb))) Loading @@ -1013,16 +1014,17 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) { if (!list_is_empty(p_lcb->link_xmit_data_q)) { p_buf = (BT_HDR*)list_front(p_lcb->link_xmit_data_q); list_remove(p_lcb->link_xmit_data_q, p_buf); l2c_link_send_to_lower(p_lcb, p_buf); l2c_link_send_to_lower(p_lcb, p_buf, NULL); } else if (single_write) { /* If only doing one write, break out */ break; } /* If nothing on the link queue, check the channel queue */ else { p_buf = l2cu_get_next_buffer_to_send(p_lcb); tL2C_TX_COMPLETE_CB_INFO cbi; p_buf = l2cu_get_next_buffer_to_send(p_lcb, &cbi); if (p_buf != NULL) { l2c_link_send_to_lower(p_lcb, p_buf); l2c_link_send_to_lower(p_lcb, p_buf, &cbi); } } } Loading Loading @@ -1055,7 +1057,7 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) { p_buf = (BT_HDR*)list_front(p_lcb->link_xmit_data_q); list_remove(p_lcb->link_xmit_data_q, p_buf); if (!l2c_link_send_to_lower(p_lcb, p_buf)) break; if (!l2c_link_send_to_lower(p_lcb, p_buf, NULL)) break; } if (!single_write) { Loading @@ -1065,10 +1067,11 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) { (l2cb.controller_le_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_LE))) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) { p_buf = l2cu_get_next_buffer_to_send(p_lcb); tL2C_TX_COMPLETE_CB_INFO cbi; p_buf = l2cu_get_next_buffer_to_send(p_lcb, &cbi); if (p_buf == NULL) break; if (!l2c_link_send_to_lower(p_lcb, p_buf)) break; if (!l2c_link_send_to_lower(p_lcb, p_buf, &cbi)) break; } } Loading @@ -1093,7 +1096,7 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) { * Returns true for success, false for fail * ******************************************************************************/ static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf) { static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf, tL2C_TX_COMPLETE_CB_INFO* p_cbi) { uint16_t num_segs; uint16_t xmit_window, acl_data_size; const controller_t* controller = controller_get_interface(); Loading Loading @@ -1183,6 +1186,9 @@ static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf) { } #endif if (p_cbi) l2cu_tx_complete(p_cbi); return true; } Loading
system/stack/l2cap/l2c_utils.cc +14 −5 Original line number Diff line number Diff line Loading @@ -3241,6 +3241,11 @@ static tL2C_CCB* l2cu_get_next_channel(tL2C_LCB* p_lcb) { } #endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */ void l2cu_tx_complete(tL2C_TX_COMPLETE_CB_INFO* p_cbi) { if (p_cbi->cb != NULL) p_cbi->cb(p_cbi->local_cid, p_cbi->num_sdu); } /****************************************************************************** * * Function l2cu_get_next_buffer_to_send Loading @@ -3251,7 +3256,7 @@ static tL2C_CCB* l2cu_get_next_channel(tL2C_LCB* p_lcb) { * Returns pointer to buffer or NULL * ******************************************************************************/ BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb) { BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb, tL2C_TX_COMPLETE_CB_INFO* p_cbi) { tL2C_CCB* p_ccb; BT_HDR* p_buf; Loading @@ -3259,6 +3264,8 @@ BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb) { #if (L2CAP_NUM_FIXED_CHNLS > 0) int xx; p_cbi->cb = NULL; for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) { p_ccb = p_lcb->p_fixed_ccbs[xx]; if (p_ccb == NULL) continue; Loading Loading @@ -3287,12 +3294,14 @@ BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb) { if (!fixed_queue_is_empty(p_ccb->xmit_hold_q)) { p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q); if (NULL == p_buf) { L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send: No data to be sent"); L2CAP_TRACE_ERROR("%s: No data to be sent", __func__); return (NULL); } /* send tx complete */ if (l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb) (*l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb)(p_ccb->local_cid, 1); /* Prepare callback info for TX completion */ p_cbi->cb = l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb; p_cbi->local_cid = p_ccb->local_cid; p_cbi->num_sdu = 1; l2cu_check_channel_congestion(p_ccb); l2cu_set_acl_hci_header(p_buf, p_ccb); Loading