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

Commit ef67f49f authored by Pomai Ahlo's avatar Pomai Ahlo Committed by Gerrit Code Review
Browse files

Merge "Add PORT_IsCollisionDetected" into main

parents 76c0f5ec e598a963
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -192,14 +192,24 @@ void bta_ag_start_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
  p_scb->open_services = p_scb->reg_services;

  /* Check if RFCOMM has any incoming connection to avoid collision. */
  if (com::android::bluetooth::flags::rfcomm_prevent_unnecessary_collisions()) {
    if (PORT_IsCollisionDetected(p_scb->peer_addr)) {
      /* Let the incoming connection go through.                           */
      /* Issue collision for this scb for now.                             */
      /* We will decide what to do when we find incoming connection later. */
      bta_ag_collision_cback(BTA_SYS_CONN_OPEN, BTA_ID_AG, 0, p_scb->peer_addr);
      return;
    }
  } else {
    RawAddress pending_bd_addr = RawAddress::kEmpty;
    if (PORT_IsOpening(&pending_bd_addr)) {
    /* Let the incoming connection goes through.                        */
      /* Let the incoming connection go through.                           */
      /* Issue collision for this scb for now.                             */
    /* We will decide what to do when we find incoming connetion later. */
      /* We will decide what to do when we find incoming connection later. */
      bta_ag_collision_cback(BTA_SYS_CONN_OPEN, BTA_ID_AG, 0, p_scb->peer_addr);
      return;
    }
  }

  /* close servers */
  bta_ag_close_servers(p_scb, p_scb->reg_services);
+17 −7
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
 ******************************************************************************/

#include <bluetooth/log.h>
#include <com_android_bluetooth_flags.h>

#include "bta/hf_client/bta_hf_client_int.h"
#include "bta/include/bta_dm_api.h"
@@ -100,14 +101,23 @@ void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA* p_data) {
  }

  /* Check if RFCOMM has any incoming connection to avoid collision. */
  if (com::android::bluetooth::flags::rfcomm_prevent_unnecessary_collisions()) {
    if (PORT_IsCollisionDetected(client_cb->peer_addr)) {
      /* Let the incoming connection go through.                          */
      /* Issue collision for now.                                         */
      /* We will decide what to do when we find incoming connection later.*/
      bta_hf_client_collision_cback(BTA_SYS_CONN_OPEN, BTA_ID_HS, 0, client_cb->peer_addr);
    }
  } else {
    RawAddress pending_bd_addr = RawAddress::kEmpty;
    if (PORT_IsOpening(&pending_bd_addr)) {
    /* Let the incoming connection goes through.                        */
      /* Let the incoming connection go through.                          */
      /* Issue collision for now.                                         */
      /* We will decide what to do when we find incoming connection later.*/
      bta_hf_client_collision_cback(BTA_SYS_CONN_OPEN, BTA_ID_HS, 0, client_cb->peer_addr);
      return;
    }
  }

  /* set role */
  client_cb->role = BTA_HF_CLIENT_INT;
+13 −0
Original line number Diff line number Diff line
@@ -332,6 +332,19 @@ typedef void(tPORT_MGMT_CALLBACK)(const tPORT_RESULT code, uint16_t port_handle)
 ******************************************************************************/
[[nodiscard]] bool PORT_IsOpening(RawAddress* bd_addr);

/*******************************************************************************
 *
 * Function         PORT_IsCollisionDetected
 *
 * Description      This function returns true if there is already an incoming
 *                  RFCOMM connection in progress for this device
 *
 * Parameters:      true if any connection opening is found
 *                  bd_addr    - bd_addr of the peer
 *
 ******************************************************************************/
[[nodiscard]] bool PORT_IsCollisionDetected(RawAddress bd_addr);

/*******************************************************************************
 *
 * Function         PORT_SetState
+46 −0
Original line number Diff line number Diff line
@@ -513,6 +513,52 @@ bool PORT_IsOpening(RawAddress* bd_addr) {
  return false;
}

/*******************************************************************************
 *
 * Function         PORT_IsCollisionDetected
 *
 * Description      This function returns true if there is already an incoming
 *                  RFCOMM connection in progress for this device
 *
 * Parameters:      true if any connection opening is found
 *                  bd_addr    - bd_addr of the peer
 *
 ******************************************************************************/
