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

Commit d743f200 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "GD: Add cert test for background connection"

parents d1d3c517 18423252
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ from cert.closable import Closable
from cert.closable import safeClose
from bluetooth_packets_python3 import hci_packets
from cert.truth import assertThat
from datetime import timedelta
from hci.facade import le_acl_manager_facade_pb2 as le_acl_manager_facade


@@ -98,6 +99,14 @@ class PyLeAclManager(Closable):
        self.listen_for_incoming_connections()
        return self.complete_incoming_connection()

    def wait_for_connection_fail(self, token):
        assertThat(self.outgoing_connection_event_streams[token]).isNotNone()
        event_stream = self.outgoing_connection_event_streams[token][0]
        connection_fail = HciCaptures.LeConnectionCompleteCapture()
        assertThat(event_stream).emits(connection_fail, timeout=timedelta(seconds=35))
        complete = connection_fail.get()
        assertThat(complete.GetStatus() == hci_packets.ErrorCode.CONNECTION_ACCEPT_TIMEOUT).isTrue()

    def cancel_connection(self, token):
        assertThat(token in self.outgoing_connection_event_streams).isTrue()
        pair = self.outgoing_connection_event_streams.pop(token)
@@ -112,6 +121,14 @@ class PyLeAclManager(Closable):
        self.next_token += 1
        return token

    def initiate_background_and_direct_connection(self, remote_addr):
        assertThat(self.next_token in self.outgoing_connection_event_streams).isFalse()
        self.outgoing_connection_event_streams[self.next_token] = EventStream(
            self.le_acl_manager.CreateBackgroundAndDirectConnection(remote_addr)), remote_addr
        token = self.next_token
        self.next_token += 1
        return token

    def complete_connection(self, event_stream):
        connection_complete = HciCaptures.LeConnectionCompleteCapture()
        assertThat(event_stream).emits(connection_complete)
+63 −0
Original line number Diff line number Diff line
@@ -285,3 +285,66 @@ class LeAclManagerTestBase():
                              hci_packets.BroadcastFlag.POINT_TO_POINT, bytes(b'!'))

        assertThat(self.dut_le_acl).emits(lambda packet: b'Hello!' in packet.payload)

    def test_background_connection(self):
        self.register_for_le_event(hci_packets.SubeventCode.CONNECTION_COMPLETE)
        self.register_for_le_event(hci_packets.SubeventCode.ENHANCED_CONNECTION_COMPLETE)
        self.set_privacy_policy_static()

        # Start background and direct connection
        token = self.dut_le_acl_manager.initiate_background_and_direct_connection(
            remote_addr=common.BluetoothAddressWithType(
                address=common.BluetoothAddress(address=bytes('0C:05:04:03:02:01', 'utf8')),
                type=int(hci_packets.AddressType.RANDOM_DEVICE_ADDRESS)))

        # Wait for direct connection timeout
        self.dut_le_acl_manager.wait_for_connection_fail(token)

        # Cert Advertises
        advertising_handle = 0
        self.enqueue_hci_command(
            hci_packets.LeSetExtendedAdvertisingLegacyParametersBuilder(
                advertising_handle,
                hci_packets.LegacyAdvertisingProperties.ADV_IND,
                400,
                450,
                7,
                hci_packets.OwnAddressType.RANDOM_DEVICE_ADDRESS,
                hci_packets.PeerAddressType.PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
                '00:00:00:00:00:00',
                hci_packets.AdvertisingFilterPolicy.ALL_DEVICES,
                0xF8,
                1,  #SID
                hci_packets.Enable.DISABLED  # Scan request notification
            ))

        self.enqueue_hci_command(
            hci_packets.LeSetExtendedAdvertisingRandomAddressBuilder(advertising_handle, '0C:05:04:03:02:01'))

        gap_name = hci_packets.GapData()
        gap_name.data_type = hci_packets.GapDataType.COMPLETE_LOCAL_NAME
        gap_name.data = list(bytes(b'Im_A_Cert'))

        self.enqueue_hci_command(
            hci_packets.LeSetExtendedAdvertisingDataBuilder(
                advertising_handle, hci_packets.Operation.COMPLETE_ADVERTISEMENT,
                hci_packets.FragmentPreference.CONTROLLER_SHOULD_NOT, [gap_name]))

        gap_short_name = hci_packets.GapData()
        gap_short_name.data_type = hci_packets.GapDataType.SHORTENED_LOCAL_NAME
        gap_short_name.data = list(bytes(b'Im_A_C'))

        self.enqueue_hci_command(
            hci_packets.LeSetExtendedAdvertisingScanResponseBuilder(
                advertising_handle, hci_packets.Operation.COMPLETE_ADVERTISEMENT,
                hci_packets.FragmentPreference.CONTROLLER_SHOULD_NOT, [gap_short_name]))

        enabled_set = hci_packets.EnabledSet()
        enabled_set.advertising_handle = advertising_handle
        enabled_set.duration = 0
        enabled_set.max_extended_advertising_events = 0
        self.enqueue_hci_command(
            hci_packets.LeSetExtendedAdvertisingEnableBuilder(hci_packets.Enable.ENABLED, [enabled_set]))

        # Check background connection complete
        self.dut_le_acl_manager.complete_outgoing_connection(token)
 No newline at end of file
