Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b1afe34 authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by android-build-merger
Browse files

Merge "Minimize amount of Flow Control packets for L2CAP CoC"

am: ad4dc5e5

Change-Id: I4a0d546d06a53e98977982a179e4687ab0a5e9aa
parents bcd7b408 ad4dc5e5
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -210,7 +210,7 @@ uint16_t GAP_ConnOpen(const char* p_serv_name, uint8_t service_id,

  /* Configure L2CAP COC, if transport is LE */
  if (transport == BT_TRANSPORT_LE) {
    p_ccb->local_coc_cfg.credits = L2CAP_LE_DEFAULT_CREDIT;
    p_ccb->local_coc_cfg.credits = L2CAP_LE_CREDIT_DEFAULT;
    p_ccb->local_coc_cfg.mtu = p_cfg->mtu;

    uint16_t max_mps = controller_get_interface()->get_acl_data_size_ble();
@@ -219,6 +219,10 @@ uint16_t GAP_ConnOpen(const char* p_serv_name, uint8_t service_id,
      le_mps = max_mps;
    }
    p_ccb->local_coc_cfg.mps = le_mps;

    VLOG(2) << __func__ << ": credits=" << p_ccb->local_coc_cfg.credits
            << ", mps=" << p_ccb->local_coc_cfg.mps
            << ", mtu=" << p_ccb->local_coc_cfg.mtu;
  }

  p_ccb->p_callback = p_cb;
+8 −2
Original line number Diff line number Diff line
@@ -555,7 +555,10 @@ uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr,
  p_ccb->p_rcb = p_rcb;

  /* Save the configuration */
  if (p_cfg) memcpy(&p_ccb->local_conn_cfg, p_cfg, sizeof(tL2CAP_LE_CFG_INFO));
  if (p_cfg) {
    memcpy(&p_ccb->local_conn_cfg, p_cfg, sizeof(tL2CAP_LE_CFG_INFO));
    p_ccb->remote_credit_count = p_cfg->credits;
  }

  /* If link is up, start the L2CAP connection */
  if (p_lcb->link_state == LST_CONNECTED) {
@@ -625,7 +628,10 @@ bool L2CA_ConnectLECocRsp(const RawAddress& p_bd_addr, uint8_t id,
    return false;
  }

  if (p_cfg) memcpy(&p_ccb->local_conn_cfg, p_cfg, sizeof(tL2CAP_LE_CFG_INFO));
  if (p_cfg) {
    memcpy(&p_ccb->local_conn_cfg, p_cfg, sizeof(tL2CAP_LE_CFG_INFO));
    p_ccb->remote_credit_count = p_cfg->credits;
  }

  if (result == L2CAP_CONN_OK)
    l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP, NULL);
+1 −1
Original line number Diff line number Diff line
@@ -1105,7 +1105,7 @@ static void l2c_csm_open(tL2C_CCB* p_ccb, uint16_t event, void* p_data) {
    case L2CEVT_L2CAP_RECV_FLOW_CONTROL_CREDIT:
      credit = (uint16_t*)p_data;
      L2CAP_TRACE_DEBUG("%s Credits received %d", __func__, *credit);
      if ((p_ccb->peer_conn_cfg.credits + *credit) > L2CAP_LE_MAX_CREDIT) {
      if ((p_ccb->peer_conn_cfg.credits + *credit) > L2CAP_LE_CREDIT_MAX) {
        /* we have received credits more than max coc credits,
         * so disconnecting the Le Coc Channel
         */
+19 −6
Original line number Diff line number Diff line
@@ -37,12 +37,21 @@
#define L2CAP_MIN_MTU 48 /* Minimum acceptable MTU is 48 bytes */

/* LE credit based L2CAP connection parameters */
#define L2CAP_LE_MIN_MTU 23
#define L2CAP_LE_MIN_MPS 23
#define L2CAP_LE_MAX_MPS 65533
#define L2CAP_LE_MIN_CREDIT 0
#define L2CAP_LE_MAX_CREDIT 65535
#define L2CAP_LE_DEFAULT_CREDIT 1
constexpr uint16_t L2CAP_LE_MIN_MTU = 23;  // Minimum SDU size
constexpr uint16_t L2CAP_LE_MIN_MPS = 23;
constexpr uint16_t L2CAP_LE_MAX_MPS = 65533;
constexpr uint16_t L2CAP_LE_CREDIT_MAX = 65535;

// This is initial amout of credits we send, and amount to which we increase
// credits once they fall below threshold
constexpr uint16_t L2CAP_LE_CREDIT_DEFAULT = 0xffff;

// If credit count on remote fall below this value, we send back credits to
// reach default value.
constexpr uint16_t L2CAP_LE_CREDIT_THRESHOLD = 0x0040;

static_assert(L2CAP_LE_CREDIT_THRESHOLD < L2CAP_LE_CREDIT_DEFAULT,
              "Threshold must be smaller then default credits");

/*
 * Timeout values (in milliseconds).
@@ -327,6 +336,10 @@ typedef struct t_l2c_ccb {
  uint16_t fixed_chnl_idle_tout; /* Idle timeout to use for the fixed channel */
#endif
  uint16_t tx_data_len;

  /* Number of LE frames that the remote can send to us (credit count in
   * remote). Valid only for LE CoC */
  uint16_t remote_credit_count;
} tL2C_CCB;

/***********************************************************************
+12 −3
Original line number Diff line number Diff line
@@ -215,9 +215,18 @@ void l2c_rcv_acl_data(BT_HDR* p_msg) {

  if (p_lcb->transport == BT_TRANSPORT_LE) {
    l2c_lcc_proc_pdu(p_ccb, p_msg);
    // Got a pkt, valid send out credits to the peer device
    uint16_t credit = L2CAP_LE_DEFAULT_CREDIT;
    l2c_csm_execute(p_ccb, L2CEVT_L2CA_SEND_FLOW_CONTROL_CREDIT, &credit);

    /* The remote device has one less credit left */
    --p_ccb->remote_credit_count;

    /* If the credits left on the remote device are getting low, send some */
    if (p_ccb->remote_credit_count <= L2CAP_LE_CREDIT_THRESHOLD) {
      uint16_t credits = L2CAP_LE_CREDIT_DEFAULT - p_ccb->remote_credit_count;
      p_ccb->remote_credit_count = L2CAP_LE_CREDIT_DEFAULT;

      /* Return back credits */
      l2c_csm_execute(p_ccb, L2CEVT_L2CA_SEND_FLOW_CONTROL_CREDIT, &credits);
    }
  } else {
    /* Basic mode packets go straight to the state machine */
    if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE)