Lines Matching full:p_ccb
89 static bool process_reqseq(tL2C_CCB* p_ccb, uint16_t ctrl_word);
90 static void process_s_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf, uint16_t ctrl_word);
91 static void process_i_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf, uint16_t ctrl_word,
93 static bool retransmit_i_frames(tL2C_CCB* p_ccb, uint8_t tx_seq);
94 static void prepare_I_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf,
96 static void process_stream_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf);
97 static bool do_sar_reassembly(tL2C_CCB* p_ccb, BT_HDR* p_buf,
101 static void l2c_fcr_collect_ack_delay(tL2C_CCB* p_ccb, uint8_t num_bufs_acked);
169 void l2c_fcr_start_timer(tL2C_CCB* p_ccb) {
170 CHECK(p_ccb != NULL);
174 if (p_ccb->fcrb.wait_ack) {
175 tout = (uint32_t)p_ccb->our_cfg.fcr.mon_tout;
177 tout = (uint32_t)p_ccb->our_cfg.fcr.rtrans_tout;
181 if (!alarm_is_scheduled(p_ccb->fcrb.mon_retrans_timer)) {
182 alarm_set_on_mloop(p_ccb->fcrb.mon_retrans_timer, tout,
183 l2c_ccb_timer_timeout, p_ccb);
196 void l2c_fcr_stop_timer(tL2C_CCB* p_ccb) {
197 CHECK(p_ccb != NULL);
198 alarm_cancel(p_ccb->fcrb.mon_retrans_timer);
211 void l2c_fcr_cleanup(tL2C_CCB* p_ccb) {
212 CHECK(p_ccb != NULL);
213 tL2C_FCRB* p_fcrb = &p_ccb->fcrb;
232 if ((p_ccb->local_cid >= L2CAP_BASE_APPL_CID) &&
233 (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE)) {
234 uint32_t dur = time_get_os_boottime_ms() - p_ccb->fcrb.connect_tick_count;
243 p_ccb->local_cid, dur);
248 p_ccb->fcrb.pkts_retransmitted, p_ccb->fcrb.xmit_window_closed,
249 p_ccb->fcrb.retrans_touts, p_ccb->fcrb.xmit_ack_touts);
254 p_ccb->fcrb.controller_idle);
258 p_ccb->fcrb.max_held_acks, p_ccb->peer_cfg.fcr.tx_win_sz);
264 p_ccb->fcrb.ertm_pkt_counts[0], p_ccb->fcrb.ertm_byte_counts[0],
265 (dur >= 10 ? (p_ccb->fcrb.ertm_byte_counts[0] * 100) / (dur / 10) : 0),
266 p_ccb->fcrb.s_frames_sent[0], p_ccb->fcrb.s_frames_sent[1],
267 p_ccb->fcrb.s_frames_sent[2], p_ccb->fcrb.s_frames_sent[3]);
276 p_ccb->fcrb.ertm_pkt_counts[1], p_ccb->fcrb.ertm_byte_counts[1],
277 (dur >= 10 ? (p_ccb->fcrb.ertm_byte_counts[1] * 100) / (dur / 10) : 0),
278 p_ccb->fcrb.s_frames_rcvd[0], p_ccb->fcrb.s_frames_rcvd[1],
279 p_ccb->fcrb.s_frames_rcvd[2], p_ccb->fcrb.s_frames_rcvd[3]);
289 if (i == p_ccb->fcrb.ack_delay_avg_index) {
298 i, p_ccb->fcrb.throughput[i], p_ccb->fcrb.ack_delay_avg[i],
299 p_ccb->fcrb.ack_delay_min[i], p_ccb->fcrb.ack_delay_max[i],
300 p_ccb->fcrb.ack_q_count_avg[i], p_ccb->fcrb.ack_q_count_min[i],
301 p_ccb->fcrb.ack_q_count_max[i]);
306 throughput_avg += p_ccb->fcrb.throughput[i];
307 ack_delay_avg += p_ccb->fcrb.ack_delay_avg[i];
308 ack_q_count_avg += p_ccb->fcrb.ack_q_count_avg[i];
375 bool l2c_fcr_is_flow_controlled(tL2C_CCB* p_ccb) {
376 CHECK(p_ccb != NULL);
377 if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) {
379 if ((p_ccb->fcrb.remote_busy) ||
380 (fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q) >=
381 p_ccb->peer_cfg.fcr.tx_win_sz)) {
383 if (!fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
384 p_ccb->fcrb.xmit_window_closed++;
386 if ((p_ccb->p_lcb->sent_not_acked < 2) &&
388 p_ccb->fcrb.controller_idle++;
408 static void prepare_I_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf,
410 CHECK(p_ccb != NULL);
412 tL2C_FCRB* p_fcrb = &p_ccb->fcrb;
436 if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) {
441 p_fcrb->last_ack_sent = p_ccb->fcrb.next_seq_expected;
443 alarm_cancel(p_ccb->fcrb.ack_timer);
452 if (p_ccb->bypass_fcs != L2CAP_BYPASS_FCS) {
476 p_ccb->local_cid, p_buf->len,
485 p_ccb->local_cid, p_buf->len,
493 if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE)
494 l2c_fcr_start_timer(p_ccb);
506 void l2c_fcr_send_S_frame(tL2C_CCB* p_ccb, uint16_t function_code,
508 CHECK(p_ccb != NULL);
513 if ((!p_ccb->in_use) || (p_ccb->chnl_state != CST_OPEN)) return;
516 p_ccb->fcrb.s_frames_sent[function_code]++;
520 p_ccb->fcrb.wait_ack = true;
522 l2c_fcr_stop_timer(p_ccb); /* Restart the monitor timer */
523 l2c_fcr_start_timer(p_ccb);
528 ctrl_word |= (p_ccb->fcrb.next_seq_expected << L2CAP_FCR_REQ_SEQ_BITS_SHIFT);
540 UINT16_TO_STREAM(p, p_ccb->remote_cid);
544 if (p_ccb->bypass_fcs != L2CAP_BYPASS_FCS) {
557 l2cu_set_acl_hci_header(p_buf, p_ccb);
564 p_ccb->local_cid, ctrl_word,
574 p_ccb->local_cid, ctrl_word,
582 l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, p_buf);
584 p_ccb->fcrb.last_ack_sent = p_ccb->fcrb.next_seq_expected;
586 alarm_cancel(p_ccb->fcrb.ack_timer);
600 void l2c_fcr_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) {
601 CHECK(p_ccb != NULL);
609 min_pdu_len = (p_ccb->bypass_fcs == L2CAP_BYPASS_FCS)
615 p_ccb->local_cid, p_buf->len);
620 if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_STREAM_MODE) {
621 process_stream_frame(p_ccb, p_buf);
636 p_ccb->local_cid, p_buf->len,
645 p_ccb->local_cid, p_buf->len,
655 p_ccb->local_cid, p_buf->len,
665 p_ccb->fcrb.next_tx_seq, p_ccb->fcrb.last_rx_ack,
666 p_ccb->fcrb.next_seq_expected, p_ccb->fcrb.last_ack_sent,
667 fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q), p_ccb->fcrb.num_tries);
670 if (p_ccb->bypass_fcs != L2CAP_BYPASS_FCS) {
679 p_ccb->local_cid);
694 if (p_ccb->fcrb.wait_ack) {
699 if (p_ccb->fcrb.srej_sent)
700 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_SREJ, L2CAP_FCR_F_BIT);
701 else if (p_ccb->fcrb.local_busy)
702 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_RNR, L2CAP_FCR_F_BIT);
704 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_RR, L2CAP_FCR_F_BIT);
714 alarm_set_on_mloop(p_ccb->fcrb.mon_retrans_timer, BT_1SEC_TIMEOUT_MS,
715 l2c_ccb_timer_timeout, p_ccb);
721 p_ccb->fcrb.wait_ack = false;
726 if (fixed_queue_is_empty(p_ccb->fcrb.waiting_for_ack_q))
727 p_ccb->fcrb.num_tries = 0;
729 l2c_fcr_stop_timer(p_ccb);
736 if (!process_reqseq(p_ccb, ctrl_word)) {
743 process_s_frame(p_ccb, p_buf, ctrl_word);
745 process_i_frame(p_ccb, p_buf, ctrl_word, false);
749 if ((!p_ccb->in_use) || (p_ccb->chnl_state != CST_OPEN)) return;
753 if ((!p_ccb->fcrb.local_busy) && (!p_ccb->fcrb.srej_sent) &&
754 (!fixed_queue_is_empty(p_ccb->fcrb.srej_rcv_hold_q))) {
755 fixed_queue_t* temp_q = p_ccb->fcrb.srej_rcv_hold_q;
756 p_ccb->fcrb.srej_rcv_hold_q = fixed_queue_new(SIZE_MAX);
759 if (p_ccb->in_use && (p_ccb->chnl_state == CST_OPEN)) {
768 p_ccb->local_cid,
770 p_ccb->fcrb.next_seq_expected);
774 process_i_frame(p_ccb, p_buf, ctrl_word, true);
779 if (p_ccb->fcrb.rej_after_srej) {
780 p_ccb->fcrb.rej_after_srej = false;
781 p_ccb->fcrb.rej_sent = true;
783 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_REJ, 0);
789 if ((!p_ccb->fcrb.local_busy) && (!p_ccb->fcrb.rej_sent) &&
790 (!p_ccb->fcrb.srej_sent) &&
791 (p_ccb->fcrb.next_seq_expected != p_ccb->fcrb.last_ack_sent))
792 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_RR, 0);
797 p_ccb->local_cid, p_ccb->fcrb.local_busy, p_ccb->fcrb.rej_sent,
798 p_ccb->fcrb.srej_sent, p_ccb->fcrb.next_seq_expected,
799 p_ccb->fcrb.last_ack_sent);
804 if ((!fixed_queue_is_empty(p_ccb->fcrb.retrans_q) ||
805 !fixed_queue_is_empty(p_ccb->xmit_hold_q)) &&
806 (!p_ccb->fcrb.wait_ack) && (!l2c_fcr_is_flow_controlled(p_ccb))) {
807 l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, NULL);
821 void l2c_lcc_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) {
822 CHECK(p_ccb != NULL);
829 if (p_buf->len > p_ccb->local_conn_cfg.mps) {
835 if (p_ccb->is_first_seg) {
838 if (sdu_length > p_ccb->local_conn_cfg.mtu) {
850 p_ccb->ble_sdu = p_data;
852 p_ccb->ble_sdu_length = sdu_length;
859 p_data = p_ccb->ble_sdu;
860 if (p_buf->len > (p_ccb->ble_sdu_length - p_data->len)) {
863 (p_ccb->ble_sdu_length - p_data->len));
868 p_ccb->is_first_seg = true;
869 osi_free(p_ccb->ble_sdu);
870 p_ccb->ble_sdu = NULL;
871 p_ccb->ble_sdu_length = 0;
872 l2cu_disconnect_chnl(p_ccb);
881 if (p_data->len == p_ccb->ble_sdu_length) {
882 l2c_csm_execute(p_ccb
883 p_ccb->is_first_seg = true;
884 p_ccb->ble_sdu = NULL;
885 p_ccb->ble_sdu_length = 0;
886 } else if (p_data->len < p_ccb->ble_sdu_length) {
887 p_ccb->is_first_seg = false;
903 void l2c_fcr_proc_tout(tL2C_CCB* p_ccb) {
904 CHECK(p_ccb != NULL);
908 p_ccb->local_cid, p_ccb->fcrb.num_tries, p_ccb->peer_cfg.fcr.max_transmit,
909 p_ccb->fcrb.wait_ack, fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q));
912 p_ccb->fcrb.retrans_touts++;
915 if ((p_ccb->peer_cfg.fcr.max_transmit != 0) &&
916 (++p_ccb->fcrb.num_tries > p_ccb->peer_cfg.fcr.max_transmit)) {
917 l2cu_disconnect_chnl(p_ccb);
919 if (!p_ccb->fcrb.srej_sent && !p_ccb->fcrb.rej_sent) {
920 if (p_ccb->fcrb.local_busy)
921 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_RNR, L2CAP_FCR_P_BIT);
923 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_RR, L2CAP_FCR_P_BIT);
937 void l2c_fcr_proc_ack_tout(tL2C_CCB* p_ccb) {
938 CHECK(p_ccb != NULL);
941 p_ccb->local_cid, p_ccb->chnl_state, p_ccb->fcrb.wait_ack,
942 p_ccb->fcrb.next_seq_expected, p_ccb->fcrb.last_ack_sent);
944 if ((p_ccb->chnl_state == CST_OPEN) && (!p_ccb->fcrb.wait_ack) &&
945 (p_ccb->fcrb.last_ack_sent != p_ccb->fcrb.next_seq_expected)) {
947 p_ccb->fcrb.xmit_ack_touts++;
949 if (p_ccb->fcrb.local_busy)
950 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_RNR, 0);
952 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_RR, 0);
965 static bool process_reqseq(tL2C_CCB* p_ccb, uint16_t ctrl_word) {
966 CHECK(p_ccb != NULL);
967 tL2C_FCRB* p_fcrb = &p_ccb->fcrb;
980 l2c_fcr_start_timer(p_ccb);
1000 l2cu_disconnect_chnl(p_ccb);
1013 l2c_fcr_collect_ack_delay(p_ccb, num_bufs_acked);
1028 if (!p_ccb->fcrb.wait_ack) l2c_fcr_stop_timer(p_ccb);
1031 if ((p_ccb->p_rcb) && (p_ccb->p_rcb->api.pL2CA_TxComplete_Cb) &&
1035 fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
1039 (*p_ccb->p_rcb->api.pL2CA_TxComplete_Cb)(p_ccb->local_cid,
1046 l2c_fcr_start_timer(p_ccb);
1059 static void process_s_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf,
1061 CHECK(p_ccb != NULL);
1064 tL2C_FCRB* p_fcrb = &p_ccb->fcrb;
1078 p_ccb->fcrb.s_frames_rcvd[s_frame_type]++;
1092 all_ok = retransmit_i_frames(p_ccb, L2C_FCR_RETX_ALL_PKTS);
1097 all_ok = retransmit_i_frames(p_ccb, L2C_FCR_RETX_ALL_PKTS);
1102 l2c_fcr_stop_timer(p_ccb);
1108 p_ccb, (uint8_t)((ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >>
1118 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_SREJ, L2CAP_FCR_F_BIT);
1120 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_RNR, L2CAP_FCR_F_BIT);
1122 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_RR, L2CAP_FCR_F_BIT);
1142 static void process_i_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf, uint16_t ctrl_word,
1144 CHECK(p_ccb != NULL);
1147 tL2C_FCRB* p_fcrb = &p_ccb->fcrb;
1153 if (!retransmit_i_frames(p_ccb, L2C_FCR_RETX_ALL_PKTS)) {
1160 p_ccb->fcrb.ertm_pkt_counts[1]++;
1161 p_ccb->fcrb.ertm_byte_counts[1] += p_buf->len;
1171 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_RNR, 0);
1181 if (num_lost >= p_ccb->our_cfg.fcr.tx_win_sz) {
1192 p_ccb->local_cid, num_lost, tx_seq, p_fcrb->next_seq_expected,
1206 p_ccb->our_cfg.fcr.tx_win_sz)) {
1209 if (p_ccb->ertm_info.fcr_rx_buf_size != L2CAP_FCR_RX_BUF_SIZE) {
1236 p_ccb->local_cid, next_srej,
1238 p_ccb->our_cfg.fcr.tx_win_sz);
1247 p_ccb->local_cid, num_lost, tx_seq, p_fcrb->next_seq_expected,
1255 p_ccb->local_cid, tx_seq, p_fcrb->next_seq_expected,
1262 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_REJ, 0);
1268 p_ccb->local_cid, tx_seq,
1274 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_SREJ, 0);
1276 alarm_cancel(p_ccb->fcrb.ack_timer);
1292 if (!do_sar_reassembly(p_ccb, p_buf, ctrl_word)) {
1294 p_ccb->local_cid);
1295 l2cu_disconnect_chnl(p_ccb);
1304 if ((num_to_ack < p_ccb->fcrb.max_held_acks) && (!p_fcrb->local_busy))
1308 if ((num_to_ack != 0) && p_ccb->in_use && (p_ccb->chnl_state == CST_OPEN)) {
1313 if (!alarm_is_scheduled(p_ccb->fcrb.ack_timer)) {
1314 alarm_set_on_mloop(p_ccb->fcrb.ack_timer, L2CAP_FCR_ACK_TIMEOUT_MS,
1315 l2c_fcrb_ack_timer_timeout, p_ccb);
1317 } else if ((fixed_queue_is_empty(p_ccb->xmit_hold_q) ||
1318 l2c_fcr_is_flow_controlled(p_ccb)) &&
1319 fixed_queue_is_empty(p_ccb->fcrb.srej_rcv_hold_q)) {
1321 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_RNR, 0);
1323 l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_RR, 0);
1337 static void process_stream_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf) {
1338 CHECK(p_ccb != NULL);
1347 if (p_ccb->bypass_fcs != L2CAP_BYPASS_FCS) {
1356 p_ccb->local_cid);
1375 p_ccb->local_cid, ctrl_word);
1383 p_ccb->local_cid, p_buf->len,
1393 if (tx_seq != p_ccb->fcrb.next_seq_expected) {
1397 p_ccb->local_cid, p_ccb->fcrb.next_seq_expected, tx_seq,
1398 p_ccb->fcrb.p_rx_sdu);
1401 osi_free_and_reset((void**)&p_ccb->fcrb.p_rx_sdu);
1404 p_ccb->fcrb.next_seq_expected = (tx_seq + 1) & L2CAP_FCR_SEQ_MODULO;
1406 if (!do_sar_reassembly(p_ccb, p_buf, ctrl_word)) {
1408 osi_free_and_reset((void**)&p_ccb->fcrb.p_rx_sdu);
1421 static bool do_sar_reassembly(tL2C_CCB* p_ccb, BT_HDR* p_buf,
1423 CHECK(p_ccb != NULL);
1426 tL2C_FCRB* p_fcrb = &p_ccb->fcrb;
1464 if (p_fcrb->rx_sdu_len > p_ccb->max_rx_mtu) {
1510 if (p_ccb->local_cid < L2CAP_BASE_APPL_CID &&
1511 (p_ccb->local_cid >= L2CAP_FIRST_FIXED_CHNL &&
1512 p_ccb->local_cid <= L2CAP_LAST_FIXED_CHNL)) {
1513 if (l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL]
1515 (*l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL]
1516 .pL2CA_FixedData_Cb)(p_ccb->local_cid,
1517 p_ccb->p_lcb->remote_bd_addr, p_buf);
1520 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DATA, p_buf);
1535 static bool retransmit_i_frames(tL2C_CCB* p_ccb, uint8_t tx_seq) {
1536 CHECK(p_ccb != NULL);
1543 if ((!fixed_queue_is_empty(p_ccb->fcrb.waiting_for_ack_q)) &&
1544 (p_ccb->peer_cfg.fcr.max_transmit != 0) &&
1545 (p_ccb->fcrb.num_tries >= p_ccb->peer_cfg.fcr.max_transmit)) {
1549 p_ccb->fcrb.last_rx_ack, p_ccb->local_cid, p_ccb->fcrb.num_tries,
1550 p_ccb->peer_cfg.fcr.max_transmit,
1551 fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q));
1553 l2cu_disconnect_chnl(p_ccb);
1561 if (!fixed_queue_is_empty(p_ccb->fcrb.waiting_for_ack_q)) {
1562 list_ack = fixed_queue_get_list(p_ccb->fcrb.waiting_for_ack_q);
1590 fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q));
1596 for (list_node_t* node_tmp = list_begin(p_ccb->p_lcb->link_xmit_data_q);
1597 node_tmp != list_end(p_ccb->p_lcb->link_xmit_data_q);) {
1602 if ((p_tmp->layer_specific == 0) && (p_tmp->event == p_ccb->local_cid)) {
1603 list_remove(p_ccb->p_lcb->link_xmit_data_q, p_tmp);
1609 while (!fixed_queue_is_empty(p_ccb->fcrb.retrans_q))
1610 osi_free(fixed_queue_try_dequeue(p_ccb->fcrb.retrans_q));
1624 fixed_queue_enqueue(p_ccb->fcrb.retrans_q, p_buf2);
1631 l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, NULL);
1633 if (fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q)) {
1634 p_ccb->fcrb.num_tries++;
1635 l2c_fcr_start_timer(p_ccb);
1650 BT_HDR* l2c_fcr_get_next_xmit_sdu_seg(tL2C_CCB* p_ccb,
1652 CHECK(p_ccb != NULL);
1660 uint16_t max_pdu = p_ccb->tx_mps /* Needed? - L2CAP_MAX_HEADER_FCS*/;
1664 p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->fcrb.retrans_q);
1668 prepare_I_frame(p_ccb, p_buf, true);
1670 p_buf->event = p_ccb->local_cid;
1673 p_ccb->fcrb.pkts_retransmitted++;
1674 p_ccb->fcrb.ertm_pkt_counts[0]++;
1675 p_ccb->fcrb.ertm_byte_counts[0] += (p_buf->len - 8);
1687 p_buf = (BT_HDR*)fixed_queue_try_peek_first(p_ccb->xmit_hold_q);
1704 p_buf->event = p_ccb->local_cid;
1705 p_xmit->event = p_ccb->local_cid;
1721 p_xmit = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q);
1725 p_xmit->event = p_ccb->local_cid;
1745 UINT16_TO_STREAM(p, p_ccb->remote_cid);
1764 prepare_I_frame(p_ccb, p_xmit, false);
1766 if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) {
1773 p_ccb->local_cid, p_xmit->len);
1776 if (p_ccb->bypass_fcs != L2CAP_BYPASS_FCS) p_xmit->len -= L2CAP_FCS_LEN;
1779 fixed_queue_enqueue(p_ccb->fcrb.waiting_for_ack_q, p_xmit);
1792 if (p_ccb->bypass_fcs != L2CAP_BYPASS_FCS) p_wack->len -= L2CAP_FCS_LEN;
1795 fixed_queue_enqueue(p_ccb->fcrb.waiting_for_ack_q, p_wack);
1799 p_ccb->fcrb.ertm_pkt_counts[0]++;
1800 p_ccb->fcrb.ertm_byte_counts[0] += (p_xmit->len - 8);
1810 BT_HDR* l2c_lcc_get_next_xmit_sdu_seg(tL2C_CCB* p_ccb,
1812 uint16_t max_pdu = p_ccb->peer_conn_cfg.mps - 4 /* Length and CID */;
1814 BT_HDR* p_buf = (BT_HDR*)fixed_queue_try_peek_first(p_ccb->xmit_hold_q);
1827 p_buf->event = p_ccb->local_cid;
1828 p_xmit->event = p_ccb->local_cid;
1846 p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q);
1859 UINT16_TO_STREAM(p, p_ccb->remote_cid);
1884 uint8_t l2c_fcr_chk_chan_modes(tL2C_CCB* p_ccb) {
1885 CHECK(p_ccb != NULL);
1888 if (!(p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_ENH_RETRANS))
1889 p_ccb->ertm_info.allowed_modes &= ~L2CAP_FCR_CHAN_OPT_ERTM;
1891 if (!(p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_STREAM_MODE))
1892 p_ccb->ertm_info.allowed_modes &= ~L2CAP_FCR_CHAN_OPT_STREAM;
1895 if (!p_ccb->ertm_info.allowed_modes) {
1900 return (p_ccb->ertm_info.allowed_modes);
1913 bool l2c_fcr_adj_our_req_options(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) {
1914 CHECK(p_ccb != NULL);
1919 if (p_fcr->mode != p_ccb->ertm_info.preferred_mode) {
1923 p_ccb->ertm_info.preferred_mode, p_fcr->mode);
1927 p_fcr->mode = p_ccb->ertm_info.preferred_mode;
1931 if (p_ccb->ertm_info.allowed_modes == L2CAP_FCR_CHAN_OPT_BASIC) {
1946 if (p_cfg->fcr_present && !(p_ccb->config_done & RECONFIG_FLAG)) {
1948 if (!l2c_fcr_chk_chan_modes(p_ccb)) {
1950 l2cu_disconnect_chnl(p_ccb);
1955 else if (p_ccb->ertm_info.allowed_modes == L2CAP_FCR_CHAN_OPT_BASIC) {
1970 !(p_ccb->ertm_info.allowed_modes & L2CAP_FCR_CHAN_OPT_STREAM)) {
1979 !(p_ccb->ertm_info.allowed_modes & L2CAP_FCR_CHAN_OPT_ERTM)) {
1988 if ((p_cfg->mtu_present) && (p_cfg->mtu > p_ccb->max_rx_mtu)) {
1990 p_cfg->mtu, p_ccb->max_rx_mtu);
1999 else if (p_fcr->mps > p_ccb->max_rx_mtu) {
2001 p_ccb->max_rx_mtu);
2015 p_ccb->our_cfg.fcr = *p_fcr;
2019 p_ccb->our_cfg.fcr_present = false;
2034 void l2c_fcr_adj_monitor_retran_timeout(tL2C_CCB* p_ccb) {
2035 CHECK(p_ccb != NULL);
2038 if (p_ccb->out_cfg_fcr_present) {
2044 if ((p_ccb->our_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) ||
2045 (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE)) {
2047 p_ccb->our_cfg.fcr.mon_tout = L2CAP_MIN_MONITOR_TOUT;
2048 p_ccb->our_cfg.fcr.rtrans_tout = L2CAP_MIN_RETRANS_TOUT;
2050 p_ccb->our_cfg.fcr.mon_tout = 0;
2051 p_ccb->our_cfg.fcr.rtrans_tout = 0;
2056 p_ccb->our_cfg.fcr.mon_tout, p_ccb->our_cfg.fcr.rtrans_tout);
2070 void l2c_fcr_adj_our_rsp_options(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) {
2071 CHECK(p_ccb != NULL);
2075 l2c_fcr_adj_monitor_retran_timeout(p_ccb);
2077 p_cfg->fcr_present = p_ccb->out_cfg_fcr_present;
2084 if (p_ccb->peer_cfg.fcr.tx_win_sz > p_ccb->our_cfg.fcr.tx_win_sz) {
2086 __func__, p_ccb->peer_cfg.fcr.tx_win_sz,
2087 p_ccb->our_cfg.fcr.tx_win_sz);
2088 p_ccb->peer_cfg.fcr.tx_win_sz = p_ccb->our_cfg.fcr.tx_win_sz;
2091 p_cfg->fcr.mode = p_ccb->peer_cfg.fcr.mode;
2092 p_cfg->fcr.tx_win_sz = p_ccb->peer_cfg.fcr.tx_win_sz;
2093 p_cfg->fcr.max_transmit = p_ccb->peer_cfg.fcr.max_transmit;
2094 p_cfg->fcr.mps = p_ccb->peer_cfg.fcr.mps;
2095 p_cfg->fcr.rtrans_tout = p_ccb->our_cfg.fcr.rtrans_tout;
2096 p_cfg->fcr.mon_tout = p_ccb->our_cfg.fcr.mon_tout;
2112 bool l2c_fcr_renegotiate_chan(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) {
2113 CHECK(p_ccb != NULL);
2116 uint8_t peer_mode = p_ccb->our_cfg.fcr.mode;
2121 if (!p_cfg->fcr_present || (p_ccb->config_done & RECONFIG_FLAG))
2128 if (p_ccb->our_cfg.fcr.mode != peer_mode) {
2129 if ((--p_ccb->fcr_cfg_tries) == 0) {
2138 switch (p_ccb->our_cfg.fcr.mode) {
2143 (p_ccb->ertm_info.allowed_modes & L2CAP_FCR_CHAN_OPT_ERTM)) {
2145 p_ccb->our_cfg.fcr.mode = L2CAP_FCR_ERTM_MODE;
2151 if (p_ccb->ertm_info.allowed_modes & L2CAP_FCR_CHAN_OPT_BASIC) {
2154 p_ccb->our_cfg.fcr.mode = L2CAP_FCR_BASIC_MODE;
2164 p_ccb->our_cfg.fcr_present = true;
2166 if (p_ccb->our_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE) {
2167 p_ccb->our_cfg.fcs_present = false;
2168 p_ccb->our_cfg.ext_flow_spec_present = false;
2177 l2cu_process_our_cfg_req(p_ccb, &p_ccb->our_cfg);
2178 l2cu_send_peer_config_req(p_ccb, &p_ccb->our_cfg);
2179 alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
2180 l2c_ccb_timer_timeout, p_ccb);
2187 if (p_ccb->our_cfg.fcr.mode != peer_mode) {
2189 p_ccb->our_cfg.fcr.mode, peer_mode);
2190 l2cu_disconnect_chnl(p_ccb);
2207 uint8_t l2c_fcr_process_peer_cfg_req(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) {
2208 CHECK(p_ccb != NULL);
2214 p_ccb->p_lcb->w4_info_rsp =
2220 p_cfg->fcr_present, p_cfg->fcr.mode, p_ccb->our_cfg.fcr.mode,
2221 p_ccb->ertm_info.preferred_mode, p_ccb->ertm_info.allowed_modes);
2226 if (!(p_ccb->ertm_info.allowed_modes & L2CAP_FCR_CHAN_OPT_BASIC))
2231 else if (p_cfg->fcr.mode != p_ccb->ertm_info.preferred_mode) {
2239 (p_ccb->ertm_info.preferred_mode == L2CAP_FCR_ERTM_MODE)) {
2240 p_cfg->fcr.mode = p_ccb->our_cfg.fcr.mode;
2241 p_cfg->fcr.tx_win_sz = p_ccb->our_cfg.fcr.tx_win_sz;
2242 p_cfg->fcr.max_transmit = p_ccb->our_cfg.fcr.max_transmit;
2247 else if (p_ccb->ertm_info.preferred_mode == L2CAP_FCR_BASIC_MODE) {
2251 p_ccb->our_cfg.fcr.rtrans_tout = p_ccb->our_cfg.fcr.mon_tout =
2252 p_ccb->our_cfg.fcr.mps = 0;
2261 !(p_ccb->ertm_info.allowed_modes & L2CAP_FCR_CHAN_OPT_ERTM)) {
2270 p_ccb->out_cfg_fcr_present = false;
2276 p_ccb->peer_cfg.fcs = p_cfg->fcs;
2277 p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_FCS;
2279 p_ccb->bypass_fcs |= L2CAP_CFG_FCS_PEER;
2282 max_retrans_size = p_ccb->ertm_info.fcr_tx_buf_size - sizeof(BT_HDR) -
2287 if ((p_cfg->fcr.mps == 0) || (p_cfg->fcr.mps > p_ccb->peer_cfg.mtu)) {
2288 p_cfg->fcr.mps = p_ccb->peer_cfg.mtu;
2289 p_ccb->out_cfg_fcr_present = true;
2298 p_ccb->out_cfg_fcr_present = true;
2304 p_ccb->out_cfg_fcr_present = true;
2309 p_ccb->peer_cfg.fcr = p_cfg->fcr;
2311 if (p_cfg->fcr_present) p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_FCR;
2314 if (p_ccb->peer_cfg_already_rejected)
2317 p_ccb->peer_cfg_already_rejected = true;
2336 static void l2c_fcr_collect_ack_delay(tL2C_CCB* p_ccb, uint8_t num_bufs_acked) {
2344 index = p_ccb->fcrb.ack_delay_avg_index;
2347 p_ccb->fcrb.ack_q_count_avg[index] +=
2348 fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q);
2350 if (fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q) >
2351 p_ccb->fcrb.ack_q_count_max[index])
2352 p_ccb->fcrb.ack_q_count_max[index] =
2353 fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q);
2355 if (fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q) <
2356 p_ccb->fcrb.ack_q_count_min[index])
2357 p_ccb->fcrb.ack_q_count_min[index] =
2358 fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q);
2362 if (!fixed_queue_is_empty(p_ccb->fcrb.waiting_for_ack_q))
2363 list = fixed_queue_get_list(p_ccb->fcrb.waiting_for_ack_q);
2370 p_ccb->fcrb.throughput[index] += p_buf->len - 8;
2375 if (p_ccb->bypass_fcs != L2CAP_BYPASS_FCS) {
2382 p_ccb->fcrb.ack_delay_avg[index] += delay;
2383 if (delay > p_ccb->fcrb.ack_delay_max[index])
2384 p_ccb->fcrb.ack_delay_max[index] = delay;
2385 if (delay < p_ccb->fcrb.ack_delay_min[index])
2386 p_ccb->fcrb.ack_delay_min[index] = delay;
2391 p_ccb->fcrb.ack_delay_avg_count++;
2394 if (p_ccb->fcrb.ack_delay_avg_count > L2CAP_ERTM_STATS_AVG_NUM_SAMPLES) {
2395 p_ccb->fcrb.ack_delay_avg_count = 0;
2397 p_ccb->fcrb.ack_q_count_avg[index] /= L2CAP_ERTM_STATS_AVG_NUM_SAMPLES;
2398 p_ccb->fcrb.ack_delay_avg[index] /= L2CAP_ERTM_STATS_AVG_NUM_SAMPLES;
2402 if (timestamp - p_ccb->fcrb.throughput_start > 0)
2403 p_ccb->fcrb.throughput[index] /=
2404 (timestamp - p_ccb->fcrb.throughput_start);
2406 p_ccb->fcrb.throughput_start = timestamp;
2412 index, p_ccb->fcrb.throughput[index], p_ccb->fcrb.ack_delay_avg[index],
2413 p_ccb->fcrb.ack_delay_min[index], p_ccb->fcrb.ack_delay_max[index],
2414 p_ccb->fcrb.ack_q_count_avg[index], p_ccb->fcrb.ack_q_count_min[index],
2415 p_ccb->fcrb.ack_q_count_max[index]);
2421 p_ccb->fcrb.ack_delay_avg_index = index;
2423 p_ccb->fcrb.ack_q_count_max[index] = 0;
2424 p_ccb->fcrb.ack_q_count_min[index] = 0xFFFFFFFF;
2425 p_ccb->fcrb.ack_q_count_avg[index] = 0;
2427 p_ccb->fcrb.ack_delay_max[index] = 0;
2428 p_ccb->fcrb.ack_delay_min[index] = 0xFFFFFFFF;
2429 p_ccb->fcrb.ack_delay_avg[index] = 0;
2431 p_ccb->fcrb.throughput[index] = 0;