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

Commit f20be75c authored by Łukasz Rymanowski's avatar Łukasz Rymanowski Committed by Jakub Pawlowski
Browse files

eatt: Improve handling incoming EATT connection

With this patch we make sure that eatt_dev is created always when EATT
is supported on the peer side, no matter what is the connection role.

It will allow to accept ecoc channels when Android device is peripheral
device

Bug: 159786353
Bug: 191313013
Tag: #feature
Test: atest --host net_test_eatt
Sponsor: jpawlowski@
Change-Id: I4d735bc4a2d74f637e9c7f7819e10659af9b0fbb
parent 7d12e8eb
Loading
Loading
Loading
Loading
+19 −10
Original line number Diff line number Diff line
@@ -571,7 +571,8 @@ struct eatt_impl {
                 << bd_addr;
  }

  void supported_features_cb(const RawAddress& bd_addr, uint8_t features) {
  void supported_features_cb(uint8_t role, const RawAddress& bd_addr,
                             uint8_t features) {
    bool is_eatt_supported = features & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK;

    LOG(INFO) << __func__ << " " << bd_addr
@@ -579,6 +580,15 @@ struct eatt_impl {
    if (!is_eatt_supported) return;

    eatt_device* eatt_dev = add_eatt_device(bd_addr);

    if (role != HCI_ROLE_CENTRAL) {
      /* TODO For now do nothing, we could run a timer here and start EATT if
       * not started by central */
      LOG(INFO)
          << " EATT Should be connected by the central. Let's wait for it.";
      return;
    }

    connect_eatt(eatt_dev);
  }

@@ -624,19 +634,18 @@ struct eatt_impl {
    LOG(INFO) << __func__ << " device " << bd_addr << " role"
              << (role == HCI_ROLE_CENTRAL ? "central" : "peripheral");

    if (eatt_dev) {
      /* We are reconnecting device we know that support EATT.
       * Just connect CoC
       */
      LOG(INFO) << __func__ << " Known device, connect eCoC";

      if (role != HCI_ROLE_CENTRAL) {
      /* TODO For now do nothing, we could run a timer here and start EATT if
       * not started by central */
        LOG(INFO)
            << " EATT Should be connected by the central. Let's wait for it.";
        return;
      }

    if (eatt_dev) {
      /* We are reconnecting device we know that support EATT.
       * Just connect CoC
       */
      LOG(INFO) << __func__ << " Known device, connect eCoC";
      connect_eatt(eatt_dev);
      return;
    }
@@ -644,7 +653,7 @@ struct eatt_impl {
    /* For new device, first read GATT server supported features. */
    if (gatt_cl_read_sr_supp_feat_req(
            bd_addr, base::BindOnce(&eatt_impl::supported_features_cb,
                                    base::Unretained(this))) == false) {
                                    base::Unretained(this), role)) == false) {
      LOG(INFO) << __func__ << "Eatt is not supported. Checked for device "
                << bd_addr;
    }
+40 −0
Original line number Diff line number Diff line
@@ -179,6 +179,46 @@ TEST_F(EattTest, ConnectSucceed) {
  DisconnectEattDevice(connected_cids_);
}

TEST_F(EattTest, IncomingEattConnectionByUnknownDevice) {
  std::vector<uint16_t> incoming_cids{71, 72, 73, 74, 75};

  EXPECT_CALL(l2cap_interface_,
              ConnectCreditBasedRsp(test_address, 1, incoming_cids,
                                    L2CAP_CONN_NO_RESOURCES, _))
      .WillOnce(Return(true));

  l2cap_app_info_.pL2CA_CreditBasedConnectInd_Cb(
      test_address, incoming_cids, BT_PSM_EATT, EATT_MIN_MTU_MPS, 1);
}

TEST_F(EattTest, IncomingEattConnectionByKnownDevice) {
  hci_role_ = HCI_ROLE_PERIPHERAL;
  ON_CALL(gatt_interface_, ClientReadSupportedFeatures)
      .WillByDefault(
          [](const RawAddress& addr,
             base::OnceCallback<void(const RawAddress&, uint8_t)> cb) {
            std::move(cb).Run(addr, BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK);
            return true;
          });
  ON_CALL(gatt_interface_, GetEattSupport)
      .WillByDefault([](const RawAddress& addr) { return true; });

  eatt_instance_->Connect(test_address);
  std::vector<uint16_t> incoming_cids{71, 72, 73, 74, 75};

  EXPECT_CALL(
      l2cap_interface_,
      ConnectCreditBasedRsp(test_address, 1, incoming_cids, L2CAP_CONN_OK, _))
      .WillOnce(Return(true));

  l2cap_app_info_.pL2CA_CreditBasedConnectInd_Cb(
      test_address, incoming_cids, BT_PSM_EATT, EATT_MIN_MTU_MPS, 1);

  DisconnectEattDevice(incoming_cids);

  hci_role_ = HCI_ROLE_CENTRAL;
}

TEST_F(EattTest, ReconnectInitiatedByRemoteSucceed) {
  ConnectDeviceEattSupported(1);
  DisconnectEattDevice(connected_cids_);