1 // Copyright 2008 Dolphin Emulator Project 2 // Licensed under GPLv2+ 3 // Refer to the license.txt file included. 4 5 #pragma once 6 7 #include <cstdint> 8 #include <map> 9 #include <string> 10 11 #include "Common/CommonTypes.h" 12 #include "Core/HW/WiimoteCommon/WiimoteHid.h" 13 #include "Core/IOS/USB/Bluetooth/hci.h" 14 15 class PointerWrap; 16 17 namespace IOS::HLE 18 { 19 namespace Device 20 { 21 class BluetoothEmu; 22 } 23 24 class WiimoteDevice 25 { 26 public: 27 using ClassType = std::array<u8, HCI_CLASS_SIZE>; 28 using FeaturesType = std::array<u8, HCI_FEATURES_SIZE>; 29 using LinkKeyType = std::array<u8, HCI_KEY_SIZE>; 30 31 WiimoteDevice(Device::BluetoothEmu* host, int number, bdaddr_t bd); 32 ~WiimoteDevice(); 33 34 WiimoteDevice(const WiimoteDevice&) = delete; 35 WiimoteDevice& operator=(const WiimoteDevice&) = delete; 36 WiimoteDevice(WiimoteDevice&&) = delete; 37 WiimoteDevice& operator=(WiimoteDevice&&) = delete; 38 39 void Reset(); 40 41 // Called every BluetoothEmu::Update. 42 void Update(); 43 44 // Called every ~200hz. 45 void UpdateInput(); 46 47 void DoState(PointerWrap& p); 48 49 bool IsInquiryScanEnabled() const; 50 bool IsPageScanEnabled() const; 51 52 u32 GetNumber() const; 53 54 bool IsSourceValid() const; 55 bool IsConnected() const; 56 57 // User-initiated. Produces UI messages. 58 void Activate(bool ready); 59 60 // From CPU 61 void ExecuteL2capCmd(u8* ptr, u32 size); 62 // From Wiimote 63 void InterruptDataInputCallback(u8 hid_type, const u8* data, u32 size); 64 65 bool EventConnectionAccept(); 66 bool EventConnectionRequest(); 67 void EventDisconnect(u8 reason); 68 69 // nullptr may be passed to disable the remote. 70 void SetSource(WiimoteCommon::HIDWiimote*); 71 GetBD()72 const bdaddr_t& GetBD() const { return m_bd; } GetName()73 const char* GetName() const { return m_name.c_str(); } GetLMPVersion()74 u8 GetLMPVersion() const { return m_lmp_version; } GetLMPSubVersion()75 u16 GetLMPSubVersion() const { return m_lmp_subversion; } 76 // Broadcom Corporation GetManufactorID()77 u16 GetManufactorID() const { return 0x000F; } GetClass()78 const ClassType& GetClass() const { return m_class; } GetFeatures()79 const FeaturesType& GetFeatures() const { return m_features; } GetLinkKey()80 const LinkKeyType& GetLinkKey() const { return m_link_key; } 81 82 private: 83 enum class BasebandState 84 { 85 Inactive, 86 RequestConnection, 87 Complete, 88 }; 89 90 enum class HIDState 91 { 92 Inactive, 93 Linking, 94 }; 95 96 struct SChannel 97 { 98 enum class State 99 { 100 Inactive, 101 ConfigurationPending, 102 Complete, 103 }; 104 105 SChannel(); 106 107 bool IsAccepted() const; 108 bool IsRemoteConfigured() const; 109 bool IsComplete() const; 110 111 State state = State::Inactive; 112 u16 psm; 113 u16 remote_cid; 114 u16 remote_mtu = 0; 115 }; 116 117 using ChannelMap = std::map<u16, SChannel>; 118 119 Device::BluetoothEmu* m_host; 120 WiimoteCommon::HIDWiimote* m_hid_source = nullptr; 121 122 // State to save: 123 BasebandState m_baseband_state = BasebandState::Inactive; 124 HIDState m_hid_state = HIDState::Inactive; 125 bdaddr_t m_bd; 126 ClassType m_class; 127 FeaturesType m_features; 128 u8 m_lmp_version; 129 u16 m_lmp_subversion; 130 LinkKeyType m_link_key; 131 std::string m_name; 132 ChannelMap m_channels; 133 u8 m_connection_request_counter = 0; 134 135 void SetBasebandState(BasebandState); 136 137 const SChannel* FindChannelWithPSM(u16 psm) const; 138 SChannel* FindChannelWithPSM(u16 psm); 139 140 bool LinkChannel(u16 psm); 141 u16 GenerateChannelID() const; 142 DoesChannelExist(u16 scid)143 bool DoesChannelExist(u16 scid) const { return m_channels.count(scid) != 0; } 144 void SendCommandToACL(u8 ident, u8 code, u8 command_length, u8* command_data); 145 146 void SignalChannel(u8* data, u32 size); 147 148 void SendConnectionRequest(u16 psm); 149 void SendConfigurationRequest(u16 cid, u16 mtu, u16 flush_time_out); 150 151 void ReceiveConnectionReq(u8 ident, u8* data, u32 size); 152 void ReceiveConnectionResponse(u8 ident, u8* data, u32 size); 153 void ReceiveDisconnectionReq(u8 ident, u8* data, u32 size); 154 void ReceiveConfigurationReq(u8 ident, u8* data, u32 size); 155 void ReceiveConfigurationResponse(u8 ident, u8* data, u32 size); 156 157 void HandleSDP(u16 cid, u8* data, u32 size); 158 void SDPSendServiceSearchResponse(u16 cid, u16 transaction_id, u8* service_search_pattern, 159 u16 maximum_service_record_count); 160 161 void SDPSendServiceAttributeResponse(u16 cid, u16 transaction_id, u32 service_handle, 162 u16 start_attr_id, u16 end_attr_id, 163 u16 maximum_attribute_byte_count, u8* continuation_state); 164 }; 165 } // namespace IOS::HLE 166