bool PORT_IsCollisionDetected(RawAddress bd_addr) {
  for (auto& multiplexer_cb : rfc_cb.port.rfc_mcb) {
    if (multiplexer_cb.bd_addr != RawAddress::kEmpty && multiplexer_cb.bd_addr != bd_addr) {
      // there's no chance of a collision if the bd_addr is different
      continue;
    }
    if (multiplexer_cb.is_initiator == false) {
      // there's no chance of a collision if this side isn't a server
      continue;
    }
    if ((multiplexer_cb.state > RFC_MX_STATE_IDLE) &&
        (multiplexer_cb.state < RFC_MX_STATE_CONNECTED)) {
      // this rfc_mcb is in the middle of opening
      // bd_addr either matches or is empty and possibly not yet set
      log::info("Found an opening rfc_mcb, multiplexer bd_addr={},returning true",
                multiplexer_cb.bd_addr);
      return true;
    }
    if (multiplexer_cb.state == RFC_MX_STATE_CONNECTED) {
      const tPORT* p_port = get_port_from_mcb(&multiplexer_cb);
      log::info("RFC_MX_STATE_CONNECTED, found_port={}, tRFC_PORT_STATE={}",
                (p_port != nullptr) ? "T" : "F", (p_port != nullptr) ? p_port->rfc.state : 0);
      if ((p_port == nullptr) || (p_port->rfc.state < RFC_STATE_OPENED)) {
        // Port is not established yet
        log::info(
                "In RFC_MX_STATE_CONNECTED but port is not established yet, "
                "returning true");
        return true;
      }
    }
  }
  log::info("returning false");
  return false;
}

/*******************************************************************************
 *
 * Function         PORT_SetState
+43 −1
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@

namespace {
const RawAddress kRawAddress = RawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});

const RawAddress kRawAddress2 = RawAddress({0x01, 0x02, 0x03, 0x04, 0x05, 0x06});
}  // namespace

class StackRfcommPortTest : public ::testing::Test {
@@ -55,3 +55,45 @@ TEST_F(StackRfcommPortTest, PORT_IsOpening__basic) {
  rfc_cb.port.rfc_mcb[0].state = RFC_MX_STATE_DISC_WAIT_UA;
  ASSERT_FALSE(PORT_IsOpening(&bd_addr));
}

TEST_F(StackRfcommPortTest, PORT_IsCollisionDetected__basic) {
  RawAddress test_bd_addr(kRawAddress);
  RawAddress different_bd_addr(kRawAddress2);

  rfc_cb.port.rfc_mcb[0].bd_addr = test_bd_addr;
  // no collisions will happen if the bd_addr don't match, regardless of state
  for (int state_int = RFC_MX_STATE_IDLE; state_int <= RFC_MX_STATE_DISC_WAIT_UA; state_int++) {
    rfc_cb.port.rfc_mcb[0].state = tRFC_MX_STATE(state_int);
    ASSERT_FALSE(PORT_IsCollisionDetected(different_bd_addr));
  }

  rfc_cb.port.rfc_mcb[0].is_initiator = false;
  // no collisions will happen if not initiator, regardless of state
  for (int state_int = RFC_MX_STATE_IDLE; state_int <= RFC_MX_STATE_DISC_WAIT_UA; state_int++) {
    rfc_cb.port.rfc_mcb[0].state = tRFC_MX_STATE(state_int);
    ASSERT_FALSE(PORT_IsCollisionDetected(test_bd_addr));
  }

  // possible collisions if bd_addr match and is initiator
  rfc_cb.port.rfc_mcb[0].is_initiator = true;

  rfc_cb.port.rfc_mcb[0].state = RFC_MX_STATE_IDLE;
  ASSERT_FALSE(PORT_IsCollisionDetected(test_bd_addr));
  rfc_cb.port.rfc_mcb[0].state = RFC_MX_STATE_WAIT_CONN_CNF;
  ASSERT_TRUE(PORT_IsCollisionDetected(test_bd_addr));
  rfc_cb.port.rfc_mcb[0].state = RFC_MX_STATE_CONFIGURE;
  ASSERT_TRUE(PORT_IsCollisionDetected(test_bd_addr));
  rfc_cb.port.rfc_mcb[0].state = RFC_MX_STATE_SABME_WAIT_UA;
  ASSERT_TRUE(PORT_IsCollisionDetected(test_bd_addr));
  rfc_cb.port.rfc_mcb[0].state = RFC_MX_STATE_WAIT_SABME;
  ASSERT_TRUE(PORT_IsCollisionDetected(test_bd_addr));
  rfc_cb.port.rfc_mcb[0].state = RFC_MX_STATE_CONNECTED;

  rfc_cb.port.port[0].rfc.p_mcb = &rfc_cb.port.rfc_mcb[0];
  rfc_cb.port.port[0].rfc.state = RFC_STATE_OPENED;
  ASSERT_FALSE(PORT_IsCollisionDetected(test_bd_addr));
  rfc_cb.port.port[0].rfc.state = RFC_STATE_TERM_WAIT_SEC_CHECK;
  ASSERT_TRUE(PORT_IsCollisionDetected(test_bd_addr));
  rfc_cb.port.rfc_mcb[0].state = RFC_MX_STATE_DISC_WAIT_UA;
  ASSERT_FALSE(PORT_IsCollisionDetected(test_bd_addr));
}
Loading