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 <cstddef> 8 #include <deque> 9 #include <memory> 10 #include <string> 11 #include <vector> 12 13 #include "Common/CommonTypes.h" 14 #include "Core/HW/Wiimote.h" 15 #include "Core/IOS/Device.h" 16 #include "Core/IOS/IOS.h" 17 #include "Core/IOS/USB/Bluetooth/BTBase.h" 18 #include "Core/IOS/USB/Bluetooth/WiimoteDevice.h" 19 #include "Core/IOS/USB/Bluetooth/hci.h" 20 #include "Core/IOS/USB/USBV0.h" 21 22 class PointerWrap; 23 24 namespace IOS::HLE 25 { 26 struct SQueuedEvent 27 { 28 u8 buffer[1024] = {}; 29 u32 size = 0; 30 u16 connection_handle = 0; 31 32 SQueuedEvent(u32 size_, u16 handle); 33 SQueuedEvent() = default; 34 }; 35 36 namespace Device 37 { 38 // Important to remember that this class is for /dev/usb/oh1/57e/305 ONLY 39 // /dev/usb/oh1 -> internal usb bus 40 // 57e/305 -> VendorID/ProductID of device on usb bus 41 // This device is ONLY the internal Bluetooth module (based on BCM2045 chip) 42 class BluetoothEmu final : public BluetoothBase 43 { 44 public: 45 BluetoothEmu(Kernel& ios, const std::string& device_name); 46 47 virtual ~BluetoothEmu(); 48 49 IPCCommandResult Close(u32 fd) override; 50 IPCCommandResult IOCtlV(const IOCtlVRequest& request) override; 51 52 void Update() override; 53 54 // Send ACL data back to Bluetooth stack 55 void SendACLPacket(const bdaddr_t& source, const u8* data, u32 size); 56 57 // Returns true if controller is configured to see the connection request. 58 bool RemoteConnect(WiimoteDevice&); 59 bool RemoteDisconnect(const bdaddr_t& address); 60 61 WiimoteDevice* AccessWiimoteByIndex(std::size_t index); 62 63 void DoState(PointerWrap& p) override; 64 65 private: 66 std::vector<std::unique_ptr<WiimoteDevice>> m_wiimotes; 67 68 bdaddr_t m_controller_bd{{0x11, 0x02, 0x19, 0x79, 0x00, 0xff}}; 69 70 // this is used to trigger connecting via ACL 71 u8 m_scan_enable = 0; 72 73 std::unique_ptr<USB::V0IntrMessage> m_hci_endpoint; 74 std::unique_ptr<USB::V0BulkMessage> m_acl_endpoint; 75 std::deque<SQueuedEvent> m_event_queue; 76 77 class ACLPool 78 { 79 public: ACLPool(Kernel & ios)80 explicit ACLPool(Kernel& ios) : m_ios(ios), m_queue() {} 81 void Store(const u8* data, const u16 size, const u16 conn_handle); 82 83 void WriteToEndpoint(const USB::V0BulkMessage& endpoint); 84 IsEmpty()85 bool IsEmpty() const { return m_queue.empty(); } 86 // For SaveStates DoState(PointerWrap & p)87 void DoState(PointerWrap& p) { p.Do(m_queue); } 88 89 private: 90 struct Packet 91 { 92 u8 data[ACL_PKT_SIZE]; 93 u16 size; 94 u16 conn_handle; 95 }; 96 97 Kernel& m_ios; 98 std::deque<Packet> m_queue; 99 } m_acl_pool{m_ios}; 100 101 u32 m_packet_count[MAX_BBMOTES] = {}; 102 u64 m_last_ticks = 0; 103 104 static u16 GetConnectionHandle(const bdaddr_t&); 105 106 WiimoteDevice* AccessWiimote(const bdaddr_t& address); 107 WiimoteDevice* AccessWiimote(u16 connection_handle); 108 109 static u32 GetWiimoteNumberFromConnectionHandle(u16 connection_handle); 110 111 // Send ACL data to a device (wiimote) 112 void IncDataPacket(u16 connection_handle); 113 void SendToDevice(u16 connection_handle, u8* data, u32 size); 114 115 // Events 116 void AddEventToQueue(const SQueuedEvent& event); 117 bool SendEventCommandStatus(u16 opcode); 118 void SendEventCommandComplete(u16 opcode, const void* data, u32 data_size); 119 bool SendEventInquiryResponse(); 120 bool SendEventInquiryComplete(u8 num_responses); 121 bool SendEventRemoteNameReq(const bdaddr_t& bd); 122 bool SendEventRequestConnection(const WiimoteDevice& wiimote); 123 bool SendEventConnectionComplete(const bdaddr_t& bd, u8 status); 124 bool SendEventReadClockOffsetComplete(u16 connection_handle); 125 bool SendEventConPacketTypeChange(u16 connection_handle, u16 packet_type); 126 bool SendEventReadRemoteVerInfo(u16 connection_handle); 127 bool SendEventReadRemoteFeatures(u16 connection_handle); 128 bool SendEventRoleChange(bdaddr_t bd, bool master); 129 bool SendEventNumberOfCompletedPackets(); 130 bool SendEventAuthenticationCompleted(u16 connection_handle); 131 bool SendEventModeChange(u16 connection_handle, u8 mode, u16 value); 132 bool SendEventDisconnect(u16 connection_handle, u8 reason); 133 bool SendEventRequestLinkKey(const bdaddr_t& bd); 134 bool SendEventLinkKeyNotification(const u8 num_to_send); 135 136 // Execute HCI Message 137 void ExecuteHCICommandMessage(const USB::V0CtrlMessage& ctrl_message); 138 139 // OGF 0x01 - Link control commands and return parameters 140 void CommandWriteInquiryMode(const u8* input); 141 void CommandWritePageScanType(const u8* input); 142 void CommandHostBufferSize(const u8* input); 143 void CommandInquiryCancel(const u8* input); 144 void CommandRemoteNameReq(const u8* input); 145 void CommandCreateCon(const u8* input); 146 void CommandAcceptCon(const u8* input); 147 void CommandReadClockOffset(const u8* input); 148 void CommandReadRemoteVerInfo(const u8* input); 149 void CommandReadRemoteFeatures(const u8* input); 150 void CommandAuthenticationRequested(const u8* input); 151 void CommandInquiry(const u8* input); 152 void CommandDisconnect(const u8* input); 153 void CommandLinkKeyNegRep(const u8* input); 154 void CommandLinkKeyRep(const u8* input); 155 void CommandDeleteStoredLinkKey(const u8* input); 156 void CommandChangeConPacketType(const u8* input); 157 158 // OGF 0x02 - Link policy commands and return parameters 159 void CommandWriteLinkPolicy(const u8* input); 160 void CommandSniffMode(const u8* input); 161 162 // OGF 0x03 - Host Controller and Baseband commands and return parameters 163 void CommandReset(const u8* input); 164 void CommandWriteLocalName(const u8* input); 165 void CommandWritePageTimeOut(const u8* input); 166 void CommandWriteScanEnable(const u8* input); 167 void CommandWriteUnitClass(const u8* input); 168 void CommandReadStoredLinkKey(const u8* input); 169 void CommandWritePinType(const u8* input); 170 void CommandSetEventFilter(const u8* input); 171 void CommandWriteInquiryScanType(const u8* input); 172 void CommandWriteLinkSupervisionTimeout(const u8* input); 173 174 // OGF 0x04 - Informational commands and return parameters 175 void CommandReadBufferSize(const u8* input); 176 void CommandReadLocalVer(const u8* input); 177 void CommandReadLocalFeatures(const u8* input); 178 void CommandReadBDAdrr(const u8* input); 179 180 // OGF 0x3F - Vendor specific 181 void CommandVendorSpecific_FC4C(const u8* input, u32 size); 182 void CommandVendorSpecific_FC4F(const u8* input, u32 size); 183 184 #pragma pack(push, 1) 185 #define CONF_PAD_MAX_REGISTERED 10 186 187 struct ConfPadDevice 188 { 189 u8 bdaddr[6]; 190 char name[0x40]; 191 }; 192 193 struct ConfPads 194 { 195 u8 num_registered; 196 ConfPadDevice registered[CONF_PAD_MAX_REGISTERED]; 197 ConfPadDevice active[MAX_BBMOTES]; 198 ConfPadDevice unknown; 199 }; 200 #pragma pack(pop) 201 }; 202 } // namespace Device 203 } // namespace IOS::HLE 204