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

Commit 2a5372b1 authored by Łukasz Rymanowski's avatar Łukasz Rymanowski
Browse files

l2cap: Add proper handling of L2CAP Reject command

This patch fixes scenario when Android is wating for
Credit Based Connection Response, but remote side does not undestand the
command.

It also fix handling Credit Based Connection Response Negative

Bug: 237399985
Test: atest BluetoothInstrumentationTests
Test: L2CAP/ECFC/BV-01
Tag: #feature
Merged-In: I02d63ea405cb7b6e6bc6d7a30e810be2c0a47805
Change-Id: I02d63ea405cb7b6e6bc6d7a30e810be2c0a47805
(cherry picked from commit 83bcc56c)
parent a1945569
Loading
Loading
Loading
Loading
+38 −7
Original line number Original line Diff line number Diff line
@@ -409,6 +409,30 @@ void l2cble_process_conn_update_evt(uint16_t handle, uint8_t status,
                    p_lcb->conn_update_mask);
                    p_lcb->conn_update_mask);
}
}


/*******************************************************************************
 *
 * Function         l2cble_handle_connect_rsp_neg
 *
 * Description      This function sends error message to all the
 *                  outstanding channels
 *
 * Returns          void
 *
 ******************************************************************************/
static void l2cble_handle_connect_rsp_neg(tL2C_LCB* p_lcb,
                                          tL2C_CONN_INFO* con_info) {
  tL2C_CCB* temp_p_ccb = NULL;
  for (int i = 0; i < p_lcb->pending_ecoc_conn_cnt; i++) {
    uint16_t cid = p_lcb->pending_ecoc_connection_cids[i];
    temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid);
    l2c_csm_execute(temp_p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG,
                    con_info);
  }

  p_lcb->pending_ecoc_conn_cnt = 0;
  memset(p_lcb->pending_ecoc_connection_cids, 0, L2CAP_CREDIT_BASED_MAX_CIDS);
}

/*******************************************************************************
/*******************************************************************************
 *
 *
 * Function         l2cble_process_sig_cmd
 * Function         l2cble_process_sig_cmd
@@ -452,9 +476,16 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
  }
  }


  switch (cmd_code) {
  switch (cmd_code) {
    case L2CAP_CMD_REJECT:
    case L2CAP_CMD_REJECT: {
      p += 2;
      uint16_t reason;
      break;
      STREAM_TO_UINT16(reason, p);

      if (reason == L2CAP_CMD_REJ_NOT_UNDERSTOOD &&
          p_lcb->pending_ecoc_conn_cnt > 0) {
        con_info.l2cap_result = L2CAP_LE_RESULT_NO_PSM;
        l2cble_handle_connect_rsp_neg(p_lcb, &con_info);
      }
    } break;


    case L2CAP_CMD_ECHO_REQ:
    case L2CAP_CMD_ECHO_REQ:
    case L2CAP_CMD_ECHO_RSP:
    case L2CAP_CMD_ECHO_RSP:
@@ -680,8 +711,9 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
          con_info.l2cap_result == L2CAP_LE_RESULT_INSUFFICIENT_AUTHORIZATION ||
          con_info.l2cap_result == L2CAP_LE_RESULT_INSUFFICIENT_AUTHORIZATION ||
          con_info.l2cap_result == L2CAP_LE_RESULT_UNACCEPTABLE_PARAMETERS ||
          con_info.l2cap_result == L2CAP_LE_RESULT_UNACCEPTABLE_PARAMETERS ||
          con_info.l2cap_result == L2CAP_LE_RESULT_INVALID_PARAMETERS) {
          con_info.l2cap_result == L2CAP_LE_RESULT_INVALID_PARAMETERS) {
        l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG,
        L2CAP_TRACE_ERROR("L2CAP - not accepted. Status %d",
                        &con_info);
                          con_info.l2cap_result);
        l2cble_handle_connect_rsp_neg(p_lcb, &con_info);
        return;
        return;
      }
      }


@@ -690,8 +722,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
          mps < L2CAP_CREDIT_BASED_MIN_MPS || mps > L2CAP_LE_MAX_MPS) {
          mps < L2CAP_CREDIT_BASED_MIN_MPS || mps > L2CAP_LE_MAX_MPS) {
        L2CAP_TRACE_ERROR("L2CAP - invalid params");
        L2CAP_TRACE_ERROR("L2CAP - invalid params");
        con_info.l2cap_result = L2CAP_LE_RESULT_INVALID_PARAMETERS;
        con_info.l2cap_result = L2CAP_LE_RESULT_INVALID_PARAMETERS;
        l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG,
        l2cble_handle_connect_rsp_neg(p_lcb, &con_info);
                        &con_info);
        return;
        return;
      }
      }