OSDN Git Service

Break out l2c_link_send_to_lower into br_edr and ble
authorChris Manton <cmanton@google.com>
Sat, 22 Aug 2020 15:31:48 +0000 (08:31 -0700)
committerChris Manton <cmanton@google.com>
Sat, 22 Aug 2020 16:22:52 +0000 (09:22 -0700)
stack/l2cap/l2c_link::l2c_link_send_to_lower

Towards proper interfaces

Bug: 163134718
Tag: #refactor
Test: compile & verify basic functions working

Change-Id: Ia8c833a0ab806429743bd974d595cc102b738c5c

stack/l2cap/l2c_link.cc

index 9d52a09..aee965a 100644 (file)
@@ -1015,8 +1015,7 @@ constexpr uint16_t kDataPacketEventBrEdr = (BT_EVT_TO_LM_HCI_ACL);
 constexpr uint16_t kDataPacketEventBle =
     (BT_EVT_TO_LM_HCI_ACL | LOCAL_BLE_CONTROLLER_ID);
 
-static void l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf,
-                                   tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
+static void l2c_link_send_to_lower_br_edr(tL2C_LCB* p_lcb, BT_HDR* p_buf) {
   const uint16_t acl_packet_size_classic =
       controller_get_interface()->get_acl_packet_size_classic();
   const uint16_t acl_packet_size_ble =
@@ -1085,7 +1084,101 @@ static void l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf,
       if (p_lcb->link_xmit_quota == 0) l2cb.ble_round_robin_unacked += num_segs;
     } else {
       l2cb.controller_xmit_window -= num_segs;
+      if (p_lcb->link_xmit_quota == 0) l2cb.round_robin_unacked += num_segs;
+    }
+
+    p_lcb->sent_not_acked += num_segs;
+    if (transport == BT_TRANSPORT_LE) {
+      bte_main_hci_send(p_buf, kDataPacketEventBle);
+    } else {
+      bte_main_hci_send(p_buf, kDataPacketEventBrEdr);
+    }
+  }
+
+  if (transport == BT_TRANSPORT_LE) {
+    L2CAP_TRACE_DEBUG(
+        "TotalWin=%d,Hndl=0x%x,Quota=%d,Unack=%d,RRQuota=%d,RRUnack=%d",
+        l2cb.controller_le_xmit_window, p_lcb->handle, p_lcb->link_xmit_quota,
+        p_lcb->sent_not_acked, l2cb.ble_round_robin_quota,
+        l2cb.ble_round_robin_unacked);
+  } else {
+    L2CAP_TRACE_DEBUG(
+        "TotalWin=%d,Hndl=0x%x,Quota=%d,Unack=%d,RRQuota=%d,RRUnack=%d",
+        l2cb.controller_xmit_window, p_lcb->handle, p_lcb->link_xmit_quota,
+        p_lcb->sent_not_acked, l2cb.round_robin_quota,
+        l2cb.round_robin_unacked);
+  }
+}
+
+static void l2c_link_send_to_lower_ble(tL2C_LCB* p_lcb, BT_HDR* p_buf) {
+  const uint16_t acl_packet_size_classic =
+      controller_get_interface()->get_acl_packet_size_classic();
+  const uint16_t acl_packet_size_ble =
+      controller_get_interface()->get_acl_packet_size_ble();
+  const uint16_t link_xmit_quota = p_lcb->link_xmit_quota;
+  const tBT_TRANSPORT transport = p_lcb->transport;
+
+  const bool is_bdr_and_fits_in_buffer =
+      (transport == BT_TRANSPORT_BR_EDR &&
+       (p_buf->len <= acl_packet_size_classic));
+  const bool is_ble_and_fits_in_buffer =
+      (transport == BT_TRANSPORT_LE && (p_buf->len <= acl_packet_size_ble));
+
+  if (is_bdr_and_fits_in_buffer || is_ble_and_fits_in_buffer) {
+    if (link_xmit_quota == 0) {
+      if (transport == BT_TRANSPORT_LE)
+        l2cb.ble_round_robin_unacked++;
+      else
+        l2cb.round_robin_unacked++;
+    }
+    p_lcb->sent_not_acked++;
+    p_buf->layer_specific = 0;
 
+    if (transport == BT_TRANSPORT_LE) {
+      l2cb.controller_le_xmit_window--;
+      bte_main_hci_send(p_buf, kDataPacketEventBle);
+    } else {
+      l2cb.controller_xmit_window--;
+      bte_main_hci_send(p_buf, kDataPacketEventBrEdr);
+    }
+  } else {
+    uint16_t xmit_window{0};
+    uint16_t acl_data_size{0};
+    if (transport == BT_TRANSPORT_LE) {
+      acl_data_size = acl_packet_size_ble;
+      xmit_window = l2cb.controller_le_xmit_window;
+
+    } else {
+      acl_data_size = acl_packet_size_classic;
+      xmit_window = l2cb.controller_xmit_window;
+    }
+    uint16_t num_segs =
+        (p_buf->len - HCI_DATA_PREAMBLE_SIZE + acl_data_size - 1) /
+        acl_data_size;
+
+    /* If doing round-robin, then only 1 segment each time */
+    if (p_lcb->link_xmit_quota == 0) {
+      num_segs = 1;
+      p_lcb->partial_segment_being_sent = true;
+    } else {
+      /* Multi-segment packet. Make sure it can fit */
+      if (num_segs > xmit_window) {
+        num_segs = xmit_window;
+        p_lcb->partial_segment_being_sent = true;
+      }
+
+      if (num_segs > (p_lcb->link_xmit_quota - p_lcb->sent_not_acked)) {
+        num_segs = (p_lcb->link_xmit_quota - p_lcb->sent_not_acked);
+        p_lcb->partial_segment_being_sent = true;
+      }
+    }
+
+    p_buf->layer_specific = num_segs;
+    if (transport == BT_TRANSPORT_LE) {
+      l2cb.controller_le_xmit_window -= num_segs;
+      if (p_lcb->link_xmit_quota == 0) l2cb.ble_round_robin_unacked += num_segs;
+    } else {
+      l2cb.controller_xmit_window -= num_segs;
       if (p_lcb->link_xmit_quota == 0) l2cb.round_robin_unacked += num_segs;
     }
 
@@ -1110,7 +1203,15 @@ static void l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf,
         p_lcb->sent_not_acked, l2cb.round_robin_quota,
         l2cb.round_robin_unacked);
   }
+}
 
+static void l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf,
+                                   tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
+  if (p_lcb->transport == BT_TRANSPORT_BR_EDR) {
+    l2c_link_send_to_lower_br_edr(p_lcb, p_buf);
+  } else {
+    l2c_link_send_to_lower_ble(p_lcb, p_buf);
+  }
   if (p_cbi) l2cu_tx_complete(p_cbi);
 }