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

Commit fdf92d1f authored by Kilsung Yu's avatar Kilsung Yu Committed by Chris Manton
Browse files

l2cap: Fix for REF responds with same DCIDs for different connections from IUT

Stack Not initiating L2CAP Disconnect when REF responds with same DCIDs for different connections from IUT
If a device receives a L2CAP_CREDIT_BASED_CONNECTION_RSP packet with an already assigned Destination CID,
 then both the original channel and the new channel shall be immediately discarded and not used.
Test: Verified with L2CAP/ECFC/BV-29-C

Change-Id: I75a67d6a7934c2015784c4471f86a4a5c54d9f67
parent ad135885
Loading
Loading
Loading
Loading

system/stack/l2cap/l2c_ble.cc

100644 → 100755
+21 −2
Original line number Diff line number Diff line
@@ -671,7 +671,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
        con_info.l2cap_result = L2CAP_LE_RESULT_INVALID_PARAMETERS;
        l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG,
                        &con_info);
        break;
        return;
      }

      /* At least some of the channels has been created and parameters are
@@ -698,8 +698,27 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {

      for (int i = 0; i < p_lcb->pending_ecoc_conn_cnt; i++) {
        uint16_t cid = p_lcb->pending_ecoc_connection_cids[i];
        STREAM_TO_UINT16(rcid, p);
        /* if duplicated remote cid then disconnect original channel
         * and current channel by sending event to upper layer */
        temp_p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid);
        if (temp_p_ccb != nullptr) {
          L2CAP_TRACE_ERROR(
              "Already Allocated Destination cid. "
              "rcid = %d "
              "send peer_disc_req", rcid);

          l2cu_send_peer_disc_req(temp_p_ccb);

          temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid);
        STREAM_TO_UINT16(temp_p_ccb->remote_cid, p);
          con_info.l2cap_result = L2CAP_LE_RESULT_UNACCEPTABLE_PARAMETERS;
          l2c_csm_execute(temp_p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG,
                          &con_info);
          continue;
        }

        temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid);
        temp_p_ccb->remote_cid = rcid;

        L2CAP_TRACE_DEBUG(
            "local cid = %d "