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

Commit 7b95b4d2 authored by Chienyuan's avatar Chienyuan
Browse files

GD HCI: Classic connection management commands

Bug: 139700781
Test: run_device_cert.sh
Change-Id: I866237141610213e71ea33c662d977d1cd458387
parent f40a842e
Loading
Loading
Loading
Loading
+1011 −0

File changed.

Preview size limit exceeded, changes collapsed.

+77 −0
Original line number Diff line number Diff line
@@ -31,6 +31,53 @@ namespace hci {

class AclManager;

class ConnectionManagementCallbacks {
 public:
  virtual ~ConnectionManagementCallbacks() = default;
  // Invoked when controller sends Connection Packet Type Changed event with Success error code
  virtual void OnConnectionPacketTypeChanged(uint16_t packet_type) = 0;
  // Invoked when controller sends Authentication Complete event with Success error code
  virtual void OnAuthenticationComplete() = 0;
  // Invoked when controller sends Encryption Change event with Success error code
  virtual void OnEncryptionChange(EncryptionEnabled enabled) = 0;
  // Invoked when controller sends Change Connection Link Key Complete event with Success error code
  virtual void OnChangeConnectionLinkKeyComplete() = 0;
  // Invoked when controller sends Read Clock Offset Complete event with Success error code
  virtual void OnReadClockOffsetComplete() = 0;
  // Invoked when controller sends Mode Change event with Success error code
  virtual void OnModeChange(Mode current_mode, uint16_t interval) = 0;
  // Invoked when controller sends QoS Setup Complete event with Success error code
  virtual void OnQosSetupComplete(ServiceType service_type, uint32_t token_rate, uint32_t peak_bandwidth,
                                  uint32_t latency, uint32_t delay_variation) = 0;
  // Invoked when controller sends Flow Specification Complete event with Success error code
  virtual void OnFlowSpecificationComplete(FlowDirection flow_direction, ServiceType service_type, uint32_t token_rate,
                                           uint32_t token_bucket_size, uint32_t peak_bandwidth,
                                           uint32_t access_latency) = 0;
  // Invoked when controller sends Flush Occurred event
  virtual void OnFlushOccurred() = 0;
  // Invoked when controller sends Command Complete event for Role Discovery command with Success error code
  virtual void OnRoleDiscoveryComplete(Role current_role) = 0;
  // Invoked when controller sends Command Complete event for Read Link Policy Settings command with Success error code
  virtual void OnReadLinkPolicySettingsComplete(uint16_t link_policy_settings) = 0;
  // Invoked when controller sends Command Complete event for Read Automatic Flush Timeout command with Success error
  // code
  virtual void OnReadAutomaticFlushTimeoutComplete(uint16_t flush_timeout) = 0;
  // Invoked when controller sends Command Complete event for Read Transmit Power Level command with Success error code
  virtual void OnReadTransmitPowerLevelComplete(uint8_t transmit_power_level) = 0;
  // Invoked when controller sends Command Complete event for Read Link Supervision Time out command with Success error
  // code
  virtual void OnReadLinkSupervisionTimeoutComplete(uint16_t link_supervision_timeout) = 0;
  // Invoked when controller sends Command Complete event for Read Failed Contact Counter command with Success error
  // code
  virtual void OnReadFailedContactCounterComplete(uint16_t failed_contact_counter) = 0;
  // Invoked when controller sends Command Complete event for Read Link Quality command with Success error code
  virtual void OnReadLinkQualityComplete(uint8_t link_quality) = 0;
  // Invoked when controller sends Command Complete event for Read RSSI command with Success error code
  virtual void OnReadRssiComplete(uint8_t rssi) = 0;
  // Invoked when controller sends Command Complete event for Read Clock command with Success error code
  virtual void OnReadClockComplete(uint32_t clock, uint16_t accuracy) = 0;
};

class AclConnection {
 public:
  AclConnection() : manager_(nullptr), handle_(0), address_(Address::kEmpty){};
@@ -48,8 +95,38 @@ class AclConnection {
  using QueueUpEnd = common::BidiQueueEnd<BasePacketBuilder, PacketView<kLittleEndian>>;
  using QueueDownEnd = common::BidiQueueEnd<PacketView<kLittleEndian>, BasePacketBuilder>;
  virtual QueueUpEnd* GetAclQueueEnd() const;
  virtual void RegisterCallbacks(ConnectionManagementCallbacks* callbacks, os::Handler* handler);
  virtual void RegisterDisconnectCallback(common::OnceCallback<void(ErrorCode)> on_disconnect, os::Handler* handler);
  virtual bool Disconnect(DisconnectReason reason);
  virtual bool ChangeConnectionPacketType(uint16_t packet_type);
  virtual bool AuthenticationRequested();
  virtual bool SetConnectionEncryption(Enable enable);
  virtual bool ChangeConnectionLinkKey();
  virtual bool ReadClockOffset();
  virtual bool HoldMode(uint16_t max_interval, uint16_t min_interval);
  virtual bool SniffMode(uint16_t max_interval, uint16_t min_interval, uint16_t attempt, uint16_t timeout);
  virtual bool ExitSniffMode();
  virtual bool QosSetup(ServiceType service_type, uint32_t token_rate, uint32_t peak_bandwidth, uint32_t latency,
                        uint32_t delay_variation);
  virtual bool RoleDiscovery();
  virtual bool ReadLinkPolicySettings();
  virtual bool WriteLinkPolicySettings(uint16_t link_policy_settings);
  virtual bool FlowSpecification(FlowDirection flow_direction, ServiceType service_type, uint32_t token_rate,
                                 uint32_t token_bucket_size, uint32_t peak_bandwidth, uint32_t access_latency);
  virtual bool SniffSubrating(uint16_t maximum_latency, uint16_t minimum_remote_timeout,
                              uint16_t minimum_local_timeout);
  virtual bool Flush();
  virtual bool ReadAutomaticFlushTimeout();
  virtual bool WriteAutomaticFlushTimeout(uint16_t flush_timeout);
  virtual bool ReadTransmitPowerLevel(TransmitPowerLevelType type);
  virtual bool ReadLinkSupervisionTimeout();
  virtual bool WriteLinkSupervisionTimeout(uint16_t link_supervision_timeout);
  virtual bool ReadFailedContactCounter();
  virtual bool ResetFailedContactCounter();
  virtual bool ReadLinkQuality();
  virtual bool ReadRssi();
  virtual bool ReadClock(WhichClock which_clock);

  // Ask AclManager to clean me up. Must invoke after on_disconnect is called
  virtual void Finish();

+13 −0
Original line number Diff line number Diff line
@@ -58,6 +58,13 @@ class AclManagerCertService : public AclManagerCert::Service {
    hci_layer_->RegisterEventHandler(EventCode::CONNECTION_REQUEST,
                                     Bind(&AclManagerCertService::on_incoming_connection, common::Unretained(this)),
                                     handler_);
    hci_layer_->RegisterEventHandler(
        EventCode::CONNECTION_PACKET_TYPE_CHANGED,
        Bind(&AclManagerCertService::on_connection_packet_type_changed, common::Unretained(this)), handler_);
    hci_layer_->RegisterEventHandler(EventCode::QOS_SETUP_COMPLETE,
                                     Bind(&AclManagerCertService::on_qos_setup_complete, common::Unretained(this)),
                                     handler_);

    controller_->RegisterCompletedAclPacketsCallback(common::Bind([](uint16_t, uint16_t) { /* TODO check */ }),
                                                     handler_);
    acl_queue_end_->RegisterDequeue(handler_,
@@ -139,6 +146,12 @@ class AclManagerCertService : public AclManagerCert::Service {
    }
  }

  void on_connection_packet_type_changed(EventPacketView packet) { /*TODO*/
  }

  void on_qos_setup_complete(EventPacketView packet) { /*TODO*/
  }

  using EventStream = ::bluetooth::grpc::GrpcEventStream<AclData, AclPacketView>;

  ::grpc::Status SetPageScanMode(::grpc::ServerContext* context, const ::bluetooth::hci::cert::PageScanMode* request,
+6 −4
Original line number Diff line number Diff line
@@ -158,10 +158,7 @@ class SimpleHciTest(GdBaseTestClass):
        self._connect_from_dut()
        self.dut_command_complete_stream.subscribe()

        message = hci_facade_pb2.AuthenticationRequestedMessage(
            connection_handle=self.connection_handle
        )
        self.device_under_test.hci_classic_security.AuthenticationRequested(message)
        self.device_under_test.hci.AuthenticationRequested(self.cert_address)

        # Link request
        self.device_under_test.hci_classic_security.LinkKeyRequestNegativeReply(self.cert_address)
@@ -342,3 +339,8 @@ class SimpleHciTest(GdBaseTestClass):
        self.device_under_test.hci.TestInternalHciCommands(empty_pb2.Empty())
        self.device_under_test.hci.TestInternalHciLeCommands(empty_pb2.Empty())
        self._disconnect_from_dut()

    def test_classic_connection_management_command(self):
        self._connect_from_dut()
        self.device_under_test.hci.TestClassicConnectionManagementCommands(self.cert_address)
        self._disconnect_from_dut()
 No newline at end of file
+0 −20
Original line number Diff line number Diff line
@@ -40,8 +40,6 @@ struct ClassicSecurityManager::impl {
    handler_ = classic_security_manager_.GetHandler();
    hci_layer_->RegisterEventHandler(EventCode::IO_CAPABILITY_REQUEST,
                                     Bind(&impl::on_request_event, common::Unretained(this)), handler_);
    hci_layer_->RegisterEventHandler(EventCode::AUTHENTICATION_COMPLETE,
                                     Bind(&impl::on_authentication_complete, common::Unretained(this)), handler_);
    hci_layer_->RegisterEventHandler(EventCode::LINK_KEY_REQUEST,
                                     Bind(&impl::on_request_event, common::Unretained(this)), handler_);
    hci_layer_->RegisterEventHandler(EventCode::PIN_CODE_REQUEST,
@@ -52,7 +50,6 @@ struct ClassicSecurityManager::impl {

  void Stop() {
    hci_layer_->UnregisterEventHandler(EventCode::IO_CAPABILITY_REQUEST);
    hci_layer_->UnregisterEventHandler(EventCode::AUTHENTICATION_COMPLETE);
    handler_ = nullptr;
    hci_layer_ = nullptr;
  }
@@ -215,14 +212,6 @@ struct ClassicSecurityManager::impl {
                               common::BindOnce(&impl::on_command_complete, common::Unretained(this)), handler_);
  }

  void authentication_requested(uint16_t connection_handle) {
    std::unique_ptr<AuthenticationRequestedBuilder> packet = AuthenticationRequestedBuilder::Create(connection_handle);
    hci_layer_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandStatusView status) {
                                 LOG_DEBUG("CYDBG AuthenticationRequested command complete");
                               }),
                               handler_);
  }

  // TODO remove
  void on_request_event(EventPacketView packet) {
    EventCode event_code = packet.GetEventCode();
@@ -235,11 +224,6 @@ struct ClassicSecurityManager::impl {
    LOG_DEBUG("receive complete event %d", (uint8_t)event_code);
  }

  // TODO remove
  void on_authentication_complete(EventPacketView packet) {
    LOG_DEBUG("on_authentication_complete");
  }

  void on_command_complete(CommandCompleteView status) {
    if (client_handler_ != nullptr) {
      client_handler_->Post(common::BindOnce(&ClassicSecurityCommandCallbacks::OnCommandComplete,
@@ -362,10 +346,6 @@ void ClassicSecurityManager::ReadEncryptionKeySize(uint16_t connection_handle) {
  GetHandler()->Post(BindOnce(&impl::read_encryption_key_size, common::Unretained(pimpl_.get()), connection_handle));
}

void ClassicSecurityManager::AuthenticationRequested(uint16_t connection_handle) {
  GetHandler()->Post(BindOnce(&impl::authentication_requested, common::Unretained(pimpl_.get()), connection_handle));
}

void ClassicSecurityManager::ListDependencies(ModuleList* list) {
  list->add<HciLayer>();
}
Loading