/* * Copyright 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include "hci/address.h" #include "hci/hci_packets.h" #include "include/phy.h" #include "model/controller/acl_connection_handler.h" #include "model/controller/controller_properties.h" #include "model/controller/le_advertiser.h" #include "model/setup/async_manager.h" #include "packets/link_layer_packets.h" #ifdef ROOTCANAL_LMP extern "C" { struct LinkManager; } #include "lmp.h" #else #include "security_manager.h" #endif /* ROOTCANAL_LMP */ namespace rootcanal { using ::bluetooth::hci::Address; using ::bluetooth::hci::AddressType; using ::bluetooth::hci::AuthenticationEnable; using ::bluetooth::hci::ClassOfDevice; using ::bluetooth::hci::ErrorCode; using ::bluetooth::hci::FilterAcceptListAddressType; using ::bluetooth::hci::OpCode; using ::bluetooth::hci::PageScanRepetitionMode; // Create an address with type Public Device Address or Random Device Address. AddressWithType PeerDeviceAddress(Address address, PeerAddressType peer_address_type); // Create an address with type Public Identity Address or Random Identity // address. AddressWithType PeerIdentityAddress(Address address, PeerAddressType peer_address_type); class LinkLayerController { public: static constexpr size_t kIrkSize = 16; LinkLayerController(const Address& address, const ControllerProperties& properties); ErrorCode SendCommandToRemoteByAddress( OpCode opcode, bluetooth::packet::PacketView args, const Address& own_address, const Address& peer_address); ErrorCode SendLeCommandToRemoteByAddress(OpCode opcode, const Address& own_address, const Address& peer_address); ErrorCode SendCommandToRemoteByHandle( OpCode opcode, bluetooth::packet::PacketView args, uint16_t handle); ErrorCode SendScoToRemote(bluetooth::hci::ScoView sco_packet); ErrorCode SendAclToRemote(bluetooth::hci::AclView acl_packet); #ifdef ROOTCANAL_LMP void ForwardToLm(bluetooth::hci::CommandView command); #else void StartSimplePairing(const Address& address); void AuthenticateRemoteStage1(const Address& address, PairingType pairing_type); void AuthenticateRemoteStage2(const Address& address); void SaveKeyAndAuthenticate(uint8_t key_type, const Address& peer); ErrorCode LinkKeyRequestReply(const Address& address, const std::array& key); ErrorCode LinkKeyRequestNegativeReply(const Address& address); ErrorCode IoCapabilityRequestReply(const Address& peer, uint8_t io_capability, uint8_t oob_data_present_flag, uint8_t authentication_requirements); ErrorCode IoCapabilityRequestNegativeReply(const Address& peer, ErrorCode reason); ErrorCode PinCodeRequestReply(const Address& peer, std::vector pin); ErrorCode PinCodeRequestNegativeReply(const Address& peer); ErrorCode UserConfirmationRequestReply(const Address& peer); ErrorCode UserConfirmationRequestNegativeReply(const Address& peer); ErrorCode UserPasskeyRequestReply(const Address& peer, uint32_t numeric_value); ErrorCode UserPasskeyRequestNegativeReply(const Address& peer); ErrorCode RemoteOobDataRequestReply(const Address& peer, const std::array& c, const std::array& r); ErrorCode RemoteOobDataRequestNegativeReply(const Address& peer); ErrorCode RemoteOobExtendedDataRequestReply( const Address& peer, const std::array& c_192, const std::array& r_192, const std::array& c_256, const std::array& r_256); ErrorCode SendKeypressNotification( const Address& peer, bluetooth::hci::KeypressNotificationType notification_type); void HandleSetConnectionEncryption(const Address& address, uint16_t handle, uint8_t encryption_enable); ErrorCode SetConnectionEncryption(uint16_t handle, uint8_t encryption_enable); void HandleAuthenticationRequest(const Address& address, uint16_t handle); ErrorCode AuthenticationRequested(uint16_t handle); #endif /* ROOTCANAL_LMP */ std::vector const& ReadCurrentIacLap() const; void WriteCurrentIacLap(std::vector iac_lap); ErrorCode AcceptConnectionRequest(const Address& addr, bool try_role_switch); void MakePeripheralConnection(const Address& addr, bool try_role_switch); ErrorCode RejectConnectionRequest(const Address& addr, uint8_t reason); void RejectPeripheralConnection(const Address& addr, uint8_t reason); ErrorCode CreateConnection(const Address& addr, uint16_t packet_type, uint8_t page_scan_mode, uint16_t clock_offset, uint8_t allow_role_switch); ErrorCode CreateConnectionCancel(const Address& addr); ErrorCode Disconnect(uint16_t handle, ErrorCode reason); private: void SendDisconnectionCompleteEvent(uint16_t handle, ErrorCode reason); void IncomingPacketWithRssi(model::packets::LinkLayerPacketView incoming, uint8_t rssi); public: const Address& GetAddress() const; void IncomingPacket(model::packets::LinkLayerPacketView incoming); void TimerTick(); void Close(); AsyncTaskId ScheduleTask(std::chrono::milliseconds delay_ms, const TaskCallback& task); AsyncTaskId SchedulePeriodicTask(std::chrono::milliseconds delay_ms, std::chrono::milliseconds period_ms, const TaskCallback& callback); void CancelScheduledTask(AsyncTaskId task); // Set the callbacks for sending packets to the HCI. void RegisterEventChannel( const std::function)>& send_event); void RegisterAclChannel( const std::function)>& send_acl); void RegisterScoChannel( const std::function)>& send_sco); void RegisterIsoChannel( const std::function)>& send_iso); void RegisterRemoteChannel( const std::function, Phy::Type)>& send_to_remote); // Set the callbacks for scheduling tasks. void RegisterTaskScheduler( std::function event_scheduler); void RegisterPeriodicTaskScheduler( std::function periodic_event_scheduler); void RegisterTaskCancel(std::function cancel); void Reset(); void LeAdvertising(); void LeScanning(); void LeConnectionUpdateComplete(uint16_t handle, uint16_t interval_min, uint16_t interval_max, uint16_t latency, uint16_t supervision_timeout); ErrorCode LeConnectionUpdate(uint16_t handle, uint16_t interval_min, uint16_t interval_max, uint16_t latency, uint16_t supervision_timeout); ErrorCode LeRemoteConnectionParameterRequestReply( uint16_t connection_handle, uint16_t interval_min, uint16_t interval_max, uint16_t timeout, uint16_t latency, uint16_t minimum_ce_length, uint16_t maximum_ce_length); ErrorCode LeRemoteConnectionParameterRequestNegativeReply( uint16_t connection_handle, bluetooth::hci::ErrorCode reason); uint16_t HandleLeConnection(AddressWithType addr, AddressWithType own_addr, bluetooth::hci::Role role, uint16_t connection_interval, uint16_t connection_latency, uint16_t supervision_timeout, bool send_le_channel_selection_algorithm_event); bool ResolvingListBusy(); bool FilterAcceptListBusy(); bool LeFilterAcceptListContainsDevice( FilterAcceptListAddressType address_type, Address address); bool LeFilterAcceptListContainsDevice(AddressWithType address); enum IrkSelection { Peer, // Use Peer IRK for RPA resolution or generation. Local // Use Local IRK for RPA resolution or generation. }; // If the selected address is a Resolvable Private Address, then // resolve the address using the resolving list. If the address cannot // be resolved none is returned. If the address is not a Resolvable // Private Address, the original address is returned. std::optional ResolvePrivateAddress(AddressWithType address, IrkSelection irk); // Generate a Resolvable Private for the selected peer. // If the address is not found in the resolving list none is returned. // `local` indicates whether to use the local (true) or peer (false) IRK when // generating the Resolvable Private Address. std::optional GenerateResolvablePrivateAddress( AddressWithType address, IrkSelection irk); // Check if the selected address matches one of the controller's device // addresses (public or random static). bool IsLocalPublicOrRandomAddress(AddressWithType address) { switch (address.GetAddressType()) { case AddressType::PUBLIC_DEVICE_ADDRESS: return address.GetAddress() == address_; case AddressType::RANDOM_DEVICE_ADDRESS: return address.GetAddress() == random_address_; default: return false; } } void LeReadIsoTxSync(uint16_t handle); void LeSetCigParameters( uint8_t cig_id, uint32_t sdu_interval_m_to_s, uint32_t sdu_interval_s_to_m, bluetooth::hci::ClockAccuracy clock_accuracy, bluetooth::hci::Packing packing, bluetooth::hci::Enable framing, uint16_t max_transport_latency_m_to_s, uint16_t max_transport_latency_s_to_m, std::vector cis_config); bluetooth::hci::ErrorCode LeCreateCis( std::vector cis_config); bluetooth::hci::ErrorCode LeRemoveCig(uint8_t cig_id); bluetooth::hci::ErrorCode LeAcceptCisRequest(uint16_t handle); bluetooth::hci::ErrorCode LeRejectCisRequest( uint16_t handle, bluetooth::hci::ErrorCode reason); bluetooth::hci::ErrorCode LeCreateBig( uint8_t big_handle, uint8_t advertising_handle, uint8_t num_bis, uint32_t sdu_interval, uint16_t max_sdu, uint16_t max_transport_latency, uint8_t rtn, bluetooth::hci::SecondaryPhyType phy, bluetooth::hci::Packing packing, bluetooth::hci::Enable framing, bluetooth::hci::Enable encryption, std::array broadcast_code); bluetooth::hci::ErrorCode LeTerminateBig(uint8_t big_handle, bluetooth::hci::ErrorCode reason); bluetooth::hci::ErrorCode LeBigCreateSync( uint8_t big_handle, uint16_t sync_handle, bluetooth::hci::Enable encryption, std::array broadcast_code, uint8_t mse, uint16_t big_syunc_timeout, std::vector bis); void LeBigTerminateSync(uint8_t big_handle); bluetooth::hci::ErrorCode LeRequestPeerSca(uint16_t request_handle); void LeSetupIsoDataPath(uint16_t connection_handle, bluetooth::hci::DataPathDirection data_path_direction, uint8_t data_path_id, uint64_t codec_id, uint32_t controller_Delay, std::vector codec_configuration); void LeRemoveIsoDataPath( uint16_t connection_handle, bluetooth::hci::RemoveDataPathDirection remove_data_path_direction); void HandleLeEnableEncryption(uint16_t handle, std::array rand, uint16_t ediv, std::array ltk); ErrorCode LeEnableEncryption(uint16_t handle, std::array rand, uint16_t ediv, std::array ltk); ErrorCode LeLongTermKeyRequestReply(uint16_t handle, std::array ltk); ErrorCode LeLongTermKeyRequestNegativeReply(uint16_t handle); uint8_t LeReadNumberOfSupportedAdvertisingSets(); // Classic void StartInquiry(std::chrono::milliseconds timeout); void InquiryCancel(); void InquiryTimeout(); void SetInquiryMode(uint8_t mode); void SetInquiryLAP(uint64_t lap); void SetInquiryMaxResponses(uint8_t max); void Inquiry(); bool GetInquiryScanEnable() { return inquiry_scan_enable_; } void SetInquiryScanEnable(bool enable); bool GetPageScanEnable() { return page_scan_enable_; } void SetPageScanEnable(bool enable); uint16_t GetPageTimeout(); void SetPageTimeout(uint16_t page_timeout); ErrorCode ChangeConnectionPacketType(uint16_t handle, uint16_t types); ErrorCode ChangeConnectionLinkKey(uint16_t handle); ErrorCode CentralLinkKey(uint8_t key_flag); ErrorCode HoldMode(uint16_t handle, uint16_t hold_mode_max_interval, uint16_t hold_mode_min_interval); ErrorCode SniffMode(uint16_t handle, uint16_t sniff_max_interval, uint16_t sniff_min_interval, uint16_t sniff_attempt, uint16_t sniff_timeout); ErrorCode ExitSniffMode(uint16_t handle); ErrorCode QosSetup(uint16_t handle, uint8_t service_type, uint32_t token_rate, uint32_t peak_bandwidth, uint32_t latency, uint32_t delay_variation); ErrorCode RoleDiscovery(uint16_t handle, bluetooth::hci::Role* role); ErrorCode SwitchRole(Address bd_addr, bluetooth::hci::Role role); ErrorCode ReadLinkPolicySettings(uint16_t handle, uint16_t* settings); ErrorCode WriteLinkPolicySettings(uint16_t handle, uint16_t settings); ErrorCode FlowSpecification(uint16_t handle, uint8_t flow_direction, uint8_t service_type, uint32_t token_rate, uint32_t token_bucket_size, uint32_t peak_bandwidth, uint32_t access_latency); ErrorCode WriteLinkSupervisionTimeout(uint16_t handle, uint16_t timeout); ErrorCode WriteDefaultLinkPolicySettings(uint16_t settings); void CheckExpiringConnection(uint16_t handle); uint16_t ReadDefaultLinkPolicySettings(); void ReadLocalOobData(); void ReadLocalOobExtendedData(); ErrorCode AddScoConnection(uint16_t connection_handle, uint16_t packet_type, ScoDatapath datapath); ErrorCode SetupSynchronousConnection( uint16_t connection_handle, uint32_t transmit_bandwidth, uint32_t receive_bandwidth, uint16_t max_latency, uint16_t voice_setting, uint8_t retransmission_effort, uint16_t packet_types, ScoDatapath datapath); ErrorCode AcceptSynchronousConnection( Address bd_addr, uint32_t transmit_bandwidth, uint32_t receive_bandwidth, uint16_t max_latency, uint16_t voice_setting, uint8_t retransmission_effort, uint16_t packet_types); ErrorCode RejectSynchronousConnection(Address bd_addr, uint16_t reason); bool HasAclConnection(); void HandleIso(bluetooth::hci::IsoView iso); // LE Commands // HCI LE Set Random Address command (Vol 4, Part E § 7.8.4). ErrorCode LeSetRandomAddress(Address random_address); // HCI LE Set Resolvable Private Address Timeout command // (Vol 4, Part E § 7.8.45). ErrorCode LeSetResolvablePrivateAddressTimeout(uint16_t rpa_timeout); // HCI LE Set Host Feature command (Vol 4, Part E § 7.8.115). ErrorCode LeSetHostFeature(uint8_t bit_number, uint8_t bit_value); // LE Filter Accept List // HCI command LE_Clear_Filter_Accept_List (Vol 4, Part E § 7.8.15). ErrorCode LeClearFilterAcceptList(); // HCI command LE_Add_Device_To_Filter_Accept_List (Vol 4, Part E § 7.8.16). ErrorCode LeAddDeviceToFilterAcceptList( FilterAcceptListAddressType address_type, Address address); // HCI command LE_Remove_Device_From_Filter_Accept_List (Vol 4, Part E // § 7.8.17). ErrorCode LeRemoveDeviceFromFilterAcceptList( FilterAcceptListAddressType address_type, Address address); // LE Address Resolving // HCI command LE_Add_Device_To_Resolving_List (Vol 4, Part E § 7.8.38). ErrorCode LeAddDeviceToResolvingList( PeerAddressType peer_identity_address_type, Address peer_identity_address, std::array peer_irk, std::array local_irk); // HCI command LE_Remove_Device_From_Resolving_List (Vol 4, Part E § 7.8.39). ErrorCode LeRemoveDeviceFromResolvingList( PeerAddressType peer_identity_address_type, Address peer_identity_address); // HCI command LE_Clear_Resolving_List (Vol 4, Part E § 7.8.40). ErrorCode LeClearResolvingList(); // HCI command LE_Set_Address_Resolution_Enable (Vol 4, Part E § 7.8.44). ErrorCode LeSetAddressResolutionEnable(bool enable); // HCI command LE_Set_Privacy_Mode (Vol 4, Part E § 7.8.77). ErrorCode LeSetPrivacyMode(PeerAddressType peer_identity_address_type, Address peer_identity_address, bluetooth::hci::PrivacyMode privacy_mode); // Legacy Advertising // HCI command LE_Set_Advertising_Parameters (Vol 4, Part E § 7.8.5). ErrorCode LeSetAdvertisingParameters( uint16_t advertising_interval_min, uint16_t advertising_interval_max, bluetooth::hci::AdvertisingType advertising_type, bluetooth::hci::OwnAddressType own_address_type, bluetooth::hci::PeerAddressType peer_address_type, Address peer_address, uint8_t advertising_channel_map, bluetooth::hci::AdvertisingFilterPolicy advertising_filter_policy); // HCI command LE_Set_Advertising_Data (Vol 4, Part E § 7.8.7). ErrorCode LeSetAdvertisingData(const std::vector& advertising_data); // HCI command LE_Set_Scan_Response_Data (Vol 4, Part E § 7.8.8). ErrorCode LeSetScanResponseData( const std::vector& scan_response_data); // HCI command LE_Advertising_Enable (Vol 4, Part E § 7.8.9). ErrorCode LeSetAdvertisingEnable(bool advertising_enable); // Extended Advertising // HCI command LE_Set_Advertising_Set_Random_Address (Vol 4, Part E § 7.8.52). ErrorCode LeSetAdvertisingSetRandomAddress(uint8_t advertising_handle, Address random_address); // HCI command LE_Set_Advertising_Parameters (Vol 4, Part E § 7.8.53). ErrorCode LeSetExtendedAdvertisingParameters( uint8_t advertising_handle, AdvertisingEventProperties advertising_event_properties, uint16_t primary_advertising_interval_min, uint16_t primary_advertising_interval_max, uint8_t primary_advertising_channel_map, bluetooth::hci::OwnAddressType own_address_type, bluetooth::hci::PeerAddressType peer_address_type, Address peer_address, bluetooth::hci::AdvertisingFilterPolicy advertising_filter_policy, uint8_t advertising_tx_power, bluetooth::hci::PrimaryPhyType primary_advertising_phy, uint8_t secondary_max_skip, bluetooth::hci::SecondaryPhyType secondary_advertising_phy, uint8_t advertising_sid, bool scan_request_notification_enable); // HCI command LE_Set_Extended_Advertising_Data (Vol 4, Part E § 7.8.54). ErrorCode LeSetExtendedAdvertisingData( uint8_t advertising_handle, bluetooth::hci::Operation operation, bluetooth::hci::FragmentPreference fragment_preference, const std::vector& advertising_data); // HCI command LE_Set_Extended_Scan_Response_Data (Vol 4, Part E § 7.8.55). ErrorCode LeSetExtendedScanResponseData( uint8_t advertising_handle, bluetooth::hci::Operation operation, bluetooth::hci::FragmentPreference fragment_preference, const std::vector& scan_response_data); // HCI command LE_Set_Extended_Advertising_Enable (Vol 4, Part E § 7.8.56). ErrorCode LeSetExtendedAdvertisingEnable( bool enable, const std::vector& sets); // HCI command LE_Remove_Advertising_Set (Vol 4, Part E § 7.8.59). ErrorCode LeRemoveAdvertisingSet(uint8_t advertising_handle); // HCI command LE_Clear_Advertising_Sets (Vol 4, Part E § 7.8.60). ErrorCode LeClearAdvertisingSets(); // Legacy Scanning // HCI command LE_Set_Scan_Parameters (Vol 4, Part E § 7.8.10). ErrorCode LeSetScanParameters( bluetooth::hci::LeScanType scan_type, uint16_t scan_interval, uint16_t scan_window, bluetooth::hci::OwnAddressType own_address_type, bluetooth::hci::LeScanningFilterPolicy scanning_filter_policy); // HCI command LE_Set_Scan_Enable (Vol 4, Part E § 7.8.11). ErrorCode LeSetScanEnable(bool enable, bool filter_duplicates); // Extended Scanning // HCI command LE_Set_Extended_Scan_Parameters (Vol 4, Part E § 7.8.64). ErrorCode LeSetExtendedScanParameters( bluetooth::hci::OwnAddressType own_address_type, bluetooth::hci::LeScanningFilterPolicy scanning_filter_policy, uint8_t scanning_phys, std::vector scanning_phy_parameters); // HCI command LE_Set_Extended_Scan_Enable (Vol 4, Part E § 7.8.65). ErrorCode LeSetExtendedScanEnable( bool enable, bluetooth::hci::FilterDuplicates filter_duplicates, uint16_t duration, uint16_t period); // Legacy Connection // HCI LE Create Connection command (Vol 4, Part E § 7.8.12). ErrorCode LeCreateConnection( uint16_t scan_interval, uint16_t scan_window, bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy, AddressWithType peer_address, bluetooth::hci::OwnAddressType own_address_type, uint16_t connection_interval_min, uint16_t connection_interval_max, uint16_t max_latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length); // HCI LE Create Connection Cancel command (Vol 4, Part E § 7.8.12). ErrorCode LeCreateConnectionCancel(); // Extended Connection // HCI LE Extended Create Connection command (Vol 4, Part E § 7.8.66). ErrorCode LeExtendedCreateConnection( bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy, bluetooth::hci::OwnAddressType own_address_type, AddressWithType peer_address, uint8_t initiating_phys, std::vector initiating_phy_parameters); protected: void SendLinkLayerPacket( std::unique_ptr packet); void SendLeLinkLayerPacket( std::unique_ptr packet); void SendLeLinkLayerPacketWithRssi( Address source_address, Address destination_address, uint8_t rssi, std::unique_ptr packet); void IncomingAclPacket(model::packets::LinkLayerPacketView packet); void IncomingScoPacket(model::packets::LinkLayerPacketView packet); void IncomingDisconnectPacket(model::packets::LinkLayerPacketView packet); void IncomingEncryptConnection(model::packets::LinkLayerPacketView packet); void IncomingEncryptConnectionResponse( model::packets::LinkLayerPacketView packet); void IncomingInquiryPacket(model::packets::LinkLayerPacketView packet, uint8_t rssi); void IncomingInquiryResponsePacket( model::packets::LinkLayerPacketView packet); #ifdef ROOTCANAL_LMP void IncomingLmpPacket(model::packets::LinkLayerPacketView packet); #else void IncomingIoCapabilityRequestPacket( model::packets::LinkLayerPacketView packet); void IncomingIoCapabilityResponsePacket( model::packets::LinkLayerPacketView packet); void IncomingIoCapabilityNegativeResponsePacket( model::packets::LinkLayerPacketView packet); void IncomingKeypressNotificationPacket( model::packets::LinkLayerPacketView packet); void IncomingPasskeyPacket(model::packets::LinkLayerPacketView packet); void IncomingPasskeyFailedPacket(model::packets::LinkLayerPacketView packet); void IncomingPinRequestPacket(model::packets::LinkLayerPacketView packet); void IncomingPinResponsePacket(model::packets::LinkLayerPacketView packet); #endif /* ROOTCANAL_LMP */ void IncomingIsoPacket(model::packets::LinkLayerPacketView packet); void IncomingIsoConnectionRequestPacket( model::packets::LinkLayerPacketView packet); void IncomingIsoConnectionResponsePacket( model::packets::LinkLayerPacketView packet); void ScanIncomingLeLegacyAdvertisingPdu( model::packets::LeLegacyAdvertisingPduView& pdu, uint8_t rssi); void ScanIncomingLeExtendedAdvertisingPdu( model::packets::LeExtendedAdvertisingPduView& pdu, uint8_t rssi); void ConnectIncomingLeLegacyAdvertisingPdu( model::packets::LeLegacyAdvertisingPduView& pdu); void ConnectIncomingLeExtendedAdvertisingPdu( model::packets::LeExtendedAdvertisingPduView& pdu); void IncomingLeLegacyAdvertisingPdu( model::packets::LinkLayerPacketView packet, uint8_t rssi); void IncomingLeExtendedAdvertisingPdu( model::packets::LinkLayerPacketView packet, uint8_t rssi); void IncomingLeConnectPacket(model::packets::LinkLayerPacketView packet); void IncomingLeConnectCompletePacket( model::packets::LinkLayerPacketView packet); void IncomingLeConnectionParameterRequest( model::packets::LinkLayerPacketView packet); void IncomingLeConnectionParameterUpdate( model::packets::LinkLayerPacketView packet); void IncomingLeEncryptConnection(model::packets::LinkLayerPacketView packet); void IncomingLeEncryptConnectionResponse( model::packets::LinkLayerPacketView packet); void IncomingLeReadRemoteFeatures(model::packets::LinkLayerPacketView packet); void IncomingLeReadRemoteFeaturesResponse( model::packets::LinkLayerPacketView packet); void ProcessIncomingLegacyScanRequest( AddressWithType scanning_address, AddressWithType resolved_scanning_address, AddressWithType advertising_address); void ProcessIncomingExtendedScanRequest( ExtendedAdvertiser const& advertiser, AddressWithType scanning_address, AddressWithType resolved_scanning_address, AddressWithType advertising_address); bool ProcessIncomingLegacyConnectRequest( model::packets::LeConnectView const& connect_ind); bool ProcessIncomingExtendedConnectRequest( ExtendedAdvertiser& advertiser, model::packets::LeConnectView const& connect_ind); void IncomingLeScanPacket(model::packets::LinkLayerPacketView packet); void IncomingLeScanResponsePacket(model::packets::LinkLayerPacketView packet, uint8_t rssi); void IncomingPagePacket(model::packets::LinkLayerPacketView packet); void IncomingPageRejectPacket(model::packets::LinkLayerPacketView packet); void IncomingPageResponsePacket(model::packets::LinkLayerPacketView packet); void IncomingReadRemoteLmpFeatures( model::packets::LinkLayerPacketView packet); void IncomingReadRemoteLmpFeaturesResponse( model::packets::LinkLayerPacketView packet); void IncomingReadRemoteSupportedFeatures( model::packets::LinkLayerPacketView packet); void IncomingReadRemoteSupportedFeaturesResponse( model::packets::LinkLayerPacketView packet); void IncomingReadRemoteExtendedFeatures( model::packets::LinkLayerPacketView packet); void IncomingReadRemoteExtendedFeaturesResponse( model::packets::LinkLayerPacketView packet); void IncomingReadRemoteVersion(model::packets::LinkLayerPacketView packet); void IncomingReadRemoteVersionResponse( model::packets::LinkLayerPacketView packet); void IncomingReadClockOffset(model::packets::LinkLayerPacketView packet); void IncomingReadClockOffsetResponse( model::packets::LinkLayerPacketView packet); void IncomingRemoteNameRequest(model::packets::LinkLayerPacketView packet); void IncomingRemoteNameRequestResponse( model::packets::LinkLayerPacketView packet); void IncomingScoConnectionRequest(model::packets::LinkLayerPacketView packet); void IncomingScoConnectionResponse( model::packets::LinkLayerPacketView packet); void IncomingScoDisconnect(model::packets::LinkLayerPacketView packet); void IncomingPingRequest(model::packets::LinkLayerPacketView packet); public: bool IsEventUnmasked(bluetooth::hci::EventCode event) const; bool IsLeEventUnmasked(bluetooth::hci::SubeventCode subevent) const; // TODO // The Clock Offset should be specific to an ACL connection. // Returning a proper value is not that important. uint32_t GetClockOffset() const { return 0; } // TODO // The Page Scan Repetition Mode should be specific to an ACL connection or // a paging session. PageScanRepetitionMode GetPageScanRepetitionMode() const { return page_scan_repetition_mode_; } // TODO // The Encryption Key Size should be specific to an ACL connection. uint8_t GetEncryptionKeySize() const { return min_encryption_key_size_; } bool GetScoFlowControlEnable() const { return sco_flow_control_enable_; } AuthenticationEnable GetAuthenticationEnable() { return authentication_enable_; } std::array const& GetLocalName() { return local_name_; } uint64_t GetLeSupportedFeatures() const { return properties_.le_features | le_host_supported_features_; } uint16_t GetConnectionAcceptTimeout() const { return connection_accept_timeout_; } uint16_t GetVoiceSetting() const { return voice_setting_; } const ClassOfDevice& GetClassOfDevice() const { return class_of_device_; } uint8_t GetMaxLmpFeaturesPageNumber() { return properties_.lmp_features.size() - 1; } uint64_t GetLmpFeatures(uint8_t page_number = 0) { return page_number == 1 ? host_supported_features_ : properties_.lmp_features[page_number]; } void SetLocalName(std::vector const& local_name); void SetLocalName(std::array const& local_name); void SetExtendedInquiryResponse( std::vector const& extended_inquiry_response); void SetClassOfDevice(ClassOfDevice class_of_device) { class_of_device_ = class_of_device; } void SetClassOfDevice(uint32_t class_of_device) { class_of_device_.cod[0] = class_of_device & 0xff; class_of_device_.cod[1] = (class_of_device >> 8) & 0xff; class_of_device_.cod[2] = (class_of_device >> 16) & 0xff; } void SetAuthenticationEnable(AuthenticationEnable enable) { authentication_enable_ = enable; } void SetScoFlowControlEnable(bool enable) { sco_flow_control_enable_ = enable; } void SetVoiceSetting(uint16_t voice_setting) { voice_setting_ = voice_setting; } void SetEventMask(uint64_t event_mask) { event_mask_ = event_mask; } void SetEventMaskPage2(uint64_t event_mask) { event_mask_page_2_ = event_mask; } void SetLeEventMask(uint64_t le_event_mask) { le_event_mask_ = le_event_mask; } void SetLeHostSupport(bool enable); void SetSecureSimplePairingSupport(bool enable); void SetSecureConnectionsSupport(bool enable); void SetConnectionAcceptTimeout(uint16_t timeout) { connection_accept_timeout_ = timeout; } bool LegacyAdvertising() const { return legacy_advertising_in_use_; } bool ExtendedAdvertising() const { return extended_advertising_in_use_; } bool SelectLegacyAdvertising() { if (extended_advertising_in_use_) { return false; } else { legacy_advertising_in_use_ = true; return true; } } bool SelectExtendedAdvertising() { if (legacy_advertising_in_use_) { return false; } else { extended_advertising_in_use_ = true; return true; } } uint16_t GetLeSuggestedMaxTxOctets() const { return le_suggested_max_tx_octets_; } uint16_t GetLeSuggestedMaxTxTime() const { return le_suggested_max_tx_time_; } void SetLeSuggestedMaxTxOctets(uint16_t max_tx_octets) { le_suggested_max_tx_octets_ = max_tx_octets; } void SetLeSuggestedMaxTxTime(uint16_t max_tx_time) { le_suggested_max_tx_time_ = max_tx_time; } AsyncTaskId StartScoStream(Address address); private: const Address& address_; const ControllerProperties& properties_; // Host Supported Features (Vol 2, Part C § 3.3 Feature Mask Definition). // Page 1 of the LMP feature mask. uint64_t host_supported_features_{0}; bool le_host_support_{false}; bool secure_simple_pairing_host_support_{false}; bool secure_connections_host_support_{false}; // Le Host Supported Features (Vol 4, Part E § 7.8.3). // Specifies the bits indicating Host support. uint64_t le_host_supported_features_{0}; bool connected_isochronous_stream_host_support_{false}; bool connection_subrating_host_support_{false}; // LE Random Address (Vol 4, Part E § 7.8.4). Address random_address_{Address::kEmpty}; // HCI configuration parameters. // // Provide the current HCI Configuration Parameters as defined in section // Vol 4, Part E § 6 of the core specification. // Scan Enable (Vol 4, Part E § 6.1). bool page_scan_enable_{false}; bool inquiry_scan_enable_{false}; // Inquiry Scan Interval and Window // (Vol 4, Part E § 6.2, 6.3). uint16_t inquiry_scan_interval_{0x1000}; uint16_t inquiry_scan_window_{0x0012}; // Page Timeout (Vol 4, Part E § 6.6). uint16_t page_timeout_{0x2000}; // Connection Accept Timeout (Vol 4, Part E § 6.7). uint16_t connection_accept_timeout_{0x1FA0}; // Page Scan Interval and Window // (Vol 4, Part E § 6.8, 6.9). uint16_t page_scan_interval_{0x0800}; uint16_t page_scan_window_{0x0012}; // Voice Setting (Vol 4, Part E § 6.12). uint16_t voice_setting_{0x0060}; // Authentication Enable (Vol 4, Part E § 6.16). AuthenticationEnable authentication_enable_{ AuthenticationEnable::NOT_REQUIRED}; // Default Link Policy Settings (Vol 4, Part E § 6.18). uint8_t default_link_policy_settings_{0x0000}; // Synchronous Flow Control Enable (Vol 4, Part E § 6.22). bool sco_flow_control_enable_{false}; // Local Name (Vol 4, Part E § 6.23). std::array local_name_{}; // Extended Inquiry Response (Vol 4, Part E § 6.24). std::array extended_inquiry_response_{}; // Class of Device (Vol 4, Part E § 6.26). ClassOfDevice class_of_device_{{0, 0, 0}}; // Other configuration parameters. // Current IAC LAP (Vol 4, Part E § 7.3.44). std::vector current_iac_lap_list_{}; // Min Encryption Key Size (Vol 4, Part E § 7.3.102). uint8_t min_encryption_key_size_{16}; // Event Mask (Vol 4, Part E § 7.3.1) and // Event Mask Page 2 (Vol 4, Part E § 7.3.69) and // LE Event Mask (Vol 4, Part E § 7.8.1). uint64_t event_mask_{0x00001fffffffffff}; uint64_t event_mask_page_2_{0x0}; uint64_t le_event_mask_{0x01f}; // Suggested Default Data Length (Vol 4, Part E § 7.8.34). uint16_t le_suggested_max_tx_octets_{0x001b}; uint16_t le_suggested_max_tx_time_{0x0148}; // Resolvable Private Address Timeout (Vol 4, Part E § 7.8.45). std::chrono::seconds resolvable_private_address_timeout_{0x0384}; // Page Scan Repetition Mode (Vol 2 Part B § 8.3.1 Page Scan substate). // The Page Scan Repetition Mode depends on the selected Page Scan Interval. PageScanRepetitionMode page_scan_repetition_mode_{PageScanRepetitionMode::R0}; AclConnectionHandler connections_; // Callbacks to schedule tasks. std::function schedule_task_; std::function schedule_periodic_task_; std::function cancel_task_; // Callbacks to send packets back to the HCI. std::function)> send_acl_; std::function)> send_event_; std::function)> send_sco_; std::function)> send_iso_; // Callback to send packets to remote devices. std::function, Phy::Type phy_type)> send_to_remote_; uint32_t oob_id_{1}; uint32_t key_id_{1}; struct FilterAcceptListEntry { FilterAcceptListAddressType address_type; Address address; }; std::vector le_filter_accept_list_; struct ResolvingListEntry { PeerAddressType peer_identity_address_type; Address peer_identity_address; std::array peer_irk; std::array local_irk; bluetooth::hci::PrivacyMode privacy_mode; }; std::vector le_resolving_list_; bool le_resolving_list_enabled_{false}; // Flag set when any legacy advertising command has been received // since the last power-on-reset. // From Vol 4, Part E § 3.1.1 Legacy and extended advertising, // extended advertising are rejected when this bit is set. bool legacy_advertising_in_use_{false}; // Flag set when any extended advertising command has been received // since the last power-on-reset. // From Vol 4, Part E § 3.1.1 Legacy and extended advertising, // legacy advertising are rejected when this bit is set. bool extended_advertising_in_use_{false}; // Legacy advertising state. LegacyAdvertiser legacy_advertiser_{}; // Extended advertising sets. std::unordered_map extended_advertisers_{}; struct Scanner { bool scan_enable; std::chrono::steady_clock::duration period; std::chrono::steady_clock::duration duration; bluetooth::hci::FilterDuplicates filter_duplicates; bluetooth::hci::OwnAddressType own_address_type; bluetooth::hci::LeScanningFilterPolicy scan_filter_policy; struct PhyParameters { bool enabled; bluetooth::hci::LeScanType scan_type; uint16_t scan_interval; uint16_t scan_window; }; PhyParameters le_1m_phy; PhyParameters le_coded_phy; // Save information about the advertising PDU being scanned. bool connectable_scan_response; std::optional pending_scan_request{}; // Time keeping std::optional timeout; std::optional periodical_timeout; // Packet History std::vector history; bool IsEnabled() const { return scan_enable; } bool IsPacketInHistory(model::packets::LinkLayerPacketView packet) const { return std::any_of( history.begin(), history.end(), [packet](model::packets::LinkLayerPacketView const& a) { return a.size() == packet.size() && std::equal(a.begin(), a.end(), packet.begin()); }); } void AddPacketToHistory(model::packets::LinkLayerPacketView packet) { history.push_back(packet); } }; // Legacy and extended scanning properties. // Legacy and extended scanning are disambiguated by the use // of legacy_advertising_in_use_ and extended_advertising_in_use_ flags. // Only one type of advertising may be used during a controller session. Scanner scanner_{}; struct Initiator { bool connect_enable; bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy; bluetooth::hci::AddressWithType peer_address{}; bluetooth::hci::OwnAddressType own_address_type; struct PhyParameters { bool enabled; uint16_t scan_interval; uint16_t scan_window; uint16_t connection_interval_min; uint16_t connection_interval_max; uint16_t max_latency; uint16_t supervision_timeout; uint16_t min_ce_length; uint16_t max_ce_length; }; PhyParameters le_1m_phy; PhyParameters le_2m_phy; PhyParameters le_coded_phy; // Save information about the ongoing connection. Address initiating_address{}; // TODO: AddressWithType std::optional pending_connect_request{}; bool IsEnabled() const { return connect_enable; } void Disable() { connect_enable = false; } }; // Legacy and extended initiating properties. // Legacy and extended initiating are disambiguated by the use // of legacy_advertising_in_use_ and extended_advertising_in_use_ flags. // Only one type of advertising may be used during a controller session. Initiator initiator_{}; // Classic state #ifdef ROOTCANAL_LMP std::unique_ptr lm_; struct LinkManagerOps ops_; #else SecurityManager security_manager_{10}; #endif /* ROOTCANAL_LMP */ AsyncTaskId page_timeout_task_id_ = kInvalidTaskId; std::chrono::steady_clock::time_point last_inquiry_; model::packets::InquiryType inquiry_mode_{ model::packets::InquiryType::STANDARD}; AsyncTaskId inquiry_timer_task_id_ = kInvalidTaskId; uint64_t inquiry_lap_{}; uint8_t inquiry_max_responses_{}; }; } // namespace rootcanal