PageRenderTime 67ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb.cpp

https://github.com/bunnei/dolphin
C++ | 1872 lines | 1379 code | 393 blank | 100 comment | 95 complexity | 2b34fa54b84c2db4bfb10e47953fa578 MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. // Copyright 2013 Dolphin Emulator Project
  2. // Licensed under GPLv2
  3. // Refer to the license.txt file included.
  4. #include "Core/ConfigManager.h"
  5. #include "Core/Core.h"
  6. #include "Core/CoreTiming.h"
  7. #include "Core/Host.h"
  8. #include "Core/Movie.h"
  9. #include "Core/Debugger/Debugger_SymbolMap.h"
  10. #include "Core/HW/SystemTimers.h"
  11. #include "Core/HW/WII_IPC.h"
  12. #include "Core/HW/Wiimote.h"
  13. #include "Core/IPC_HLE/WII_IPC_HLE.h"
  14. #include "Core/IPC_HLE/WII_IPC_HLE_Device_usb.h"
  15. void CWII_IPC_HLE_Device_usb_oh1_57e_305::EnqueueReply(u32 CommandAddress)
  16. {
  17. // IOS seems to write back the command that was responded to in the FD field, this
  18. // class does not overwrite the command so it is safe to read back.
  19. Memory::Write_U32(Memory::Read_U32(CommandAddress), CommandAddress + 8);
  20. // The original hardware overwrites the command type with the async reply type.
  21. Memory::Write_U32(IPC_REP_ASYNC, CommandAddress);
  22. WII_IPC_HLE_Interface::EnqReply(CommandAddress);
  23. }
  24. // The device class
  25. CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _DeviceID, const std::string& _rDeviceName)
  26. : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
  27. , m_ScanEnable(0)
  28. , m_HCIEndpoint(0)
  29. , m_ACLEndpoint(0)
  30. , m_last_ticks(0)
  31. {
  32. // Activate only first Wiimote by default
  33. _conf_pads BT_DINF;
  34. SetUsbPointer(this);
  35. if (!SConfig::GetInstance().m_SYSCONF->GetArrayData("BT.DINF", (u8*)&BT_DINF, sizeof(_conf_pads)))
  36. {
  37. PanicAlertT("Trying to read from invalid SYSCONF\nWiimote bt ids are not available");
  38. }
  39. else
  40. {
  41. bdaddr_t tmpBD = BDADDR_ANY;
  42. u8 i = 0;
  43. while (i < MAX_BBMOTES)
  44. {
  45. if (i < BT_DINF.num_registered)
  46. {
  47. tmpBD.b[5] = BT_DINF.active[i].bdaddr[0] = BT_DINF.registered[i].bdaddr[0];
  48. tmpBD.b[4] = BT_DINF.active[i].bdaddr[1] = BT_DINF.registered[i].bdaddr[1];
  49. tmpBD.b[3] = BT_DINF.active[i].bdaddr[2] = BT_DINF.registered[i].bdaddr[2];
  50. tmpBD.b[2] = BT_DINF.active[i].bdaddr[3] = BT_DINF.registered[i].bdaddr[3];
  51. tmpBD.b[1] = BT_DINF.active[i].bdaddr[4] = BT_DINF.registered[i].bdaddr[4];
  52. tmpBD.b[0] = BT_DINF.active[i].bdaddr[5] = BT_DINF.registered[i].bdaddr[5];
  53. }
  54. else
  55. {
  56. tmpBD.b[5] = BT_DINF.active[i].bdaddr[0] = BT_DINF.registered[i].bdaddr[0] = i;
  57. tmpBD.b[4] = BT_DINF.active[i].bdaddr[1] = BT_DINF.registered[i].bdaddr[1] = 0;
  58. tmpBD.b[3] = BT_DINF.active[i].bdaddr[2] = BT_DINF.registered[i].bdaddr[2] = 0x79;
  59. tmpBD.b[2] = BT_DINF.active[i].bdaddr[3] = BT_DINF.registered[i].bdaddr[3] = 0x19;
  60. tmpBD.b[1] = BT_DINF.active[i].bdaddr[4] = BT_DINF.registered[i].bdaddr[4] = 2;
  61. tmpBD.b[0] = BT_DINF.active[i].bdaddr[5] = BT_DINF.registered[i].bdaddr[5] = 0x11;
  62. }
  63. const char* wmName;
  64. if (i == WIIMOTE_BALANCE_BOARD)
  65. wmName = "Nintendo RVL-WBC-01";
  66. else
  67. wmName = "Nintendo RVL-CNT-01";
  68. memcpy(BT_DINF.registered[i].name, wmName, 20);
  69. memcpy(BT_DINF.active[i].name, wmName, 20);
  70. INFO_LOG(WII_IPC_WIIMOTE, "Wiimote %d BT ID %x,%x,%x,%x,%x,%x", i, tmpBD.b[0], tmpBD.b[1], tmpBD.b[2], tmpBD.b[3], tmpBD.b[4], tmpBD.b[5]);
  71. m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, i, tmpBD, false));
  72. i++;
  73. }
  74. // save now so that when games load sysconf file it includes the new wiimotes
  75. // and the correct order for connected wiimotes
  76. if (!SConfig::GetInstance().m_SYSCONF->SetArrayData("BT.DINF", (u8*)&BT_DINF, sizeof(_conf_pads)) || !SConfig::GetInstance().m_SYSCONF->Save())
  77. PanicAlertT("Failed to write BT.DINF to SYSCONF");
  78. }
  79. // The BCM2045's btaddr:
  80. m_ControllerBD.b[0] = 0x11;
  81. m_ControllerBD.b[1] = 0x02;
  82. m_ControllerBD.b[2] = 0x19;
  83. m_ControllerBD.b[3] = 0x79;
  84. m_ControllerBD.b[4] = 0x00;
  85. m_ControllerBD.b[5] = 0xFF;
  86. memset(m_PacketCount, 0, sizeof(m_PacketCount));
  87. Host_SetWiiMoteConnectionState(0);
  88. }
  89. CWII_IPC_HLE_Device_usb_oh1_57e_305::~CWII_IPC_HLE_Device_usb_oh1_57e_305()
  90. {
  91. m_WiiMotes.clear();
  92. SetUsbPointer(nullptr);
  93. }
  94. void CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState(PointerWrap &p)
  95. {
  96. p.Do(m_Active);
  97. p.Do(m_ControllerBD);
  98. p.Do(m_CtrlSetup);
  99. p.Do(m_ACLSetup);
  100. p.DoPOD(m_HCIEndpoint);
  101. p.DoPOD(m_ACLEndpoint);
  102. p.Do(m_last_ticks);
  103. p.DoArray(m_PacketCount,MAX_BBMOTES);
  104. p.Do(m_ScanEnable);
  105. p.Do(m_EventQueue);
  106. m_acl_pool.DoState(p);
  107. for (unsigned int i = 0; i < MAX_BBMOTES; i++)
  108. m_WiiMotes[i].DoState(p);
  109. }
  110. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::RemoteDisconnect(u16 _connectionHandle)
  111. {
  112. return SendEventDisconnect(_connectionHandle, 0x13);
  113. }
  114. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::Open(u32 _CommandAddress, u32 _Mode)
  115. {
  116. m_ScanEnable = 0;
  117. m_last_ticks = 0;
  118. memset(m_PacketCount, 0, sizeof(m_PacketCount));
  119. m_HCIEndpoint.m_address = 0;
  120. m_ACLEndpoint.m_address = 0;
  121. Memory::Write_U32(GetDeviceID(), _CommandAddress + 4);
  122. m_Active = true;
  123. return true;
  124. }
  125. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::Close(u32 _CommandAddress, bool _bForce)
  126. {
  127. m_ScanEnable = 0;
  128. m_last_ticks = 0;
  129. memset(m_PacketCount, 0, sizeof(m_PacketCount));
  130. m_HCIEndpoint.m_address = 0;
  131. m_ACLEndpoint.m_address = 0;
  132. if (!_bForce)
  133. Memory::Write_U32(0, _CommandAddress + 4);
  134. m_Active = false;
  135. return true;
  136. }
  137. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtl(u32 _CommandAddress)
  138. {
  139. //ERROR_LOG(WII_IPC_WIIMOTE, "Passing ioctl to ioctlv");
  140. return IOCtlV(_CommandAddress); // FIXME: Hack
  141. }
  142. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress)
  143. {
  144. /*
  145. Memory::Write_U8(255, 0x80149950); // BTM LOG // 3 logs L2Cap // 4 logs l2_csm$
  146. Memory::Write_U8(255, 0x80149949); // Security Manager
  147. Memory::Write_U8(255, 0x80149048); // HID
  148. Memory::Write_U8(3, 0x80152058); // low ?? // >= 4 and you will get a lot of event messages of the same type
  149. Memory::Write_U8(1, 0x80152018); // WUD
  150. Memory::Write_U8(1, 0x80151FC8); // DEBUGPrint
  151. Memory::Write_U8(1, 0x80151488); // WPAD_LOG
  152. Memory::Write_U8(1, 0x801514A8); // USB_LOG
  153. Memory::Write_U8(1, 0x801514D8); // WUD_DEBUGPrint
  154. Memory::Write_U8(1, 0x80148E09); // HID LOG
  155. */
  156. bool _SendReply = false;
  157. SIOCtlVBuffer CommandBuffer(_CommandAddress);
  158. switch (CommandBuffer.Parameter)
  159. {
  160. case USBV0_IOCTL_CTRLMSG: // HCI command is received from the stack
  161. {
  162. // This is the HCI datapath from CPU to Wiimote, the USB stuff is little endian..
  163. m_CtrlSetup.bRequestType = *( u8*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address);
  164. m_CtrlSetup.bRequest = *( u8*)Memory::GetPointer(CommandBuffer.InBuffer[1].m_Address);
  165. m_CtrlSetup.wValue = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[2].m_Address);
  166. m_CtrlSetup.wIndex = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[3].m_Address);
  167. m_CtrlSetup.wLength = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[4].m_Address);
  168. m_CtrlSetup.m_PayLoadAddr = CommandBuffer.PayloadBuffer[0].m_Address;
  169. m_CtrlSetup.m_PayLoadSize = CommandBuffer.PayloadBuffer[0].m_Size;
  170. m_CtrlSetup.m_Address = CommandBuffer.m_Address;
  171. // check termination
  172. _dbg_assert_msg_(WII_IPC_WIIMOTE, *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[5].m_Address) == 0,
  173. "WIIMOTE: Termination != 0");
  174. #if 0 // this log can get really annoying
  175. DEBUG_LOG(WII_IPC_WIIMOTE, "USB_IOCTL_CTRLMSG (0x%08x) - execute command", _CommandAddress);
  176. DEBUG_LOG(WII_IPC_WIIMOTE, " bRequestType: 0x%x", m_CtrlSetup.bRequestType);
  177. DEBUG_LOG(WII_IPC_WIIMOTE, " bRequest: 0x%x", m_CtrlSetup.bRequest);
  178. DEBUG_LOG(WII_IPC_WIIMOTE, " wValue: 0x%x", m_CtrlSetup.wValue);
  179. DEBUG_LOG(WII_IPC_WIIMOTE, " wIndex: 0x%x", m_CtrlSetup.wIndex);
  180. DEBUG_LOG(WII_IPC_WIIMOTE, " wLength: 0x%x", m_CtrlSetup.wLength);
  181. DEBUG_LOG(WII_IPC_WIIMOTE, " m_PayLoadAddr: 0x%x", m_CtrlSetup.m_PayLoadAddr);
  182. DEBUG_LOG(WII_IPC_WIIMOTE, " m_PayLoadSize: 0x%x", m_CtrlSetup.m_PayLoadSize);
  183. #endif
  184. // Replies are generated inside
  185. ExecuteHCICommandMessage(m_CtrlSetup);
  186. }
  187. break;
  188. case USBV0_IOCTL_BLKMSG:
  189. {
  190. u8 Command = Memory::Read_U8(CommandBuffer.InBuffer[0].m_Address);
  191. switch (Command)
  192. {
  193. case ACL_DATA_OUT: // ACL data is received from the stack
  194. {
  195. // This is the ACL datapath from CPU to Wiimote
  196. // Here we only need to record the command address in case we need to delay the reply
  197. m_ACLSetup = CommandBuffer.m_Address;
  198. #if defined(_DEBUG) || defined(DEBUGFAST)
  199. DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer);
  200. #endif
  201. CtrlBuffer BulkBuffer(_CommandAddress);
  202. hci_acldata_hdr_t* pACLHeader = (hci_acldata_hdr_t*)Memory::GetPointer(BulkBuffer.m_buffer);
  203. _dbg_assert_(WII_IPC_WIIMOTE, HCI_BC_FLAG(pACLHeader->con_handle) == HCI_POINT2POINT);
  204. _dbg_assert_(WII_IPC_WIIMOTE, HCI_PB_FLAG(pACLHeader->con_handle) == HCI_PACKET_START);
  205. SendToDevice(HCI_CON_HANDLE(pACLHeader->con_handle),
  206. Memory::GetPointer(BulkBuffer.m_buffer + sizeof(hci_acldata_hdr_t)),
  207. pACLHeader->length);
  208. _SendReply = true;
  209. }
  210. break;
  211. case ACL_DATA_IN: // We are given an ACL buffer to fill
  212. {
  213. CtrlBuffer temp(_CommandAddress);
  214. m_ACLEndpoint = temp;
  215. DEBUG_LOG(WII_IPC_WIIMOTE, "ACL_DATA_IN: 0x%08x ", _CommandAddress);
  216. }
  217. break;
  218. default:
  219. {
  220. _dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown USBV0_IOCTL_BLKMSG: %x", Command);
  221. }
  222. break;
  223. }
  224. }
  225. break;
  226. case USBV0_IOCTL_INTRMSG:
  227. {
  228. u8 Command = Memory::Read_U8(CommandBuffer.InBuffer[0].m_Address);
  229. if (Command == HCI_EVENT) // We are given a HCI buffer to fill
  230. {
  231. CtrlBuffer temp(_CommandAddress);
  232. m_HCIEndpoint = temp;
  233. DEBUG_LOG(WII_IPC_WIIMOTE, "HCI_EVENT: 0x%08x ", _CommandAddress);
  234. }
  235. else
  236. {
  237. _dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown USBV0_IOCTL_INTRMSG: %x", Command);
  238. }
  239. }
  240. break;
  241. default:
  242. {
  243. _dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown CWII_IPC_HLE_Device_usb_oh1_57e_305: %x", CommandBuffer.Parameter);
  244. DEBUG_LOG(WII_IPC_WIIMOTE, "%s - IOCtlV:", GetDeviceName().c_str());
  245. DEBUG_LOG(WII_IPC_WIIMOTE, " Parameter: 0x%x", CommandBuffer.Parameter);
  246. DEBUG_LOG(WII_IPC_WIIMOTE, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer);
  247. DEBUG_LOG(WII_IPC_WIIMOTE, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer);
  248. DEBUG_LOG(WII_IPC_WIIMOTE, " BufferVector: 0x%08x", CommandBuffer.BufferVector);
  249. DEBUG_LOG(WII_IPC_WIIMOTE, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address);
  250. DEBUG_LOG(WII_IPC_WIIMOTE, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size);
  251. #if defined(_DEBUG) || defined(DEBUGFAST)
  252. DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer);
  253. #endif
  254. }
  255. break;
  256. }
  257. // write return value
  258. Memory::Write_U32(0, _CommandAddress + 4);
  259. return _SendReply;
  260. }
  261. // Here we handle the USBV0_IOCTL_BLKMSG Ioctlv
  262. void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendToDevice(u16 _ConnectionHandle, u8* _pData, u32 _Size)
  263. {
  264. CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_ConnectionHandle);
  265. if (pWiiMote == nullptr)
  266. return;
  267. INFO_LOG(WII_IPC_WIIMOTE, "Send ACL Packet to ConnectionHandle 0x%04x", _ConnectionHandle);
  268. IncDataPacket(_ConnectionHandle);
  269. pWiiMote->ExecuteL2capCmd(_pData, _Size);
  270. }
  271. void CWII_IPC_HLE_Device_usb_oh1_57e_305::IncDataPacket(u16 _ConnectionHandle)
  272. {
  273. m_PacketCount[_ConnectionHandle & 0xff]++;
  274. // I don't think this makes sense or should be necessary
  275. // m_PacketCount refers to "completed" packets and is not related to some buffer size, yes?
  276. #if 0
  277. if (m_PacketCount[_ConnectionHandle & 0xff] > (unsigned int)m_acl_pkts_num)
  278. {
  279. DEBUG_LOG(WII_IPC_WIIMOTE, "ACL buffer overflow");
  280. m_PacketCount[_ConnectionHandle & 0xff] = m_acl_pkts_num;
  281. }
  282. #endif
  283. }
  284. // Here we send ACL packets to CPU. They will consist of header + data.
  285. // The header is for example 07 00 41 00 which means size 0x0007 and channel 0x0041.
  286. void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLPacket(u16 _ConnectionHandle, u8* _pData, u32 _Size)
  287. {
  288. DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet from %x ready to send to stack...", _ConnectionHandle);
  289. if (m_ACLEndpoint.IsValid() && !m_HCIEndpoint.IsValid() && m_EventQueue.empty())
  290. {
  291. DEBUG_LOG(WII_IPC_WIIMOTE, "ACL endpoint valid, sending packet to %08x", m_ACLEndpoint.m_address);
  292. hci_acldata_hdr_t* pHeader = (hci_acldata_hdr_t*)Memory::GetPointer(m_ACLEndpoint.m_buffer);
  293. pHeader->con_handle = HCI_MK_CON_HANDLE(_ConnectionHandle, HCI_PACKET_START, HCI_POINT2POINT);
  294. pHeader->length = _Size;
  295. // Write the packet to the buffer
  296. memcpy((u8*)pHeader + sizeof(hci_acldata_hdr_t), _pData, pHeader->length);
  297. m_ACLEndpoint.SetRetVal(sizeof(hci_acldata_hdr_t) + _Size);
  298. EnqueueReply(m_ACLEndpoint.m_address);
  299. m_ACLEndpoint.Invalidate();
  300. }
  301. else
  302. {
  303. DEBUG_LOG(WII_IPC_WIIMOTE, "ACL endpoint not currently valid, queuing...");
  304. m_acl_pool.Store(_pData, _Size, _ConnectionHandle);
  305. }
  306. }
  307. // These messages are sent from the Wiimote to the game, for example RequestConnection()
  308. // or ConnectionComplete().
  309. //
  310. // Our WII_IPC_HLE is so efficient that we could fill the buffer immediately
  311. // rather than enqueue it to some other memory and this will do good for StateSave
  312. void CWII_IPC_HLE_Device_usb_oh1_57e_305::AddEventToQueue(const SQueuedEvent& _event)
  313. {
  314. DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x completed...", ((hci_event_hdr_t*)_event.m_buffer)->event);
  315. if (m_HCIEndpoint.IsValid())
  316. {
  317. if (m_EventQueue.empty()) // fast path :)
  318. {
  319. DEBUG_LOG(WII_IPC_WIIMOTE, "HCI endpoint valid, sending packet to %08x", m_HCIEndpoint.m_address);
  320. m_HCIEndpoint.FillBuffer(_event.m_buffer, _event.m_size);
  321. m_HCIEndpoint.SetRetVal(_event.m_size);
  322. // Send a reply to indicate HCI buffer is filled
  323. EnqueueReply(m_HCIEndpoint.m_address);
  324. m_HCIEndpoint.Invalidate();
  325. }
  326. else // push new one, pop oldest
  327. {
  328. DEBUG_LOG(WII_IPC_WIIMOTE, "HCI endpoint not "
  329. "currently valid, queueing(%lu)...",
  330. (unsigned long)m_EventQueue.size());
  331. m_EventQueue.push_back(_event);
  332. const SQueuedEvent& event = m_EventQueue.front();
  333. DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x "
  334. "being written from queue(%lu) to %08x...",
  335. ((hci_event_hdr_t*)event.m_buffer)->event,
  336. (unsigned long)m_EventQueue.size()-1,
  337. m_HCIEndpoint.m_address);
  338. m_HCIEndpoint.FillBuffer(event.m_buffer, event.m_size);
  339. m_HCIEndpoint.SetRetVal(event.m_size);
  340. // Send a reply to indicate HCI buffer is filled
  341. EnqueueReply(m_HCIEndpoint.m_address);
  342. m_HCIEndpoint.Invalidate();
  343. m_EventQueue.pop_front();
  344. }
  345. }
  346. else
  347. {
  348. DEBUG_LOG(WII_IPC_WIIMOTE, "HCI endpoint not currently valid, "
  349. "queuing(%lu)...", (unsigned long)m_EventQueue.size());
  350. m_EventQueue.push_back(_event);
  351. }
  352. }
  353. u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
  354. {
  355. bool packet_transferred = false;
  356. // check HCI queue
  357. if (!m_EventQueue.empty() && m_HCIEndpoint.IsValid())
  358. {
  359. // an endpoint has become available, and we have a stored response.
  360. const SQueuedEvent& event = m_EventQueue.front();
  361. DEBUG_LOG(WII_IPC_WIIMOTE,
  362. "HCI event %x being written from queue(%lu) to %08x...",
  363. ((hci_event_hdr_t*)event.m_buffer)->event,
  364. (unsigned long)m_EventQueue.size()-1,
  365. m_HCIEndpoint.m_address);
  366. m_HCIEndpoint.FillBuffer(event.m_buffer, event.m_size);
  367. m_HCIEndpoint.SetRetVal(event.m_size);
  368. // Send a reply to indicate HCI buffer is filled
  369. EnqueueReply(m_HCIEndpoint.m_address);
  370. m_HCIEndpoint.Invalidate();
  371. m_EventQueue.pop_front();
  372. packet_transferred = true;
  373. }
  374. // check ACL queue
  375. if (!m_acl_pool.IsEmpty() && m_ACLEndpoint.IsValid() && m_EventQueue.empty())
  376. {
  377. m_acl_pool.WriteToEndpoint(m_ACLEndpoint);
  378. packet_transferred = true;
  379. }
  380. // We wait for ScanEnable to be sent from the bt stack through HCI_CMD_WRITE_SCAN_ENABLE
  381. // before we initiate the connection.
  382. //
  383. // FiRES: TODO find a better way to do this
  384. // Create ACL connection
  385. if (m_HCIEndpoint.IsValid() && (m_ScanEnable & HCI_PAGE_SCAN_ENABLE))
  386. {
  387. for (auto& wiimote : m_WiiMotes)
  388. {
  389. if (wiimote.EventPagingChanged(m_ScanEnable))
  390. {
  391. Host_SetWiiMoteConnectionState(1);
  392. SendEventRequestConnection(wiimote);
  393. }
  394. }
  395. }
  396. // Link channels when connected
  397. if (m_ACLEndpoint.IsValid())
  398. {
  399. for (auto& wiimote : m_WiiMotes)
  400. {
  401. if (wiimote.LinkChannel())
  402. break;
  403. }
  404. }
  405. // The Real Wiimote sends report every ~5ms (200 Hz).
  406. const u64 interval = SystemTimers::GetTicksPerSecond() / 200;
  407. const u64 now = CoreTiming::GetTicks();
  408. if (now - m_last_ticks > interval)
  409. {
  410. for (unsigned int i = 0; i < m_WiiMotes.size(); i++)
  411. if (m_WiiMotes[i].IsConnected())
  412. {
  413. Wiimote::Update(i);
  414. }
  415. m_last_ticks = now;
  416. }
  417. SendEventNumberOfCompletedPackets();
  418. return packet_transferred;
  419. }
  420. void CWII_IPC_HLE_Device_usb_oh1_57e_305::ACLPool::Store(const u8* data, const u16 size, const u16 conn_handle)
  421. {
  422. if (m_queue.size() >= 100)
  423. {
  424. // Many simultaneous exchanges of ACL packets tend to cause the queue to fill up.
  425. ERROR_LOG(WII_IPC_WIIMOTE, "ACL queue size reached 100 - current packet will be dropped!");
  426. return;
  427. }
  428. _dbg_assert_msg_(WII_IPC_WIIMOTE,
  429. size < m_acl_pkt_size, "ACL packet too large for pool");
  430. m_queue.push_back(Packet());
  431. auto& packet = m_queue.back();
  432. std::copy(data, data + size, packet.data);
  433. packet.size = size;
  434. packet.conn_handle = conn_handle;
  435. }
  436. void CWII_IPC_HLE_Device_usb_oh1_57e_305::ACLPool::WriteToEndpoint(CtrlBuffer& endpoint)
  437. {
  438. auto& packet = m_queue.front();
  439. const u8* const data = packet.data;
  440. const u16 size = packet.size;
  441. const u16 conn_handle = packet.conn_handle;
  442. DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet being written from "
  443. "queue to %08x", endpoint.m_address);
  444. hci_acldata_hdr_t* pHeader = (hci_acldata_hdr_t*)Memory::GetPointer(endpoint.m_buffer);
  445. pHeader->con_handle = HCI_MK_CON_HANDLE(conn_handle, HCI_PACKET_START, HCI_POINT2POINT);
  446. pHeader->length = size;
  447. // Write the packet to the buffer
  448. std::copy(data, data + size, (u8*)pHeader + sizeof(hci_acldata_hdr_t));
  449. endpoint.SetRetVal(sizeof(hci_acldata_hdr_t) + size);
  450. m_queue.pop_front();
  451. EnqueueReply(endpoint.m_address);
  452. endpoint.Invalidate();
  453. }
  454. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventInquiryComplete()
  455. {
  456. SQueuedEvent Event(sizeof(SHCIEventInquiryComplete), 0);
  457. SHCIEventInquiryComplete* pInquiryComplete = (SHCIEventInquiryComplete*)Event.m_buffer;
  458. pInquiryComplete->EventType = HCI_EVENT_INQUIRY_COMPL;
  459. pInquiryComplete->PayloadLength = sizeof(SHCIEventInquiryComplete) - 2;
  460. pInquiryComplete->EventStatus = 0x00;
  461. AddEventToQueue(Event);
  462. INFO_LOG(WII_IPC_WIIMOTE, "Event: Inquiry complete");
  463. return true;
  464. }
  465. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventInquiryResponse()
  466. {
  467. if (m_WiiMotes.empty())
  468. return false;
  469. _dbg_assert_(WII_IPC_WIIMOTE, sizeof(SHCIEventInquiryResult) - 2 + (m_WiiMotes.size() * sizeof(hci_inquiry_response)) < 256);
  470. SQueuedEvent Event(static_cast<u32>(sizeof(SHCIEventInquiryResult) + m_WiiMotes.size()*sizeof(hci_inquiry_response)), 0);
  471. SHCIEventInquiryResult* pInquiryResult = (SHCIEventInquiryResult*)Event.m_buffer;
  472. pInquiryResult->EventType = HCI_EVENT_INQUIRY_RESULT;
  473. pInquiryResult->PayloadLength = (u8)(sizeof(SHCIEventInquiryResult) - 2 + (m_WiiMotes.size() * sizeof(hci_inquiry_response)));
  474. pInquiryResult->num_responses = (u8)m_WiiMotes.size();
  475. for (size_t i=0; i < m_WiiMotes.size(); i++)
  476. {
  477. if (m_WiiMotes[i].IsConnected())
  478. continue;
  479. u8* pBuffer = Event.m_buffer + sizeof(SHCIEventInquiryResult) + i*sizeof(hci_inquiry_response);
  480. hci_inquiry_response* pResponse = (hci_inquiry_response*)pBuffer;
  481. pResponse->bdaddr = m_WiiMotes[i].GetBD();
  482. pResponse->uclass[0]= m_WiiMotes[i].GetClass()[0];
  483. pResponse->uclass[1]= m_WiiMotes[i].GetClass()[1];
  484. pResponse->uclass[2]= m_WiiMotes[i].GetClass()[2];
  485. pResponse->page_scan_rep_mode = 1;
  486. pResponse->page_scan_period_mode = 0;
  487. pResponse->page_scan_mode = 0;
  488. pResponse->clock_offset = 0x3818;
  489. INFO_LOG(WII_IPC_WIIMOTE, "Event: Send Fake Inquiry of one controller");
  490. INFO_LOG(WII_IPC_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x",
  491. pResponse->bdaddr.b[0], pResponse->bdaddr.b[1], pResponse->bdaddr.b[2],
  492. pResponse->bdaddr.b[3], pResponse->bdaddr.b[4], pResponse->bdaddr.b[5]);
  493. }
  494. AddEventToQueue(Event);
  495. return true;
  496. }
  497. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventConnectionComplete(const bdaddr_t& _bd)
  498. {
  499. CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_bd);
  500. if (pWiiMote == nullptr)
  501. return false;
  502. SQueuedEvent Event(sizeof(SHCIEventConnectionComplete), 0);
  503. SHCIEventConnectionComplete* pConnectionComplete = (SHCIEventConnectionComplete*)Event.m_buffer;
  504. pConnectionComplete->EventType = HCI_EVENT_CON_COMPL;
  505. pConnectionComplete->PayloadLength = sizeof(SHCIEventConnectionComplete) - 2;
  506. pConnectionComplete->EventStatus = 0x00;
  507. pConnectionComplete->Connection_Handle = pWiiMote->GetConnectionHandle();
  508. pConnectionComplete->bdaddr = _bd;
  509. pConnectionComplete->LinkType = HCI_LINK_ACL;
  510. pConnectionComplete->EncryptionEnabled = HCI_ENCRYPTION_MODE_NONE;
  511. AddEventToQueue(Event);
  512. CWII_IPC_HLE_WiiMote* pWiimote = AccessWiiMote(pConnectionComplete->Connection_Handle);
  513. if (pWiimote)
  514. pWiimote->EventConnectionAccepted();
  515. static char s_szLinkType[][128] =
  516. {
  517. { "HCI_LINK_SCO 0x00 - Voice"},
  518. { "HCI_LINK_ACL 0x01 - Data"},
  519. { "HCI_LINK_eSCO 0x02 - eSCO"},
  520. };
  521. INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventConnectionComplete");
  522. INFO_LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", pConnectionComplete->Connection_Handle);
  523. DEBUG_LOG(WII_IPC_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x",
  524. pConnectionComplete->bdaddr.b[0], pConnectionComplete->bdaddr.b[1], pConnectionComplete->bdaddr.b[2],
  525. pConnectionComplete->bdaddr.b[3], pConnectionComplete->bdaddr.b[4], pConnectionComplete->bdaddr.b[5]);
  526. DEBUG_LOG(WII_IPC_WIIMOTE, " LinkType: %s", s_szLinkType[pConnectionComplete->LinkType]);
  527. DEBUG_LOG(WII_IPC_WIIMOTE, " EncryptionEnabled: %i", pConnectionComplete->EncryptionEnabled);
  528. return true;
  529. }
  530. // This is called from Update() after ScanEnable has been enabled.
  531. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRequestConnection(CWII_IPC_HLE_WiiMote& _rWiiMote)
  532. {
  533. SQueuedEvent Event(sizeof(SHCIEventRequestConnection), 0);
  534. SHCIEventRequestConnection* pEventRequestConnection = (SHCIEventRequestConnection*)Event.m_buffer;
  535. pEventRequestConnection->EventType = HCI_EVENT_CON_REQ;
  536. pEventRequestConnection->PayloadLength = sizeof(SHCIEventRequestConnection) - 2;
  537. pEventRequestConnection->bdaddr = _rWiiMote.GetBD();
  538. pEventRequestConnection->uclass[0] = _rWiiMote.GetClass()[0];
  539. pEventRequestConnection->uclass[1] = _rWiiMote.GetClass()[1];
  540. pEventRequestConnection->uclass[2] = _rWiiMote.GetClass()[2];
  541. pEventRequestConnection->LinkType = HCI_LINK_ACL;
  542. AddEventToQueue(Event);
  543. static char LinkType[][128] =
  544. {
  545. { "HCI_LINK_SCO 0x00 - Voice"},
  546. { "HCI_LINK_ACL 0x01 - Data" },
  547. { "HCI_LINK_eSCO 0x02 - eSCO" },
  548. };
  549. INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventRequestConnection");
  550. INFO_LOG(WII_IPC_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x",
  551. pEventRequestConnection->bdaddr.b[0], pEventRequestConnection->bdaddr.b[1], pEventRequestConnection->bdaddr.b[2],
  552. pEventRequestConnection->bdaddr.b[3], pEventRequestConnection->bdaddr.b[4], pEventRequestConnection->bdaddr.b[5]);
  553. DEBUG_LOG(WII_IPC_WIIMOTE, " COD[0]: 0x%02x", pEventRequestConnection->uclass[0]);
  554. DEBUG_LOG(WII_IPC_WIIMOTE, " COD[1]: 0x%02x", pEventRequestConnection->uclass[1]);
  555. DEBUG_LOG(WII_IPC_WIIMOTE, " COD[2]: 0x%02x", pEventRequestConnection->uclass[2]);
  556. DEBUG_LOG(WII_IPC_WIIMOTE, " LinkType: %s", LinkType[pEventRequestConnection->LinkType]);
  557. return true;
  558. }
  559. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventDisconnect(u16 _connectionHandle, u8 _Reason)
  560. {
  561. CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_connectionHandle);
  562. if (pWiiMote == nullptr)
  563. return false;
  564. SQueuedEvent Event(sizeof(SHCIEventDisconnectCompleted), _connectionHandle);
  565. SHCIEventDisconnectCompleted* pDisconnect = (SHCIEventDisconnectCompleted*)Event.m_buffer;
  566. pDisconnect->EventType = HCI_EVENT_DISCON_COMPL;
  567. pDisconnect->PayloadLength = sizeof(SHCIEventDisconnectCompleted) - 2;
  568. pDisconnect->EventStatus = 0;
  569. pDisconnect->Connection_Handle = _connectionHandle;
  570. pDisconnect->Reason = _Reason;
  571. AddEventToQueue(Event);
  572. INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventDisconnect");
  573. INFO_LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", pDisconnect->Connection_Handle);
  574. INFO_LOG(WII_IPC_WIIMOTE, " Reason: 0x%02x", pDisconnect->Reason);
  575. return true;
  576. }
  577. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventAuthenticationCompleted(u16 _connectionHandle)
  578. {
  579. CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_connectionHandle);
  580. if (pWiiMote == nullptr)
  581. return false;
  582. SQueuedEvent Event(sizeof(SHCIEventAuthenticationCompleted), _connectionHandle);
  583. SHCIEventAuthenticationCompleted* pEventAuthenticationCompleted = (SHCIEventAuthenticationCompleted*)Event.m_buffer;
  584. pEventAuthenticationCompleted->EventType = HCI_EVENT_AUTH_COMPL;
  585. pEventAuthenticationCompleted->PayloadLength = sizeof(SHCIEventAuthenticationCompleted) - 2;
  586. pEventAuthenticationCompleted->EventStatus = 0;
  587. pEventAuthenticationCompleted->Connection_Handle = _connectionHandle;
  588. INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventAuthenticationCompleted");
  589. INFO_LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", pEventAuthenticationCompleted->Connection_Handle);
  590. AddEventToQueue(Event);
  591. return true;
  592. }
  593. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRemoteNameReq(const bdaddr_t& _bd)
  594. {
  595. CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_bd);
  596. if (pWiiMote == nullptr)
  597. return false;
  598. SQueuedEvent Event(sizeof(SHCIEventRemoteNameReq), 0);
  599. SHCIEventRemoteNameReq* pRemoteNameReq = (SHCIEventRemoteNameReq*)Event.m_buffer;
  600. pRemoteNameReq->EventType = HCI_EVENT_REMOTE_NAME_REQ_COMPL;
  601. pRemoteNameReq->PayloadLength = sizeof(SHCIEventRemoteNameReq) - 2;
  602. pRemoteNameReq->EventStatus = 0x00;
  603. pRemoteNameReq->bdaddr = _bd;
  604. strcpy((char*)pRemoteNameReq->RemoteName, pWiiMote->GetName());
  605. INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventRemoteNameReq");
  606. INFO_LOG(WII_IPC_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x",
  607. pRemoteNameReq->bdaddr.b[0], pRemoteNameReq->bdaddr.b[1], pRemoteNameReq->bdaddr.b[2],
  608. pRemoteNameReq->bdaddr.b[3], pRemoteNameReq->bdaddr.b[4], pRemoteNameReq->bdaddr.b[5]);
  609. DEBUG_LOG(WII_IPC_WIIMOTE, " RemoteName: %s", pRemoteNameReq->RemoteName);
  610. AddEventToQueue(Event);
  611. return true;
  612. }
  613. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventReadRemoteFeatures(u16 _connectionHandle)
  614. {
  615. CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_connectionHandle);
  616. if (pWiiMote == nullptr)
  617. return false;
  618. SQueuedEvent Event(sizeof(SHCIEventReadRemoteFeatures), _connectionHandle);
  619. SHCIEventReadRemoteFeatures* pReadRemoteFeatures = (SHCIEventReadRemoteFeatures*)Event.m_buffer;
  620. pReadRemoteFeatures->EventType = HCI_EVENT_READ_REMOTE_FEATURES_COMPL;
  621. pReadRemoteFeatures->PayloadLength = sizeof(SHCIEventReadRemoteFeatures) - 2;
  622. pReadRemoteFeatures->EventStatus = 0x00;
  623. pReadRemoteFeatures->ConnectionHandle = _connectionHandle;
  624. pReadRemoteFeatures->features[0] = pWiiMote->GetFeatures()[0];
  625. pReadRemoteFeatures->features[1] = pWiiMote->GetFeatures()[1];
  626. pReadRemoteFeatures->features[2] = pWiiMote->GetFeatures()[2];
  627. pReadRemoteFeatures->features[3] = pWiiMote->GetFeatures()[3];
  628. pReadRemoteFeatures->features[4] = pWiiMote->GetFeatures()[4];
  629. pReadRemoteFeatures->features[5] = pWiiMote->GetFeatures()[5];
  630. pReadRemoteFeatures->features[6] = pWiiMote->GetFeatures()[6];
  631. pReadRemoteFeatures->features[7] = pWiiMote->GetFeatures()[7];
  632. INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventReadRemoteFeatures");
  633. DEBUG_LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", pReadRemoteFeatures->ConnectionHandle);
  634. DEBUG_LOG(WII_IPC_WIIMOTE, " features: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
  635. pReadRemoteFeatures->features[0], pReadRemoteFeatures->features[1], pReadRemoteFeatures->features[2],
  636. pReadRemoteFeatures->features[3], pReadRemoteFeatures->features[4], pReadRemoteFeatures->features[5],
  637. pReadRemoteFeatures->features[6], pReadRemoteFeatures->features[7]);
  638. AddEventToQueue(Event);
  639. return true;
  640. }
  641. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventReadRemoteVerInfo(u16 _connectionHandle)
  642. {
  643. CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_connectionHandle);
  644. if (pWiiMote == nullptr)
  645. return false;
  646. SQueuedEvent Event(sizeof(SHCIEventReadRemoteVerInfo), _connectionHandle);
  647. SHCIEventReadRemoteVerInfo* pReadRemoteVerInfo = (SHCIEventReadRemoteVerInfo*)Event.m_buffer;
  648. pReadRemoteVerInfo->EventType = HCI_EVENT_READ_REMOTE_VER_INFO_COMPL;
  649. pReadRemoteVerInfo->PayloadLength = sizeof(SHCIEventReadRemoteVerInfo) - 2;
  650. pReadRemoteVerInfo->EventStatus = 0x00;
  651. pReadRemoteVerInfo->ConnectionHandle = _connectionHandle;
  652. pReadRemoteVerInfo->lmp_version = pWiiMote->GetLMPVersion();
  653. pReadRemoteVerInfo->manufacturer = pWiiMote->GetManufactorID();
  654. pReadRemoteVerInfo->lmp_subversion = pWiiMote->GetLMPSubVersion();
  655. INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventReadRemoteVerInfo");
  656. DEBUG_LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", pReadRemoteVerInfo->ConnectionHandle);
  657. DEBUG_LOG(WII_IPC_WIIMOTE, " lmp_version: 0x%02x", pReadRemoteVerInfo->lmp_version);
  658. DEBUG_LOG(WII_IPC_WIIMOTE, " manufacturer: 0x%04x", pReadRemoteVerInfo->manufacturer);
  659. DEBUG_LOG(WII_IPC_WIIMOTE, " lmp_subversion: 0x%04x", pReadRemoteVerInfo->lmp_subversion);
  660. AddEventToQueue(Event);
  661. return true;
  662. }
  663. void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventCommandComplete(u16 _OpCode, void* _pData, u32 _DataSize)
  664. {
  665. _dbg_assert_(WII_IPC_WIIMOTE, (sizeof(SHCIEventCommand) - 2 + _DataSize) < 256);
  666. SQueuedEvent Event(sizeof(SHCIEventCommand) + _DataSize, 0);
  667. SHCIEventCommand* pHCIEvent = (SHCIEventCommand*)Event.m_buffer;
  668. pHCIEvent->EventType = HCI_EVENT_COMMAND_COMPL;
  669. pHCIEvent->PayloadLength = (u8)(sizeof(SHCIEventCommand) - 2 + _DataSize);
  670. pHCIEvent->PacketIndicator = 0x01;
  671. pHCIEvent->Opcode = _OpCode;
  672. // add the payload
  673. if ((_pData != nullptr) && (_DataSize > 0))
  674. {
  675. u8* pPayload = Event.m_buffer + sizeof(SHCIEventCommand);
  676. memcpy(pPayload, _pData, _DataSize);
  677. }
  678. INFO_LOG(WII_IPC_WIIMOTE, "Event: Command Complete (Opcode: 0x%04x)", pHCIEvent->Opcode);
  679. AddEventToQueue(Event);
  680. }
  681. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventCommandStatus(u16 _Opcode)
  682. {
  683. SQueuedEvent Event(sizeof(SHCIEventStatus), 0);
  684. SHCIEventStatus* pHCIEvent = (SHCIEventStatus*)Event.m_buffer;
  685. pHCIEvent->EventType = HCI_EVENT_COMMAND_STATUS;
  686. pHCIEvent->PayloadLength = sizeof(SHCIEventStatus) - 2;
  687. pHCIEvent->EventStatus = 0x0;
  688. pHCIEvent->PacketIndicator = 0x01;
  689. pHCIEvent->Opcode = _Opcode;
  690. INFO_LOG(WII_IPC_WIIMOTE, "Event: Command Status (Opcode: 0x%04x)", pHCIEvent->Opcode);
  691. AddEventToQueue(Event);
  692. return true;
  693. }
  694. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRoleChange(bdaddr_t _bd, bool _master)
  695. {
  696. CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_bd);
  697. if (pWiiMote == nullptr)
  698. return false;
  699. SQueuedEvent Event(sizeof(SHCIEventRoleChange), 0);
  700. SHCIEventRoleChange* pRoleChange = (SHCIEventRoleChange*)Event.m_buffer;
  701. pRoleChange->EventType = HCI_EVENT_ROLE_CHANGE;
  702. pRoleChange->PayloadLength = sizeof(SHCIEventRoleChange) - 2;
  703. pRoleChange->EventStatus = 0x00;
  704. pRoleChange->bdaddr = _bd;
  705. pRoleChange->NewRole = _master ? 0x00 : 0x01;
  706. AddEventToQueue(Event);
  707. INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventRoleChange");
  708. DEBUG_LOG(WII_IPC_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x",
  709. pRoleChange->bdaddr.b[0], pRoleChange->bdaddr.b[1], pRoleChange->bdaddr.b[2],
  710. pRoleChange->bdaddr.b[3], pRoleChange->bdaddr.b[4], pRoleChange->bdaddr.b[5]);
  711. DEBUG_LOG(WII_IPC_WIIMOTE, " NewRole: %i", pRoleChange->NewRole);
  712. return true;
  713. }
  714. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventNumberOfCompletedPackets()
  715. {
  716. SQueuedEvent Event((u32)(sizeof(hci_event_hdr_t) + sizeof(hci_num_compl_pkts_ep) + (sizeof(hci_num_compl_pkts_info) * m_WiiMotes.size())), 0);
  717. INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventNumberOfCompletedPackets");
  718. hci_event_hdr_t* event_hdr = (hci_event_hdr_t*)Event.m_buffer;
  719. hci_num_compl_pkts_ep* event = (hci_num_compl_pkts_ep*)((u8*)event_hdr + sizeof(hci_event_hdr_t));
  720. hci_num_compl_pkts_info* info = (hci_num_compl_pkts_info*)((u8*)event + sizeof(hci_num_compl_pkts_ep));
  721. event_hdr->event = HCI_EVENT_NUM_COMPL_PKTS;
  722. event_hdr->length = sizeof(hci_num_compl_pkts_ep);
  723. event->num_con_handles = 0;
  724. u32 acc = 0;
  725. for (unsigned int i = 0; i < m_WiiMotes.size(); i++)
  726. {
  727. event_hdr->length += sizeof(hci_num_compl_pkts_info);
  728. event->num_con_handles++;
  729. info->compl_pkts = m_PacketCount[i];
  730. info->con_handle = m_WiiMotes[i].GetConnectionHandle();
  731. DEBUG_LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", info->con_handle);
  732. DEBUG_LOG(WII_IPC_WIIMOTE, " Number_Of_Completed_Packets: %i", info->compl_pkts);
  733. acc += info->compl_pkts;
  734. m_PacketCount[i] = 0;
  735. info++;
  736. }
  737. if (acc)
  738. {
  739. AddEventToQueue(Event);
  740. }
  741. else
  742. {
  743. INFO_LOG(WII_IPC_WIIMOTE, "SendEventNumberOfCompletedPackets: no packets; no event");
  744. }
  745. return true;
  746. }
  747. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventModeChange(u16 _connectionHandle, u8 _mode, u16 _value)
  748. {
  749. CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_connectionHandle);
  750. if (pWiiMote == nullptr)
  751. return false;
  752. SQueuedEvent Event(sizeof(SHCIEventModeChange), _connectionHandle);
  753. SHCIEventModeChange* pModeChange = (SHCIEventModeChange*)Event.m_buffer;
  754. pModeChange->EventType = HCI_EVENT_MODE_CHANGE;
  755. pModeChange->PayloadLength = sizeof(SHCIEventModeChange) - 2;
  756. pModeChange->EventStatus = 0;
  757. pModeChange->Connection_Handle = _connectionHandle;
  758. pModeChange->CurrentMode = _mode;
  759. pModeChange->Value = _value;
  760. INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventModeChange");
  761. DEBUG_LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", pModeChange->Connection_Handle);
  762. DEBUG_LOG(WII_IPC_WIIMOTE, " Current Mode: 0x%02x", pModeChange->CurrentMode = _mode);
  763. AddEventToQueue(Event);
  764. return true;
  765. }
  766. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventLinkKeyNotification(const u8 num_to_send)
  767. {
  768. u8 payload_length = sizeof(hci_return_link_keys_ep) + sizeof(hci_link_key_rep_cp) * num_to_send;
  769. SQueuedEvent Event(2 + payload_length, 0);
  770. SHCIEventLinkKeyNotification* pEventLinkKey = (SHCIEventLinkKeyNotification*)Event.m_buffer;
  771. INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventLinkKeyNotification");
  772. // event header
  773. pEventLinkKey->EventType = HCI_EVENT_RETURN_LINK_KEYS;
  774. pEventLinkKey->PayloadLength = payload_length;
  775. // this is really hci_return_link_keys_ep.num_keys
  776. pEventLinkKey->numKeys = num_to_send;
  777. // copy infos - this only works correctly if we're meant to start at first device and read all keys
  778. for (int i = 0; i < num_to_send; i++)
  779. {
  780. hci_link_key_rep_cp* link_key_info
  781. = (hci_link_key_rep_cp*)((u8*)&pEventLinkKey->bdaddr + sizeof(hci_link_key_rep_cp) * i);
  782. link_key_info->bdaddr = m_WiiMotes[i].GetBD();
  783. memcpy(link_key_info->key, m_WiiMotes[i].GetLinkKey(), HCI_KEY_SIZE);
  784. DEBUG_LOG(WII_IPC_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x",
  785. link_key_info->bdaddr.b[0], link_key_info->bdaddr.b[1], link_key_info->bdaddr.b[2],
  786. link_key_info->bdaddr.b[3], link_key_info->bdaddr.b[4], link_key_info->bdaddr.b[5]);
  787. LOG_LinkKey(link_key_info->key);
  788. }
  789. AddEventToQueue(Event);
  790. return true;
  791. };
  792. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRequestLinkKey(const bdaddr_t& _bd)
  793. {
  794. SQueuedEvent Event(sizeof(SHCIEventRequestLinkKey), 0);
  795. SHCIEventRequestLinkKey* pEventRequestLinkKey = (SHCIEventRequestLinkKey*)Event.m_buffer;
  796. pEventRequestLinkKey->EventType = HCI_EVENT_LINK_KEY_REQ;
  797. pEventRequestLinkKey->PayloadLength = sizeof(SHCIEventRequestLinkKey) - 2;
  798. pEventRequestLinkKey->bdaddr = _bd;
  799. INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventRequestLinkKey");
  800. DEBUG_LOG(WII_IPC_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x",
  801. pEventRequestLinkKey->bdaddr.b[0], pEventRequestLinkKey->bdaddr.b[1], pEventRequestLinkKey->bdaddr.b[2],
  802. pEventRequestLinkKey->bdaddr.b[3], pEventRequestLinkKey->bdaddr.b[4], pEventRequestLinkKey->bdaddr.b[5]);
  803. AddEventToQueue(Event);
  804. return true;
  805. };
  806. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventReadClockOffsetComplete(u16 _connectionHandle)
  807. {
  808. CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_connectionHandle);
  809. if (pWiiMote == nullptr)
  810. return false;
  811. SQueuedEvent Event(sizeof(SHCIEventReadClockOffsetComplete), _connectionHandle);
  812. SHCIEventReadClockOffsetComplete* pReadClockOffsetComplete = (SHCIEventReadClockOffsetComplete*)Event.m_buffer;
  813. pReadClockOffsetComplete->EventType = HCI_EVENT_READ_CLOCK_OFFSET_COMPL;
  814. pReadClockOffsetComplete->PayloadLength = sizeof(SHCIEventReadClockOffsetComplete) - 2;
  815. pReadClockOffsetComplete->EventStatus = 0x00;
  816. pReadClockOffsetComplete->ConnectionHandle = _connectionHandle;
  817. pReadClockOffsetComplete->ClockOffset = 0x3818;
  818. INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventReadClockOffsetComplete");
  819. DEBUG_LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", pReadClockOffsetComplete->ConnectionHandle);
  820. DEBUG_LOG(WII_IPC_WIIMOTE, " ClockOffset: 0x%04x", pReadClockOffsetComplete->ClockOffset);
  821. AddEventToQueue(Event);
  822. return true;
  823. }
  824. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventConPacketTypeChange(u16 _connectionHandle, u16 _packetType)
  825. {
  826. CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_connectionHandle);
  827. if (pWiiMote == nullptr)
  828. return false;
  829. SQueuedEvent Event(sizeof(SHCIEventConPacketTypeChange), _connectionHandle);
  830. SHCIEventConPacketTypeChange* pChangeConPacketType = (SHCIEventConPacketTypeChange*)Event.m_buffer;
  831. pChangeConPacketType->EventType = HCI_EVENT_CON_PKT_TYPE_CHANGED;
  832. pChangeConPacketType->PayloadLength = sizeof(SHCIEventConPacketTypeChange) - 2;
  833. pChangeConPacketType->EventStatus = 0x00;
  834. pChangeConPacketType->ConnectionHandle = _connectionHandle;
  835. pChangeConPacketType->PacketType = _packetType;
  836. INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventConPacketTypeChange");
  837. DEBUG_LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", pChangeConPacketType->ConnectionHandle);
  838. DEBUG_LOG(WII_IPC_WIIMOTE, " PacketType: 0x%04x", pChangeConPacketType->PacketType);
  839. AddEventToQueue(Event);
  840. return true;
  841. }
  842. // Command dispatcher
  843. // This is called from the USBV0_IOCTL_CTRLMSG Ioctlv
  844. void CWII_IPC_HLE_Device_usb_oh1_57e_305::ExecuteHCICommandMessage(const SHCICommandMessage& _rHCICommandMessage)
  845. {
  846. u8* pInput = Memory::GetPointer(_rHCICommandMessage.m_PayLoadAddr + 3);
  847. SCommandMessage* pMsg = (SCommandMessage*)Memory::GetPointer(_rHCICommandMessage.m_PayLoadAddr);
  848. u16 ocf = HCI_OCF(pMsg->Opcode);
  849. u16 ogf = HCI_OGF(pMsg->Opcode);
  850. INFO_LOG(WII_IPC_WIIMOTE, "**************************************************");
  851. INFO_LOG(WII_IPC_WIIMOTE, "Execute HCI Command: 0x%04x (ocf: 0x%02x, ogf: 0x%02x)", pMsg->Opcode, ocf, ogf);
  852. switch (pMsg->Opcode)
  853. {
  854. //
  855. // --- read commands ---
  856. //
  857. case HCI_CMD_RESET:
  858. CommandReset(pInput);
  859. break;
  860. case HCI_CMD_READ_BUFFER_SIZE:
  861. CommandReadBufferSize(pInput);
  862. break;
  863. case HCI_CMD_READ_LOCAL_VER:
  864. CommandReadLocalVer(pInput);
  865. break;
  866. case HCI_CMD_READ_BDADDR:
  867. CommandReadBDAdrr(pInput);
  868. break;
  869. case HCI_CMD_READ_LOCAL_FEATURES:
  870. CommandReadLocalFeatures(pInput);
  871. break;
  872. case HCI_CMD_READ_STORED_LINK_KEY:
  873. CommandReadStoredLinkKey(pInput);
  874. break;
  875. case HCI_CMD_WRITE_UNIT_CLASS:
  876. CommandWriteUnitClass(pInput);
  877. break;
  878. case HCI_CMD_WRITE_LOCAL_NAME:
  879. CommandWriteLocalName(pInput);
  880. break;
  881. case HCI_CMD_WRITE_PIN_TYPE:
  882. CommandWritePinType(pInput);
  883. break;
  884. case HCI_CMD_HOST_BUFFER_SIZE:
  885. CommandHostBufferSize(pInput);
  886. break;
  887. case HCI_CMD_WRITE_PAGE_TIMEOUT:
  888. CommandWritePageTimeOut(pInput);
  889. break;
  890. case HCI_CMD_WRITE_SCAN_ENABLE:
  891. CommandWriteScanEnable(pInput);
  892. break;
  893. case HCI_CMD_WRITE_INQUIRY_MODE:
  894. CommandWriteInquiryMode(pInput);
  895. break;
  896. case HCI_CMD_WRITE_PAGE_SCAN_TYPE:
  897. CommandWritePageScanType(pInput);
  898. break;
  899. case HCI_CMD_SET_EVENT_FILTER:
  900. CommandSetEventFilter(pInput);
  901. break;
  902. case HCI_CMD_INQUIRY:
  903. CommandInquiry(pInput);
  904. break;
  905. case HCI_CMD_WRITE_INQUIRY_SCAN_TYPE:
  906. CommandWriteInquiryScanType(pInput);
  907. break;
  908. // vendor specific...
  909. case 0xFC4C:
  910. CommandVendorSpecific_FC4C(pInput, _rHCICommandMessage.m_PayLoadSize - 3);
  911. break;
  912. case 0xFC4F:
  913. CommandVendorSpecific_FC4F(pInput, _rHCICommandMessage.m_PayLoadSize - 3);
  914. break;
  915. case HCI_CMD_INQUIRY_CANCEL:
  916. CommandInquiryCancel(pInput);
  917. break;
  918. case HCI_CMD_REMOTE_NAME_REQ:
  919. CommandRemoteNameReq(pInput);
  920. break;
  921. case HCI_CMD_CREATE_CON:
  922. CommandCreateCon(pInput);
  923. break;
  924. case HCI_CMD_ACCEPT_CON:
  925. CommandAcceptCon(pInput);
  926. break;
  927. case HCI_CMD_CHANGE_CON_PACKET_TYPE:
  928. CommandChangeConPacketType(pInput);
  929. break;
  930. case HCI_CMD_READ_CLOCK_OFFSET:
  931. CommandReadClockOffset(pInput);
  932. break;
  933. case HCI_CMD_READ_REMOTE_VER_INFO:
  934. CommandReadRemoteVerInfo(pInput);
  935. break;
  936. case HCI_CMD_READ_REMOTE_FEATURES:
  937. CommandReadRemoteFeatures(pInput);
  938. break;
  939. case HCI_CMD_WRITE_LINK_POLICY_SETTINGS:
  940. CommandWriteLinkPolicy(pInput);
  941. break;
  942. case HCI_CMD_AUTH_REQ:
  943. CommandAuthenticationRequested(pInput);
  944. break;
  945. case HCI_CMD_SNIFF_MODE:
  946. CommandSniffMode(pInput);
  947. break;
  948. case HCI_CMD_DISCONNECT:
  949. CommandDisconnect(pInput);
  950. break;
  951. case HCI_CMD_WRITE_LINK_SUPERVISION_TIMEOUT:
  952. CommandWriteLinkSupervisionTimeout(pInput);
  953. break;
  954. case HCI_CMD_LINK_KEY_NEG_REP:
  955. CommandLinkKeyNegRep(pInput);
  956. break;
  957. case HCI_CMD_LINK_KEY_REP:
  958. CommandLinkKeyRep(pInput);
  959. break;
  960. case HCI_CMD_DELETE_STORED_LINK_KEY:
  961. CommandDeleteStoredLinkKey(pInput);
  962. break;
  963. default:
  964. // send fake okay msg...
  965. SendEventCommandComplete(pMsg->Opcode, nullptr, 0);
  966. if (ogf == HCI_OGF_VENDOR)
  967. {
  968. ERROR_LOG(WII_IPC_WIIMOTE, "Command: vendor specific: 0x%04X (ocf: 0x%x)", pMsg->Opcode, ocf);
  969. for (int i = 0; i < pMsg->len; i++)
  970. {
  971. ERROR_LOG(WII_IPC_WIIMOTE, " 0x02%x", pInput[i]);
  972. }
  973. }
  974. else
  975. {
  976. _dbg_assert_msg_(WII_IPC_WIIMOTE, 0,
  977. "Unknown USB_IOCTL_CTRLMSG: 0x%04X (ocf: 0x%x ogf 0x%x)", pMsg->Opcode, ocf, ogf);
  978. }
  979. break;
  980. }
  981. // HCI command is finished, send a reply to command
  982. EnqueueReply(_rHCICommandMessage.m_Address);
  983. }
  984. //
  985. //
  986. // --- command helper
  987. //
  988. //
  989. void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandInquiry(u8* _Input)
  990. {
  991. // Inquiry should not be called normally
  992. hci_inquiry_cp* pInquiry = (hci_inquiry_cp*)_Input;
  993. INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_INQUIRY:");
  994. DEBUG_LOG(WII_IPC_WIIMOTE, "write:");
  995. DEBUG_LOG(WII_IPC_WIIMOTE, " LAP[0]: 0x%02x", pInquiry->lap[0]);
  996. DEBUG_LOG(WII_IPC_WIIMOTE, " LAP[1]: 0x%02x", pInquiry->lap[1]);
  997. DEBUG_LOG(WII_IPC_WIIMOTE, " LAP[2]: 0x%02x", pInquiry->lap[2]);
  998. DEBUG_LOG(WII_IPC_WIIMOTE, " inquiry_length: %i (N x 1.28) sec", pInquiry->inquiry_length);
  999. DEBUG_LOG(WII_IPC_WIIMOTE, " num_responses: %i (N x 1.28) sec", pInquiry->num_responses);
  1000. SendEventCommandStatus(HCI_CMD_INQUIRY);
  1001. SendEventInquiryResponse();
  1002. SendEventInquiryComplete();
  1003. }
  1004. void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandInquiryCancel(u8* _Input)
  1005. {
  1006. hci_inquiry_cancel_rp Reply;
  1007. Reply.status = 0x00;
  1008. INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_INQUIRY_CANCEL");
  1009. SendEventCommandComplete(HCI_CMD_INQUIRY_CANCEL, &Reply, sizeof(hci_inquiry_cancel_rp));
  1010. }
  1011. void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandCreateCon(u8* _Input)
  1012. {
  1013. hci_create_con_cp* pCreateCon = (hci_create_con_cp*)_Input;
  1014. INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_CREATE_CON");
  1015. DEBUG_LOG(WII_IPC_WIIMOTE, "Input:");
  1016. DEBUG_LOG(WII_IPC_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x",
  1017. pCreateCon->bdaddr.b[0], pCreateCon->bdaddr.b[1], pCreateCon->bdaddr.b[2],
  1018. pCreateCon->bdaddr.b[3], pCreateCon->bdaddr.b[4], pCreateCon->bdaddr.b[5]);
  1019. DEBUG_LOG(WII_IPC_WIIMOTE, " pkt_type: %i", pCreateCon->pkt_type);
  1020. DEBUG_LOG(WII_IPC_WIIMOTE, " page_scan_rep_mode: %i", pCreateCon->page_scan_rep_mode);
  1021. DEBUG_LOG(WII_IPC_WIIMOTE, " page_scan_mode: %i", pCreateCon->page_scan_mode);
  1022. DEBUG_LOG(WII_IPC_WIIMOTE, " clock_offset: %i", pCreateCon->clock_offset);
  1023. DEBUG_LOG(WII_IPC_WIIMOTE, " accept_role_switch: %i", pCreateCon->accept_role_switch);
  1024. SendEventCommandStatus(HCI_CMD_CREATE_CON);
  1025. SendEventConnectionComplete(pCreateCon->bdaddr);
  1026. }
  1027. void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandDisconnect(u8* _Input)
  1028. {
  1029. hci_discon_cp* pDiscon = (hci_discon_cp*)_Input;
  1030. INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_DISCONNECT");
  1031. DEBUG_LOG(WII_IPC_WIIMOTE, " ConnectionHandle: 0x%04x", pDiscon->con_handle);
  1032. DEBUG_LOG(WII_IPC_WIIMOTE, " Reason: 0x%02x", pDiscon->reason);
  1033. Host_SetWiiMoteConnectionState(0);
  1034. SendEventCommandStatus(HCI_CMD_DISCONNECT);
  1035. SendEventDisconnect(pDiscon->con_handle, pDiscon->reason);
  1036. CWII_IPC_HLE_WiiMote* pWiimote = AccessWiiMote(pDiscon->con_handle);
  1037. if (pWiimote)
  1038. pWiimote->EventDisconnect();
  1039. }
  1040. void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandAcceptCon(u8* _Input)
  1041. {
  1042. hci_accept_con_cp* pAcceptCon = (hci_accept_con_cp*)_Input;
  1043. static char s_szRole[][128] =
  1044. {
  1045. { "Master (0x00)"},
  1046. { "Slave (0x01)"},
  1047. };
  1048. INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_ACCEPT_CON");
  1049. DEBUG_LOG(WII_IPC_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x",
  1050. pAcceptCon->bdaddr.b[0], pAcceptCon->bdaddr.b[1], pAcceptCon->bdaddr.b[2],
  1051. pAcceptCon->bdaddr.b[3], pAcceptCon->bdaddr.b[4], pAcceptCon->bdaddr.b[5]);
  1052. DEBUG_LOG(WII_IPC_WIIMOTE, " role: %s", s_szRole[pAcceptCon->role]);
  1053. SendEventCommandStatus(HCI_CMD_ACCEPT_CON);
  1054. // this connection wants to be the master
  1055. if (pAcceptCon->role == 0)
  1056. {
  1057. SendEventRoleChange(pAcceptCon->bdaddr, true);
  1058. }
  1059. SendEventConnectionComplete(pAcceptCon->bdaddr);
  1060. }
  1061. void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandLinkKeyRep(u8* _Input)
  1062. {
  1063. hci_link_key_rep_cp* pKeyRep = (hci_link_key_rep_cp*)_Input;
  1064. INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_LINK_KEY_REP");
  1065. DEBUG_LOG(WII_IPC_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x",
  1066. pKeyRep->bdaddr.b[0], pKeyRep->bdaddr.b[1], pKeyRep->bdaddr.b[2],
  1067. pKeyRep->bdaddr.b[3], pKeyRep->bdaddr.b[4], pKeyRep->bdaddr.b[5]);
  1068. LOG_LinkKey(pKeyRep->key);
  1069. hci_link_key_rep_rp Reply;
  1070. Reply.status = 0x00;
  1071. Reply.bdaddr = pKeyRep->bdaddr;
  1072. SendEventCommandComplete(HCI_CMD_LINK_KEY_REP, &Reply, sizeof(hci_link_key_rep_rp));
  1073. }
  1074. void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandLinkKeyNegRep(u8* _Input)
  1075. {
  1076. hci_link_key_neg_rep_cp* pKeyNeg = (hci_link_key_neg_rep_cp*)_Input;
  1077. INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_LINK_KEY_NEG_REP");
  1078. DEBUG_LOG(WII_IPC_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x",
  1079. pKeyNeg->bdaddr.b[0], pKeyNeg->bdaddr.b[1], pKeyNeg->bdaddr.b[2],
  1080. pKeyNeg->bdaddr.b[3], pKeyNeg->bdaddr.b[4], pKeyNeg->bdaddr.b[5]);
  1081. hci_link_key_neg_rep_rp Reply;
  1082. Reply.status = 0x00;
  1083. Reply.bdaddr = pKeyNeg->bdaddr;
  1084. SendEventCommandComplete(HCI_CMD_LINK_KEY_NEG_REP, &Reply, sizeof(hci_link_key_neg_rep_rp));
  1085. }
  1086. void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandChangeConPacketType(u8* _Input)
  1087. {
  1088. hci_change_con_pkt_type_cp* pChangePacketType = (hci_change_con_pkt_type_cp*)_Input;
  1089. // ntd stack sets packet type 0xcc18, which is HCI_PKT_DH5 | HCI_PKT_DM5 | HCI_PKT_DH1 | HCI_PKT_DM1
  1090. // dunno what to do...run awayyyyyy!
  1091. INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_CHANGE_CON_PACKET_TYPE");
  1092. DEBUG_LOG(WII_IPC_WIIMOTE, " ConnectionHandle: 0x%04x", pChangePacketType->con_handle);
  1093. DEBUG_LOG(WII_IPC_WIIMOTE, " PacketType: 0x%04x", pChangePacketType->pkt_type);
  1094. SendEventCommandStatus(HCI_CMD_CHANGE_CON_PACKET_TYPE);
  1095. SendEventConPacketTypeChange(pChangePacketType->con_handle, pChangePacketType->pkt_type);
  1096. }
  1097. void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandAuthenticationRequested(u8* _Input)
  1098. {
  1099. hci_auth_req_cp* pAuthReq = (hci_auth_req_cp*)_Input;
  1100. INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_AUTH_REQ");
  1101. DEBUG_LOG(WII_IPC_WIIMOTE, " ConnectionHandle: 0x%04x", pAuthReq->con_handle);
  1102. SendEventCommandStatus(HCI_CMD_AUTH_REQ);
  1103. SendEventAuthenticationCompleted(pAuthReq->con_handle);
  1104. }
  1105. void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandRemoteNameReq(u8* _Input)
  1106. {
  1107. hci_remote_name_req_cp* pRemoteNameReq = (hci_remote_name_req_cp*)_Input;
  1108. INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_REMOTE_NAME_REQ");
  1109. DEBUG_LOG(WII_IPC_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x",
  1110. pRemoteNameReq->bdaddr.b[0], pRemoteNameReq->bdaddr.b[1], pRemoteNameReq->bdaddr.b[2],
  1111. pRemoteNameReq->bdaddr.b[3], pRemoteNameReq->bdaddr.b[4], pRemoteNameReq->bdaddr.b[5]);
  1112. DEBUG_LOG(WII_IPC_WIIMOTE, " page_scan_rep_mode: %i", pRemoteNameReq->page_scan_rep_mode);
  1113. DEBUG_LOG(WII_IPC_WIIMOTE, " page_scan_mode: %i", pRemoteNameReq->page_scan_mode);
  1114. DEBUG_LOG(WII_IPC_WIIMOTE, " clock_offset: %i", pRemoteNameReq->clock_offset);
  1115. SendEventCommandStatus(HCI_CMD_REMOTE_NAME_REQ);
  1116. SendEventRemoteNameReq(pRemoteNameReq->bdaddr);
  1117. }
  1118. void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadRemoteFeatures(u8* _Input)
  1119. {
  1120. hci_read_remote_features_cp* pReadRemoteFeatures = (hci_read_remote_features_cp*)_Input;
  1121. INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_READ_REMOTE_FEATURES");
  1122. DEBUG_LOG(WII_IPC_WIIMOTE, " ConnectionHandle: 0x%04x", pReadRemoteFeatures->con_handle);
  1123. SendEventCommandStatus(HCI_CMD_READ_REMOTE_FEATURES);
  1124. SendEventReadRemoteFeatures(pReadRemoteFeatures->con_handle);
  1125. }
  1126. void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadRemoteVerInfo(u8* _Input)
  1127. {
  1128. hci_read_remote_ver_info_cp* pReadRemoteVerInfo = (hci_read_remote_ver_info_cp*)_Input;
  1129. INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_READ_REMOTE_VER_INFO");
  1130. DEBUG_LOG(WII_IPC_WIIMOTE, " ConnectionHandle: 0x%02x", pReadRemoteVerInfo->con_handle);
  1131. SendEventCommandStatus(HCI_CMD_READ_REMOTE_VER_INFO);
  1132. SendEventReadRemoteVerInfo(pReadRemoteVerInfo->con_handle);
  1133. }
  1134. void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadClockOffset(u8* _Input)
  1135. {
  1136. hci_read_clock_offset_cp* pReadClockOffset = (hci_read_clock_offset_cp*)_Input;
  1137. INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_READ_CLOCK_OFFSET");
  1138. DEBUG_LOG(WII_IPC_WIIMOTE, " ConnectionHandle: 0x%02x", pReadClockOffset->con_handle);
  1139. SendEventCommandStatus(HCI_CMD_READ_CLOCK_OFFSET);
  1140. SendEventReadClockOffsetComplete(pReadClockOffset->con_handle);
  1141. }
  1142. void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandSniffMode(u8*

Large files files are truncated, but you can click here to view the full file