Loading system/gd/cert/gd_cert_device.py +3 −0 Original line number Original line Diff line number Diff line Loading @@ -71,6 +71,9 @@ class GdCertDevice(GdDeviceBase): self.l2cap = l2cap_cert_pb2_grpc.L2capModuleCertStub(self.grpc_channel) self.l2cap = l2cap_cert_pb2_grpc.L2capModuleCertStub(self.grpc_channel) # Event streams # Event streams self.hal.hci_event_stream = EventStream(self.hal.FetchHciEvent) self.hal.hci_acl_stream = EventStream(self.hal.FetchHciAcl) self.hal.hci_sco_stream = EventStream(self.hal.FetchHciSco) self.hci.connection_complete_stream = EventStream(self.hci.FetchConnectionComplete) self.hci.connection_complete_stream = EventStream(self.hci.FetchConnectionComplete) self.hci.disconnection_stream = EventStream(self.hci.FetchDisconnection) self.hci.disconnection_stream = EventStream(self.hci.FetchDisconnection) self.hci.connection_failed_stream = EventStream(self.hci.FetchConnectionFailed) self.hci.connection_failed_stream = EventStream(self.hci.FetchConnectionFailed) Loading system/gd/hal/cert/simple_hal_test.py +145 −0 Original line number Original line Diff line number Diff line Loading @@ -56,6 +56,9 @@ class SimpleHalTest(GdBaseTestClass): self.cert_device.hal.SendHciResetCommand(empty_pb2.Empty()) self.cert_device.hal.SendHciResetCommand(empty_pb2.Empty()) self.hci_event_stream = self.device_under_test.hal.hci_event_stream self.hci_event_stream = self.device_under_test.hal.hci_event_stream self.cert_hci_event_stream = self.cert_device.hal.hci_event_stream self.hci_acl_stream = self.device_under_test.hal.hci_acl_stream self.cert_hci_acl_stream = self.cert_device.hal.hci_acl_stream def teardown_test(self): def teardown_test(self): self.device_under_test.rootservice.StopStack( self.device_under_test.rootservice.StopStack( Loading @@ -64,6 +67,8 @@ class SimpleHalTest(GdBaseTestClass): self.cert_device.rootservice.StopStack( self.cert_device.rootservice.StopStack( cert_rootservice_pb2.StopStackRequest() cert_rootservice_pb2.StopStackRequest() ) ) self.hci_event_stream.clear_event_buffer() self.cert_hci_event_stream.clear_event_buffer() def test_none_event(self): def test_none_event(self): self.hci_event_stream.clear_event_buffer() self.hci_event_stream.clear_event_buffer() Loading Loading @@ -109,3 +114,143 @@ class SimpleHalTest(GdBaseTestClass): # Expecting an HCI Event (code 0x02, length 0x0f) # Expecting an HCI Event (code 0x02, length 0x0f) ) ) self.hci_event_stream.unsubscribe() self.hci_event_stream.unsubscribe() def test_le_ad_scan_cert_advertises(self): self.hci_event_stream.subscribe() # Set the LE Address to 0D:05:04:03:02:01 self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x05\x20\x06\x01\x02\x03\x04\x05\x0D' ) ) # Set the LE Scan parameters (active, 40ms, 20ms, Random, self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x0B\x20\x07\x01\x40\x00\x20\x00\x01\x00' ) ) # Enable Scanning (Disable duplicate filtering) self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x0C\x20\x02\x01\x00' ) ) # Set the LE Address to 0C:05:04:03:02:01 self.cert_device.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x05\x20\x06\x01\x02\x03\x04\x05\x0C' ) ) # Set LE Advertising parameters self.cert_device.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x06\x20\x0F\x00\x02\x00\x03\x00\x01\x00\xA1\xA2\xA3\xA4\xA5\xA6\x07\x00' ) ) # Set LE Advertising data self.cert_device.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x08\x20\x20\x0C\x0A\x09Im_A_Cert\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ) ) # Enable Advertising self.cert_device.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x0A\x20\x01\x01' ) ) self.hci_event_stream.assert_event_occurs( lambda packet: b'Im_A_Cert' in packet.payload # Expecting an HCI Event (code 0x3e, length 0x13, subevent 0x01 ) ) # Disable Advertising self.cert_device.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x0A\x20\x01\x00' ) ) # Disable Scanning self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x0C\x20\x02\x00\x00' ) ) self.hci_event_stream.unsubscribe() def test_le_connection_dut_advertises(self): self.hci_event_stream.subscribe() self.cert_hci_event_stream.subscribe() self.hci_acl_stream.subscribe() self.cert_hci_acl_stream.subscribe() # Set the CERT LE Address to 0C:05:04:03:02:01 self.cert_device.hal.SendHciCommand( hal_cert_pb2.HciCommandPacket( payload=b'\x05\x20\x06\x01\x02\x03\x04\x05\x0C' ) ) # Direct connect to 0D:05:04:03:02:01 self.cert_device.hal.SendHciCommand( hal_cert_pb2.HciCommandPacket( payload=b'\x0D\x20\x19\x11\x01\x22\x02\x00\x01\x01\x02\x03\x04\x05\x0D\x01\x06\x00\x70\x0C\x40\x00\x03\x07\x01\x00\x02\x00' ) ) # Set the LE Address to 0D:05:04:03:02:01 self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x05\x20\x06\x01\x02\x03\x04\x05\x0D' ) ) # Set LE Advertising parameters self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x06\x20\x0F\x80\x00\x00\x04\x00\x01\x00\xA1\xA2\xA3\xA4\xA5\xA6\x07\x00' ) ) # Set LE Advertising data self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x08\x20\x20\x0C\x0B\x09Im_The_DUT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ) ) # Enable Advertising self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x0A\x20\x01\x01' ) ) # LeConnectionComplete TODO: Extract the handle self.cert_hci_event_stream.assert_event_occurs( lambda packet: b'\x3e\x13\x01' in packet.payload ) # LeConnectionComplete TODO: Extract the handle self.hci_event_stream.assert_event_occurs( lambda packet: b'\x3e\x13\x01' in packet.payload ) # Send ACL Data self.device_under_test.hal.SendHciAcl( hal_facade_pb2.HciAclPacket( payload=b'\xfe\x0e\x0b\x00SomeAclData' ) ) # Send ACL Data self.cert_device.hal.SendHciAcl( hal_facade_pb2.HciAclPacket( payload=b'\xfe\x0e\x0f\x00SomeMoreAclData' ) ) self.cert_hci_acl_stream.assert_event_occurs( lambda packet: b'\xfe\x0e\x0b\x00SomeAclData' in packet.payload ) self.hci_acl_stream.assert_event_occurs( lambda packet: b'\xfe\x0e\x0f\x00SomeMoreAclData' in packet.payload ) self.hci_event_stream.unsubscribe() self.cert_hci_event_stream.unsubscribe() self.hci_acl_stream.unsubscribe() self.cert_hci_acl_stream.unsubscribe() system/vendor_libs/test_vendor_lib/include/link.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -36,6 +36,8 @@ class Link { IO_CAPABILITY_RESPONSE, IO_CAPABILITY_RESPONSE, IO_CAPABILITY_NEGATIVE_RESPONSE, IO_CAPABILITY_NEGATIVE_RESPONSE, LE_ADVERTISEMENT, LE_ADVERTISEMENT, LE_CONNECT, LE_CONNECT_COMPLETE, LE_SCAN, LE_SCAN, LE_SCAN_RESPONSE, LE_SCAN_RESPONSE, PAGE, PAGE, Loading system/vendor_libs/test_vendor_lib/model/controller/acl_connection.h +19 −12 Original line number Original line Diff line number Diff line Loading @@ -25,17 +25,10 @@ namespace test_vendor_lib { // Model the connection of a device to the controller. // Model the connection of a device to the controller. class AclConnection { class AclConnection { public: public: AclConnection(const Address& addr) : address_(addr), connected_(false), encrypted_(false) {} AclConnection(Address addr) : address_(addr), address_type_(0), own_address_type_(0) {} virtual ~AclConnection() = default; virtual ~AclConnection() = default; void SetConnected(bool connected) { connected_ = connected; }; bool IsConnected() const { return connected_; }; void Encrypt() { void Encrypt() { encrypted_ = true; encrypted_ = true; }; }; Loading @@ -43,19 +36,33 @@ class AclConnection { return encrypted_; return encrypted_; }; }; const Address& GetAddress() const { Address GetAddress() const { return address_; return address_; } } void SetAddress(const Address& address) { void SetAddress(Address address) { address_ = address; address_ = address; } } uint8_t GetAddressType() const { return address_type_; } void SetAddressType(uint8_t address_type) { address_type_ = address_type; } uint8_t GetOwnAddressType() const { return own_address_type_; } void SetOwnAddressType(uint8_t address_type) { own_address_type_ = address_type; } private: private: Address address_; Address address_; uint8_t address_type_; uint8_t own_address_type_; // State variables // State variables bool connected_; bool encrypted_{false}; bool encrypted_; }; }; } // namespace test_vendor_lib } // namespace test_vendor_lib system/vendor_libs/test_vendor_lib/model/controller/acl_connection_handler.cc +87 −25 Original line number Original line Diff line number Diff line Loading @@ -35,40 +35,82 @@ bool AclConnectionHandler::HasHandle(uint16_t handle) const { } } uint16_t AclConnectionHandler::GetUnusedHandle() { uint16_t AclConnectionHandler::GetUnusedHandle() { static uint16_t sNextHandle = acl::kReservedHandle - 2; while (acl_connections_.count(last_handle_) == 1) { while (acl_connections_.count(sNextHandle) == 1) { last_handle_ = (last_handle_ + 1) % acl::kReservedHandle; sNextHandle = (sNextHandle + 1) % acl::kReservedHandle; } } uint16_t unused_handle = sNextHandle; uint16_t unused_handle = last_handle_; sNextHandle = (sNextHandle + 1) % acl::kReservedHandle; last_handle_ = (last_handle_ + 1) % acl::kReservedHandle; return unused_handle; return unused_handle; } } bool AclConnectionHandler::CreatePendingConnection(const Address& addr) { bool AclConnectionHandler::CreatePendingConnection(Address addr) { if ((pending_connections_.size() + 1 > max_pending_connections_) || HasPendingConnection(addr)) { if (classic_connection_pending_) { return false; return false; } } pending_connections_.insert(addr); classic_connection_pending_ = true; pending_connection_address_ = addr; return true; return true; } } bool AclConnectionHandler::HasPendingConnection(const Address& addr) { bool AclConnectionHandler::HasPendingConnection(Address addr) { return pending_connections_.count(addr) == 1; return classic_connection_pending_ && pending_connection_address_ == addr; } } bool AclConnectionHandler::CancelPendingConnection(const Address& addr) { bool AclConnectionHandler::CancelPendingConnection(Address addr) { if (!HasPendingConnection(addr)) { if (!classic_connection_pending_ || pending_connection_address_ != addr) { return false; return false; } } pending_connections_.erase(addr); classic_connection_pending_ = false; pending_connection_address_ = Address::kEmpty; return true; return true; } } uint16_t AclConnectionHandler::CreateConnection(const Address& addr) { bool AclConnectionHandler::CreatePendingLeConnection(Address addr, uint8_t address_type) { if (IsDeviceConnected(addr, address_type)) { LOG_INFO(LOG_TAG, "%s: %s (type %hhx) is already connected", __func__, addr.ToString().c_str(), address_type); return false; } if (le_connection_pending_) { LOG_INFO(LOG_TAG, "%s: connection already pending", __func__); return false; } le_connection_pending_ = true; pending_le_connection_address_ = addr; pending_le_connection_address_type_ = address_type; return true; } bool AclConnectionHandler::HasPendingLeConnection(Address addr, uint8_t address_type) { return le_connection_pending_ && pending_le_connection_address_ == addr && pending_le_connection_address_type_ == address_type; } bool AclConnectionHandler::CancelPendingLeConnection(Address addr, uint8_t address_type) { if (!le_connection_pending_ || pending_le_connection_address_ != addr || pending_le_connection_address_type_ != address_type) { return false; } le_connection_pending_ = false; pending_le_connection_address_ = Address::kEmpty; pending_le_connection_address_type_ = 0xba; return true; } uint16_t AclConnectionHandler::CreateConnection(Address addr) { if (CancelPendingConnection(addr)) { if (CancelPendingConnection(addr)) { uint16_t handle = GetUnusedHandle(); uint16_t handle = GetUnusedHandle(); acl_connections_.emplace(handle, addr); acl_connections_.emplace(handle, addr); SetConnected(handle, true); return handle; } return acl::kReservedHandle; } uint16_t AclConnectionHandler::CreateLeConnection(Address addr, uint8_t address_type, uint8_t own_address_type) { if (CancelPendingLeConnection(addr, address_type)) { uint16_t handle = GetUnusedHandle(); acl_connections_.emplace(handle, addr); set_own_address_type(handle, own_address_type); SetAddress(handle, addr, address_type); return handle; return handle; } } return acl::kReservedHandle; return acl::kReservedHandle; Loading @@ -78,7 +120,7 @@ bool AclConnectionHandler::Disconnect(uint16_t handle) { return acl_connections_.erase(handle) > 0; return acl_connections_.erase(handle) > 0; } } uint16_t AclConnectionHandler::GetHandle(const Address& addr) const { uint16_t AclConnectionHandler::GetHandle(Address addr) const { for (auto pair : acl_connections_) { for (auto pair : acl_connections_) { if (std::get<AclConnection>(pair).GetAddress() == addr) { if (std::get<AclConnection>(pair).GetAddress() == addr) { return std::get<0>(pair); return std::get<0>(pair); Loading @@ -87,23 +129,41 @@ uint16_t AclConnectionHandler::GetHandle(const Address& addr) const { return acl::kReservedHandle; return acl::kReservedHandle; } } const Address& AclConnectionHandler::GetAddress(uint16_t handle) const { Address AclConnectionHandler::GetAddress(uint16_t handle) const { CHECK(HasHandle(handle)) << "Handle unknown " << handle; CHECK(HasHandle(handle)) << "Handle unknown " << handle; return acl_connections_.at(handle).GetAddress(); return acl_connections_.at(handle).GetAddress(); } } void AclConnectionHandler::SetConnected(uint16_t handle, bool connected) { uint8_t AclConnectionHandler::GetAddressType(uint16_t handle) const { if (!HasHandle(handle)) { CHECK(HasHandle(handle)) << "Handle unknown " << handle; return; return acl_connections_.at(handle).GetAddressType(); } } acl_connections_.at(handle).SetConnected(connected); void AclConnectionHandler::set_own_address_type(uint16_t handle, uint8_t address_type) { CHECK(HasHandle(handle)) << "Handle unknown " << handle; acl_connections_.at(handle).SetOwnAddressType(address_type); } uint8_t AclConnectionHandler::GetOwnAddressType(uint16_t handle) const { CHECK(HasHandle(handle)) << "Handle unknown " << handle; return acl_connections_.at(handle).GetOwnAddressType(); } } bool AclConnectionHandler::IsConnected(uint16_t handle) const { bool AclConnectionHandler::IsConnected(uint16_t handle) const { if (!HasHandle(handle)) { if (!HasHandle(handle)) { return false; return false; } } return acl_connections_.at(handle).IsConnected(); return true; } bool AclConnectionHandler::IsDeviceConnected(Address addr, uint8_t address_type) const { for (auto pair : acl_connections_) { auto connection = std::get<AclConnection>(pair); if (connection.GetAddress() == addr && connection.GetAddressType() == address_type) { return true; } } return false; } } void AclConnectionHandler::Encrypt(uint16_t handle) { void AclConnectionHandler::Encrypt(uint16_t handle) { Loading @@ -120,11 +180,13 @@ bool AclConnectionHandler::IsEncrypted(uint16_t handle) const { return acl_connections_.at(handle).IsEncrypted(); return acl_connections_.at(handle).IsEncrypted(); } } void AclConnectionHandler::SetAddress(uint16_t handle, const Address& address) { void AclConnectionHandler::SetAddress(uint16_t handle, Address address, uint8_t address_type) { if (!HasHandle(handle)) { if (!HasHandle(handle)) { return; return; } } acl_connections_.at(handle).SetAddress(address); auto connection = acl_connections_.at(handle); connection.SetAddress(address); connection.SetAddressType(address_type); } } } // namespace test_vendor_lib } // namespace test_vendor_lib Loading
system/gd/cert/gd_cert_device.py +3 −0 Original line number Original line Diff line number Diff line Loading @@ -71,6 +71,9 @@ class GdCertDevice(GdDeviceBase): self.l2cap = l2cap_cert_pb2_grpc.L2capModuleCertStub(self.grpc_channel) self.l2cap = l2cap_cert_pb2_grpc.L2capModuleCertStub(self.grpc_channel) # Event streams # Event streams self.hal.hci_event_stream = EventStream(self.hal.FetchHciEvent) self.hal.hci_acl_stream = EventStream(self.hal.FetchHciAcl) self.hal.hci_sco_stream = EventStream(self.hal.FetchHciSco) self.hci.connection_complete_stream = EventStream(self.hci.FetchConnectionComplete) self.hci.connection_complete_stream = EventStream(self.hci.FetchConnectionComplete) self.hci.disconnection_stream = EventStream(self.hci.FetchDisconnection) self.hci.disconnection_stream = EventStream(self.hci.FetchDisconnection) self.hci.connection_failed_stream = EventStream(self.hci.FetchConnectionFailed) self.hci.connection_failed_stream = EventStream(self.hci.FetchConnectionFailed) Loading
system/gd/hal/cert/simple_hal_test.py +145 −0 Original line number Original line Diff line number Diff line Loading @@ -56,6 +56,9 @@ class SimpleHalTest(GdBaseTestClass): self.cert_device.hal.SendHciResetCommand(empty_pb2.Empty()) self.cert_device.hal.SendHciResetCommand(empty_pb2.Empty()) self.hci_event_stream = self.device_under_test.hal.hci_event_stream self.hci_event_stream = self.device_under_test.hal.hci_event_stream self.cert_hci_event_stream = self.cert_device.hal.hci_event_stream self.hci_acl_stream = self.device_under_test.hal.hci_acl_stream self.cert_hci_acl_stream = self.cert_device.hal.hci_acl_stream def teardown_test(self): def teardown_test(self): self.device_under_test.rootservice.StopStack( self.device_under_test.rootservice.StopStack( Loading @@ -64,6 +67,8 @@ class SimpleHalTest(GdBaseTestClass): self.cert_device.rootservice.StopStack( self.cert_device.rootservice.StopStack( cert_rootservice_pb2.StopStackRequest() cert_rootservice_pb2.StopStackRequest() ) ) self.hci_event_stream.clear_event_buffer() self.cert_hci_event_stream.clear_event_buffer() def test_none_event(self): def test_none_event(self): self.hci_event_stream.clear_event_buffer() self.hci_event_stream.clear_event_buffer() Loading Loading @@ -109,3 +114,143 @@ class SimpleHalTest(GdBaseTestClass): # Expecting an HCI Event (code 0x02, length 0x0f) # Expecting an HCI Event (code 0x02, length 0x0f) ) ) self.hci_event_stream.unsubscribe() self.hci_event_stream.unsubscribe() def test_le_ad_scan_cert_advertises(self): self.hci_event_stream.subscribe() # Set the LE Address to 0D:05:04:03:02:01 self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x05\x20\x06\x01\x02\x03\x04\x05\x0D' ) ) # Set the LE Scan parameters (active, 40ms, 20ms, Random, self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x0B\x20\x07\x01\x40\x00\x20\x00\x01\x00' ) ) # Enable Scanning (Disable duplicate filtering) self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x0C\x20\x02\x01\x00' ) ) # Set the LE Address to 0C:05:04:03:02:01 self.cert_device.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x05\x20\x06\x01\x02\x03\x04\x05\x0C' ) ) # Set LE Advertising parameters self.cert_device.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x06\x20\x0F\x00\x02\x00\x03\x00\x01\x00\xA1\xA2\xA3\xA4\xA5\xA6\x07\x00' ) ) # Set LE Advertising data self.cert_device.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x08\x20\x20\x0C\x0A\x09Im_A_Cert\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ) ) # Enable Advertising self.cert_device.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x0A\x20\x01\x01' ) ) self.hci_event_stream.assert_event_occurs( lambda packet: b'Im_A_Cert' in packet.payload # Expecting an HCI Event (code 0x3e, length 0x13, subevent 0x01 ) ) # Disable Advertising self.cert_device.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x0A\x20\x01\x00' ) ) # Disable Scanning self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x0C\x20\x02\x00\x00' ) ) self.hci_event_stream.unsubscribe() def test_le_connection_dut_advertises(self): self.hci_event_stream.subscribe() self.cert_hci_event_stream.subscribe() self.hci_acl_stream.subscribe() self.cert_hci_acl_stream.subscribe() # Set the CERT LE Address to 0C:05:04:03:02:01 self.cert_device.hal.SendHciCommand( hal_cert_pb2.HciCommandPacket( payload=b'\x05\x20\x06\x01\x02\x03\x04\x05\x0C' ) ) # Direct connect to 0D:05:04:03:02:01 self.cert_device.hal.SendHciCommand( hal_cert_pb2.HciCommandPacket( payload=b'\x0D\x20\x19\x11\x01\x22\x02\x00\x01\x01\x02\x03\x04\x05\x0D\x01\x06\x00\x70\x0C\x40\x00\x03\x07\x01\x00\x02\x00' ) ) # Set the LE Address to 0D:05:04:03:02:01 self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x05\x20\x06\x01\x02\x03\x04\x05\x0D' ) ) # Set LE Advertising parameters self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x06\x20\x0F\x80\x00\x00\x04\x00\x01\x00\xA1\xA2\xA3\xA4\xA5\xA6\x07\x00' ) ) # Set LE Advertising data self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x08\x20\x20\x0C\x0B\x09Im_The_DUT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ) ) # Enable Advertising self.device_under_test.hal.SendHciCommand( hal_facade_pb2.HciCommandPacket( payload=b'\x0A\x20\x01\x01' ) ) # LeConnectionComplete TODO: Extract the handle self.cert_hci_event_stream.assert_event_occurs( lambda packet: b'\x3e\x13\x01' in packet.payload ) # LeConnectionComplete TODO: Extract the handle self.hci_event_stream.assert_event_occurs( lambda packet: b'\x3e\x13\x01' in packet.payload ) # Send ACL Data self.device_under_test.hal.SendHciAcl( hal_facade_pb2.HciAclPacket( payload=b'\xfe\x0e\x0b\x00SomeAclData' ) ) # Send ACL Data self.cert_device.hal.SendHciAcl( hal_facade_pb2.HciAclPacket( payload=b'\xfe\x0e\x0f\x00SomeMoreAclData' ) ) self.cert_hci_acl_stream.assert_event_occurs( lambda packet: b'\xfe\x0e\x0b\x00SomeAclData' in packet.payload ) self.hci_acl_stream.assert_event_occurs( lambda packet: b'\xfe\x0e\x0f\x00SomeMoreAclData' in packet.payload ) self.hci_event_stream.unsubscribe() self.cert_hci_event_stream.unsubscribe() self.hci_acl_stream.unsubscribe() self.cert_hci_acl_stream.unsubscribe()
system/vendor_libs/test_vendor_lib/include/link.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -36,6 +36,8 @@ class Link { IO_CAPABILITY_RESPONSE, IO_CAPABILITY_RESPONSE, IO_CAPABILITY_NEGATIVE_RESPONSE, IO_CAPABILITY_NEGATIVE_RESPONSE, LE_ADVERTISEMENT, LE_ADVERTISEMENT, LE_CONNECT, LE_CONNECT_COMPLETE, LE_SCAN, LE_SCAN, LE_SCAN_RESPONSE, LE_SCAN_RESPONSE, PAGE, PAGE, Loading
system/vendor_libs/test_vendor_lib/model/controller/acl_connection.h +19 −12 Original line number Original line Diff line number Diff line Loading @@ -25,17 +25,10 @@ namespace test_vendor_lib { // Model the connection of a device to the controller. // Model the connection of a device to the controller. class AclConnection { class AclConnection { public: public: AclConnection(const Address& addr) : address_(addr), connected_(false), encrypted_(false) {} AclConnection(Address addr) : address_(addr), address_type_(0), own_address_type_(0) {} virtual ~AclConnection() = default; virtual ~AclConnection() = default; void SetConnected(bool connected) { connected_ = connected; }; bool IsConnected() const { return connected_; }; void Encrypt() { void Encrypt() { encrypted_ = true; encrypted_ = true; }; }; Loading @@ -43,19 +36,33 @@ class AclConnection { return encrypted_; return encrypted_; }; }; const Address& GetAddress() const { Address GetAddress() const { return address_; return address_; } } void SetAddress(const Address& address) { void SetAddress(Address address) { address_ = address; address_ = address; } } uint8_t GetAddressType() const { return address_type_; } void SetAddressType(uint8_t address_type) { address_type_ = address_type; } uint8_t GetOwnAddressType() const { return own_address_type_; } void SetOwnAddressType(uint8_t address_type) { own_address_type_ = address_type; } private: private: Address address_; Address address_; uint8_t address_type_; uint8_t own_address_type_; // State variables // State variables bool connected_; bool encrypted_{false}; bool encrypted_; }; }; } // namespace test_vendor_lib } // namespace test_vendor_lib
system/vendor_libs/test_vendor_lib/model/controller/acl_connection_handler.cc +87 −25 Original line number Original line Diff line number Diff line Loading @@ -35,40 +35,82 @@ bool AclConnectionHandler::HasHandle(uint16_t handle) const { } } uint16_t AclConnectionHandler::GetUnusedHandle() { uint16_t AclConnectionHandler::GetUnusedHandle() { static uint16_t sNextHandle = acl::kReservedHandle - 2; while (acl_connections_.count(last_handle_) == 1) { while (acl_connections_.count(sNextHandle) == 1) { last_handle_ = (last_handle_ + 1) % acl::kReservedHandle; sNextHandle = (sNextHandle + 1) % acl::kReservedHandle; } } uint16_t unused_handle = sNextHandle; uint16_t unused_handle = last_handle_; sNextHandle = (sNextHandle + 1) % acl::kReservedHandle; last_handle_ = (last_handle_ + 1) % acl::kReservedHandle; return unused_handle; return unused_handle; } } bool AclConnectionHandler::CreatePendingConnection(const Address& addr) { bool AclConnectionHandler::CreatePendingConnection(Address addr) { if ((pending_connections_.size() + 1 > max_pending_connections_) || HasPendingConnection(addr)) { if (classic_connection_pending_) { return false; return false; } } pending_connections_.insert(addr); classic_connection_pending_ = true; pending_connection_address_ = addr; return true; return true; } } bool AclConnectionHandler::HasPendingConnection(const Address& addr) { bool AclConnectionHandler::HasPendingConnection(Address addr) { return pending_connections_.count(addr) == 1; return classic_connection_pending_ && pending_connection_address_ == addr; } } bool AclConnectionHandler::CancelPendingConnection(const Address& addr) { bool AclConnectionHandler::CancelPendingConnection(Address addr) { if (!HasPendingConnection(addr)) { if (!classic_connection_pending_ || pending_connection_address_ != addr) { return false; return false; } } pending_connections_.erase(addr); classic_connection_pending_ = false; pending_connection_address_ = Address::kEmpty; return true; return true; } } uint16_t AclConnectionHandler::CreateConnection(const Address& addr) { bool AclConnectionHandler::CreatePendingLeConnection(Address addr, uint8_t address_type) { if (IsDeviceConnected(addr, address_type)) { LOG_INFO(LOG_TAG, "%s: %s (type %hhx) is already connected", __func__, addr.ToString().c_str(), address_type); return false; } if (le_connection_pending_) { LOG_INFO(LOG_TAG, "%s: connection already pending", __func__); return false; } le_connection_pending_ = true; pending_le_connection_address_ = addr; pending_le_connection_address_type_ = address_type; return true; } bool AclConnectionHandler::HasPendingLeConnection(Address addr, uint8_t address_type) { return le_connection_pending_ && pending_le_connection_address_ == addr && pending_le_connection_address_type_ == address_type; } bool AclConnectionHandler::CancelPendingLeConnection(Address addr, uint8_t address_type) { if (!le_connection_pending_ || pending_le_connection_address_ != addr || pending_le_connection_address_type_ != address_type) { return false; } le_connection_pending_ = false; pending_le_connection_address_ = Address::kEmpty; pending_le_connection_address_type_ = 0xba; return true; } uint16_t AclConnectionHandler::CreateConnection(Address addr) { if (CancelPendingConnection(addr)) { if (CancelPendingConnection(addr)) { uint16_t handle = GetUnusedHandle(); uint16_t handle = GetUnusedHandle(); acl_connections_.emplace(handle, addr); acl_connections_.emplace(handle, addr); SetConnected(handle, true); return handle; } return acl::kReservedHandle; } uint16_t AclConnectionHandler::CreateLeConnection(Address addr, uint8_t address_type, uint8_t own_address_type) { if (CancelPendingLeConnection(addr, address_type)) { uint16_t handle = GetUnusedHandle(); acl_connections_.emplace(handle, addr); set_own_address_type(handle, own_address_type); SetAddress(handle, addr, address_type); return handle; return handle; } } return acl::kReservedHandle; return acl::kReservedHandle; Loading @@ -78,7 +120,7 @@ bool AclConnectionHandler::Disconnect(uint16_t handle) { return acl_connections_.erase(handle) > 0; return acl_connections_.erase(handle) > 0; } } uint16_t AclConnectionHandler::GetHandle(const Address& addr) const { uint16_t AclConnectionHandler::GetHandle(Address addr) const { for (auto pair : acl_connections_) { for (auto pair : acl_connections_) { if (std::get<AclConnection>(pair).GetAddress() == addr) { if (std::get<AclConnection>(pair).GetAddress() == addr) { return std::get<0>(pair); return std::get<0>(pair); Loading @@ -87,23 +129,41 @@ uint16_t AclConnectionHandler::GetHandle(const Address& addr) const { return acl::kReservedHandle; return acl::kReservedHandle; } } const Address& AclConnectionHandler::GetAddress(uint16_t handle) const { Address AclConnectionHandler::GetAddress(uint16_t handle) const { CHECK(HasHandle(handle)) << "Handle unknown " << handle; CHECK(HasHandle(handle)) << "Handle unknown " << handle; return acl_connections_.at(handle).GetAddress(); return acl_connections_.at(handle).GetAddress(); } } void AclConnectionHandler::SetConnected(uint16_t handle, bool connected) { uint8_t AclConnectionHandler::GetAddressType(uint16_t handle) const { if (!HasHandle(handle)) { CHECK(HasHandle(handle)) << "Handle unknown " << handle; return; return acl_connections_.at(handle).GetAddressType(); } } acl_connections_.at(handle).SetConnected(connected); void AclConnectionHandler::set_own_address_type(uint16_t handle, uint8_t address_type) { CHECK(HasHandle(handle)) << "Handle unknown " << handle; acl_connections_.at(handle).SetOwnAddressType(address_type); } uint8_t AclConnectionHandler::GetOwnAddressType(uint16_t handle) const { CHECK(HasHandle(handle)) << "Handle unknown " << handle; return acl_connections_.at(handle).GetOwnAddressType(); } } bool AclConnectionHandler::IsConnected(uint16_t handle) const { bool AclConnectionHandler::IsConnected(uint16_t handle) const { if (!HasHandle(handle)) { if (!HasHandle(handle)) { return false; return false; } } return acl_connections_.at(handle).IsConnected(); return true; } bool AclConnectionHandler::IsDeviceConnected(Address addr, uint8_t address_type) const { for (auto pair : acl_connections_) { auto connection = std::get<AclConnection>(pair); if (connection.GetAddress() == addr && connection.GetAddressType() == address_type) { return true; } } return false; } } void AclConnectionHandler::Encrypt(uint16_t handle) { void AclConnectionHandler::Encrypt(uint16_t handle) { Loading @@ -120,11 +180,13 @@ bool AclConnectionHandler::IsEncrypted(uint16_t handle) const { return acl_connections_.at(handle).IsEncrypted(); return acl_connections_.at(handle).IsEncrypted(); } } void AclConnectionHandler::SetAddress(uint16_t handle, const Address& address) { void AclConnectionHandler::SetAddress(uint16_t handle, Address address, uint8_t address_type) { if (!HasHandle(handle)) { if (!HasHandle(handle)) { return; return; } } acl_connections_.at(handle).SetAddress(address); auto connection = acl_connections_.at(handle); connection.SetAddress(address); connection.SetAddressType(address_type); } } } // namespace test_vendor_lib } // namespace test_vendor_lib