+24 −1
Original line number Diff line number Diff line
@@ -75,6 +75,25 @@ class LeAclManagerFacadeService : public LeAclManagerFacade::Service, public LeC
    return per_connection_events_[current_connection_request_]->RunLoop(context, writer);
  }

  ::grpc::Status CreateBackgroundAndDirectConnection(
      ::grpc::ServerContext* context,
      const ::bluetooth::facade::BluetoothAddressWithType* request,
      ::grpc::ServerWriter<LeConnectionEvent>* writer) override {
    Address peer_address;
    ASSERT(Address::FromString(request->address().address(), peer_address));
    AddressWithType peer(peer_address, static_cast<AddressType>(request->type()));
    // Create background connection first
    acl_manager_->CreateLeConnection(peer, /* is_direct */ false);
    acl_manager_->CreateLeConnection(peer, /* is_direct */ true);
    wait_for_background_connection_complete = true;
    if (per_connection_events_.size() > current_connection_request_) {
      return ::grpc::Status(::grpc::StatusCode::RESOURCE_EXHAUSTED, "Only one outstanding request is supported");
    }
    per_connection_events_.emplace_back(std::make_unique<::bluetooth::grpc::GrpcEventQueue<LeConnectionEvent>>(
        std::string("connection attempt ") + std::to_string(current_connection_request_)));
    return per_connection_events_[current_connection_request_]->RunLoop(context, writer);
  }

  ::grpc::Status CancelConnection(
      ::grpc::ServerContext* context,
      const ::bluetooth::facade::BluetoothAddressWithType* request,
@@ -243,6 +262,7 @@ class LeAclManagerFacadeService : public LeAclManagerFacade::Service, public LeC
      success.set_payload(builder_to_string(std::move(builder)));
      per_connection_events_[current_connection_request_]->OnIncomingEvent(success);
    }
    wait_for_background_connection_complete = false;
    current_connection_request_++;
  }

@@ -252,8 +272,10 @@ class LeAclManagerFacadeService : public LeAclManagerFacade::Service, public LeC
    LeConnectionEvent fail;
    fail.set_payload(builder_to_string(std::move(builder)));
    per_connection_events_[current_connection_request_]->OnIncomingEvent(fail);
    if (!wait_for_background_connection_complete) {
      current_connection_request_++;
    }
  }

  class Connection : public LeConnectionManagementCallbacks {
   public:
@@ -310,6 +332,7 @@ class LeAclManagerFacadeService : public LeAclManagerFacade::Service, public LeC
  std::vector<std::shared_ptr<::bluetooth::grpc::GrpcEventQueue<LeConnectionEvent>>> per_connection_events_;
  std::map<uint16_t, Connection> acl_connections_;
  uint32_t current_connection_request_{0};
  bool wait_for_background_connection_complete = false;
};

void LeAclManagerFacadeModule::ListDependencies(ModuleList* list) const {
+2 −0
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@ import "facade/common.proto";

service LeAclManagerFacade {
  rpc CreateConnection(bluetooth.facade.BluetoothAddressWithType) returns (stream LeConnectionEvent) {}
  rpc CreateBackgroundAndDirectConnection(bluetooth.facade.BluetoothAddressWithType)
      returns (stream LeConnectionEvent) {}
  rpc CancelConnection(bluetooth.facade.BluetoothAddressWithType) returns (google.protobuf.Empty) {}
  rpc Disconnect(LeHandleMsg) returns (google.protobuf.Empty) {}
  rpc ConnectionCommand(LeConnectionCommandMsg) returns (google.protobuf.Empty) {}