diff --git a/Source/Core/Core/Core.vcproj b/Source/Core/Core/Core.vcproj index 20fb7b864b..bd2ab5fb2d 100644 --- a/Source/Core/Core/Core.vcproj +++ b/Source/Core/Core/Core.vcproj @@ -1344,6 +1344,14 @@ RelativePath=".\Src\VolumeHandler.h" > + + + + diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp index d2975e61fd..73851051a6 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp @@ -20,14 +20,11 @@ #include CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _DeviceID, const std::string& _rDeviceName) -: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) -, m_ACLAnswer(false) -, m_pACLBuffer(NULL) -, m_pHCIBuffer(NULL) -, m_State(STATE_NONE) -, m_UpdateWaitCount(0) -, scan_enable(0) -, m_DelayedEvent(EVENT_NONE) + : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) + , m_pACLBuffer(NULL) + , m_pHCIBuffer(NULL) + , m_UpdateWaitCount(0) + , scan_enable(0) { m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, 0)); @@ -57,12 +54,12 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress) { // wpadsampled.elf - patch so the USB_LOG will print somehting // even it it wasn't very useful yet... - // Memory::Write_U8(1, 0x801514A8); // USB_LOG - //Memory::Write_U8(1, 0x801514D8); // WUD_DEBUGPrint + Memory::Write_U8(1, 0x801514A8); // USB_LOG + Memory::Write_U8(1, 0x801514D8); // WUD_DEBUGPrint SIOCtlVBuffer CommandBuffer(_CommandAddress); - LOG(WIIMOTE, "USB_IOCTL_CTRLMSG(0x%x)", CommandBuffer.Parameter); +// LOG(WIIMOTE, "USB_IOCTL_CTRLMSG(0x%x)", CommandBuffer.Parameter); // DumpAsync(CommandBuffer.BufferVector, _CommandAddress, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer); @@ -154,10 +151,13 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress) case HCI_EVENT_ENDPOINT: { if (m_pHCIBuffer) + { + PanicAlert("Kill current hci buffer... there could be a comand inside"); delete m_pHCIBuffer; + } m_pHCIBuffer = new SIOCtlVBuffer(_CommandAddress); - LOG(WIIMOTE, "HCI_EVENT_ENDPOINT: 0x%08x", _CommandAddress); + // LOG(WIIMOTE, "HCI_EVENT_ENDPOINT: 0x%08x", _CommandAddress); return false; } break; @@ -206,30 +206,15 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendToDevice(u16 _ConnectionHandle, u8 void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLFrame(u16 _ConnectionHandle, u8* _pData, u32 _Size) { - if(m_State == STATE_NONE && m_HCICommandMessageQueue.empty() && !m_ACLAnswer && m_pACLBuffer) { - LOG(WIIMOTE, "Sending ACL frame."); - UACLHeader* pHeader = (UACLHeader*)Memory::GetPointer(m_pACLBuffer->PayloadBuffer[0].m_Address); - pHeader->ConnectionHandle = _ConnectionHandle; - pHeader->BCFlag = 0; - pHeader->PBFlag = 2; - pHeader->Size = _Size; + LOG(WIIMOTE, "Queing ACL frame."); - memcpy(Memory::GetPointer(m_pACLBuffer->PayloadBuffer[0].m_Address + sizeof(UACLHeader)), _pData, _Size); - - // return reply buffer size - Memory::Write_U32(sizeof(UACLHeader) + _Size, m_pACLBuffer->m_Address + 0x4); - - m_ACLAnswer = true; - } else { - LOG(WIIMOTE, "Queing ACL frame."); - //queue the packet - ACLFrame frame; - frame.ConnectionHandle = _ConnectionHandle; - frame.data = new u8[_Size]; - memcpy(frame.data, _pData, _Size); - frame.size = _Size; - m_AclFrameQue.push(frame); - } + //queue the packet + ACLFrame frame; + frame.ConnectionHandle = _ConnectionHandle; + frame.data = new u8[_Size]; + memcpy(frame.data, _pData, _Size); + frame.size = _Size; + m_AclFrameQue.push(frame); } u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() @@ -243,77 +228,27 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() } #endif - //LOG(WIIMOTE, "Update() %i 0x%08x", - //m_HCICommandMessageQueue.size(), m_pHCIBuffer); - // check state machine - if (m_pHCIBuffer) + //LOG(WIIMOTE, "Update() %i 0x%08x", m_HCICommandMessageQueue.size(), m_pHCIBuffer); + if (!m_EventQueue.empty() && m_pHCIBuffer) { - bool ReturnHCIBuffer = false; - switch(m_State) + // copy the event to memory { - case STATE_NONE: - break; + const SQueuedEvent& rEvent = m_EventQueue.front(); - case STATE_INQUIRY_RESPONSE: - SendEventInquiryResponse(); - m_State = STATE_INQUIRY_COMPLETE; - ReturnHCIBuffer = true; - break; + u8* pHCIEvent = Memory::GetPointer(m_pHCIBuffer->PayloadBuffer[0].m_Address); + memcpy(pHCIEvent, rEvent.m_buffer, rEvent.m_size); - case STATE_INQUIRY_COMPLETE: - SendEventInquiryComplete(); - m_State = STATE_NONE; - ReturnHCIBuffer = true; - break; + // return reply buffer size + Memory::Write_U32(rEvent.m_size, m_pHCIBuffer->m_Address + 0x4); - case STATE_REMOTE_NAME_REQ: - SendEventRemoteNameReq(); - m_State = STATE_NONE; - ReturnHCIBuffer = true; - break; - - case STATE_CONNECTION_COMPLETE_EVENT: - SendEventConnectionComplete(); - m_State = STATE_NONE; - ReturnHCIBuffer = true; - break; - - case STATE_READ_CLOCK_OFFSET: - SendEventReadClockOffsetComplete(); - m_State = STATE_NONE; - ReturnHCIBuffer = true; - break; - - case STATE_READ_REMOTE_VER_INFO: - SendEventReadRemoteVerInfo(); - m_State = STATE_NONE; - ReturnHCIBuffer = true; - break; - - case STATE_READ_REMOTE_FEATURES: - SendEventReadRemoteFeatures(); - m_State = STATE_NONE; - ReturnHCIBuffer = true; - break; - - case STATE_CONNECT_WIIMOTE: - m_WiiMotes[0].Connect(); - m_State = STATE_NONE; - ReturnHCIBuffer = true; - break; - - default: - PanicAlert("Unknown State in USBDev"); - break; + m_EventQueue.pop(); } - if (ReturnHCIBuffer) - { - u32 Addr = m_pHCIBuffer->m_Address; - delete m_pHCIBuffer; - m_pHCIBuffer = NULL; - return Addr; - } + u32 Addr = m_pHCIBuffer->m_Address; + delete m_pHCIBuffer; + m_pHCIBuffer = NULL; + + return Addr; } // HCI control message/event handling @@ -327,51 +262,36 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() u32 Addr = m_pHCIBuffer->m_Address; delete m_pHCIBuffer; m_pHCIBuffer = NULL; + return Addr; } - // check if something is inside the ACL Buffer - if (m_ACLAnswer && m_pACLBuffer) + // check if we can fill the aclbuffer + if(!m_AclFrameQue.empty() && m_pACLBuffer) { - m_ACLAnswer = false; + ACLFrame& frame = m_AclFrameQue.front(); - u32 Addr = m_pACLBuffer->m_Address; - delete m_pACLBuffer; - m_pACLBuffer = NULL; - return Addr; - } + LOG(WIIMOTE, "Sending ACL frame."); + UACLHeader* pHeader = (UACLHeader*)Memory::GetPointer(m_pACLBuffer->PayloadBuffer[0].m_Address); + pHeader->ConnectionHandle = frame.ConnectionHandle; + pHeader->BCFlag = 0; + pHeader->PBFlag = 2; + pHeader->Size = frame.size; - //TODO: remove - if(m_DelayedEvent != EVENT_NONE && m_pHCIBuffer) { - switch(m_DelayedEvent) { - case EVENT_REQUEST_CONNECTION: - SendEventRequestConnection(); - break; - case EVENT_CONNECTION_COMPLETE: - SendEventConnectionComplete(); - break; - default: - PanicAlert("Unknown Event in USBDev: %i", m_DelayedEvent); - } - m_DelayedEvent = EVENT_NONE; + memcpy(Memory::GetPointer(m_pACLBuffer->PayloadBuffer[0].m_Address + sizeof(UACLHeader)), frame.data , frame.size); - u32 Addr = m_pHCIBuffer->m_Address; - delete m_pHCIBuffer; - m_pHCIBuffer = NULL; - return Addr; - } + // return reply buffer size + Memory::Write_U32(sizeof(UACLHeader) + frame.size, m_pACLBuffer->m_Address + 0x4); - if(!m_AclFrameQue.empty() && m_pACLBuffer) { - ACLFrame& frame = m_AclFrameQue.front(); - SendACLFrame(frame.ConnectionHandle, frame.data, - frame.size); delete frame.data; m_AclFrameQue.pop(); - m_ACLAnswer = false; u32 Addr = m_pACLBuffer->m_Address; delete m_pACLBuffer; m_pACLBuffer = NULL; + + // SendEventNumberOfCompletedPackets(frame.ConnectionHandle); + return Addr; } @@ -380,39 +300,54 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() return 0; } +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// +// --- events +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventCommandStatus(u16 _Opcode) { - SHCIEventStatus* pHCIEvent = (SHCIEventStatus*)Memory::GetPointer(m_pHCIBuffer->PayloadBuffer[0].m_Address); + SQueuedEvent Event(sizeof(SHCIEventStatus)); + SHCIEventStatus* pHCIEvent = (SHCIEventStatus*)Event.m_buffer; pHCIEvent->EventType = 0x0F; - pHCIEvent->PayloadLength = 0x4; + pHCIEvent->PayloadLength = sizeof(SHCIEventStatus) - 2; pHCIEvent->Status = 0x0; pHCIEvent->PacketIndicator = 0x01; pHCIEvent->Opcode = _Opcode; - // return reply buffer size - Memory::Write_U32(sizeof(SHCIEventStatus), m_pHCIBuffer->m_Address + 0x4); + AddEventToQueue(Event); + + LOG(WIIMOTE, "Event: Command Status"); + LOG(WIIMOTE, " Opcode: %i", pHCIEvent->Opcode); return true; } void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventCommandComplete(u16 _OpCode, void* _pData, u32 _DataSize) { - SHCIEventCommand* pHCIEvent = (SHCIEventCommand*)Memory::GetPointer(m_pHCIBuffer->PayloadBuffer[0].m_Address); + SQueuedEvent Event(sizeof(SHCIEventCommand) + _DataSize); + + SHCIEventCommand* pHCIEvent = (SHCIEventCommand*)Event.m_buffer; pHCIEvent->EventType = 0x0E; - pHCIEvent->PayloadLength = _DataSize + 0x03; + pHCIEvent->PayloadLength = sizeof(SHCIEventCommand) - 2 + _DataSize; pHCIEvent->PacketIndicator = 0x01; pHCIEvent->Opcode = _OpCode; // add the payload if ((_pData != NULL) && (_DataSize > 0)) { - u8* pPayload = (u8*)Memory::GetPointer(m_pHCIBuffer->PayloadBuffer[0].m_Address + sizeof(SHCIEventCommand)); + u8* pPayload = Event.m_buffer + sizeof(SHCIEventCommand); memcpy(pPayload, _pData, _DataSize); } - // answer with the number of sent bytes - Memory::Write_U32(_DataSize + sizeof(SHCIEventCommand), m_pHCIBuffer->m_Address + 0x4); + AddEventToQueue(Event); + + LOG(WIIMOTE, "Event: Command Complete"); + LOG(WIIMOTE, " Opcode: %i", pHCIEvent->Opcode); } bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventInquiryResponse() @@ -420,16 +355,18 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventInquiryResponse() if (m_WiiMotes.empty()) return false; - SHCIEventInquiryResult* pInquiryResult = (SHCIEventInquiryResult*)Memory::GetPointer(m_pHCIBuffer->PayloadBuffer[0].m_Address); + SQueuedEvent Event(sizeof(SHCIEventInquiryResult) + m_WiiMotes.size()*sizeof(hci_inquiry_response)); + + SHCIEventInquiryResult* pInquiryResult = (SHCIEventInquiryResult*)Event.m_buffer; pInquiryResult->EventType = 0x02; - pInquiryResult->PayloadLength = 1 + m_WiiMotes.size() * sizeof(hci_inquiry_response); + pInquiryResult->PayloadLength = sizeof(SHCIEventInquiryResult) - 2 + (m_WiiMotes.size() * sizeof(hci_inquiry_response)); pInquiryResult->num_responses = m_WiiMotes.size(); for (size_t i=0; iPayloadBuffer[0].m_Address + sizeof(SHCIEventInquiryResult) + i*sizeof(hci_inquiry_response); - hci_inquiry_response* pResponse = (hci_inquiry_response*)Memory::GetPointer(Address); + u8* pBuffer = Event.m_buffer + sizeof(SHCIEventInquiryResult) + i*sizeof(hci_inquiry_response); + hci_inquiry_response* pResponse = (hci_inquiry_response*)pBuffer; pResponse->bdaddr = m_WiiMotes[i].GetBD(); pResponse->uclass[0]= m_WiiMotes[i].GetClass()[0]; @@ -447,49 +384,49 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventInquiryResponse() pResponse->bdaddr.b[3], pResponse->bdaddr.b[4], pResponse->bdaddr.b[5]); } - // return reply buffer size - Memory::Write_U32(sizeof(SHCIEventInquiryResult) + sizeof(hci_inquiry_response), m_pHCIBuffer->m_Address + 0x4); + AddEventToQueue(Event); return true; } bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventInquiryComplete() { - SHCIEventInquiryComplete* pInquiryComplete = (SHCIEventInquiryComplete*)Memory::GetPointer(m_pHCIBuffer->PayloadBuffer[0].m_Address); + SQueuedEvent Event(sizeof(SHCIEventInquiryComplete)); + + SHCIEventInquiryComplete* pInquiryComplete = (SHCIEventInquiryComplete*)Event.m_buffer; pInquiryComplete->EventType = 0x01; - pInquiryComplete->PayloadLength = 0x01; + pInquiryComplete->PayloadLength = sizeof(SHCIEventInquiryComplete) - 2; pInquiryComplete->status = 0x00; - // control message has been sent... - Memory::Write_U32(sizeof(SHCIEventInquiryComplete), m_pHCIBuffer->m_Address + 0x4); + AddEventToQueue(Event); LOG(WIIMOTE, "Event: Inquiry complete"); return true; } -bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRemoteNameReq() +bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRemoteNameReq(bdaddr_t _bd) { - CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(m_StateTempBD); + CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_bd); if (pWiiMote == NULL) { PanicAlert("Cant find WiiMote by bd: %02x:%02x:%02x:%02x:%02x:%02x", - m_StateTempBD.b[0], m_StateTempBD.b[1], m_StateTempBD.b[2], - m_StateTempBD.b[3], m_StateTempBD.b[4], m_StateTempBD.b[5]); + _bd.b[0], _bd.b[1], _bd.b[2], + _bd.b[3], _bd.b[4], _bd.b[5]); return false; } - ClearBD(m_StateTempBD); - SHCIEventRemoteNameReq* pRemoteNameReq = (SHCIEventRemoteNameReq*)Memory::GetPointer(m_pHCIBuffer->PayloadBuffer[0].m_Address); + SQueuedEvent Event(sizeof(SHCIEventRemoteNameReq)); + + SHCIEventRemoteNameReq* pRemoteNameReq = (SHCIEventRemoteNameReq*)Event.m_buffer; pRemoteNameReq->EventType = 0x07; - pRemoteNameReq->PayloadLength = 255; + pRemoteNameReq->PayloadLength = sizeof(SHCIEventRemoteNameReq) - 2; pRemoteNameReq->Status = 0x00; pRemoteNameReq->bdaddr = pWiiMote->GetBD(); strcpy((char*)pRemoteNameReq->RemoteName, pWiiMote->GetName()); - // return reply buffer size - Memory::Write_U32(sizeof(SHCIEventRemoteNameReq), m_pHCIBuffer->m_Address + 0x4); + AddEventToQueue(Event); LOG(WIIMOTE, "Event: SendEventRemoteNameReq"); LOG(WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x", @@ -502,21 +439,31 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRemoteNameReq() bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRequestConnection() { - //PanicAlert("unused"); + const CWII_IPC_HLE_WiiMote rWiiMote = m_WiiMotes[0]; - SHCIEventRequestConnection* pEventRequestConnection = (SHCIEventRequestConnection*)Memory::GetPointer(m_pHCIBuffer->PayloadBuffer[0].m_Address); + SQueuedEvent Event(sizeof(SHCIEventRequestConnection)); + + SHCIEventRequestConnection* pEventRequestConnection = (SHCIEventRequestConnection*)Event.m_buffer; pEventRequestConnection->EventType = 0x04; - pEventRequestConnection->PayloadLength = 13; - - pEventRequestConnection->bdaddr = m_WiiMotes[0].GetBD(); // BD_ADDR of the device that requests the connection - pEventRequestConnection->uclass[0] = 0x04; // thanks to shagkur - pEventRequestConnection->uclass[1] = 0x25; - pEventRequestConnection->uclass[2] = 0x00; + pEventRequestConnection->PayloadLength = sizeof(SHCIEventRequestConnection) - 2; + pEventRequestConnection->bdaddr = rWiiMote.GetBD(); // BD_ADDR of the device that requests the connection + pEventRequestConnection->uclass[0] = rWiiMote.GetClass()[0]; + pEventRequestConnection->uclass[1] = rWiiMote.GetClass()[1]; + pEventRequestConnection->uclass[2] = rWiiMote.GetClass()[2]; pEventRequestConnection->LinkType = 0x01; - // return reply buffer size - Memory::Write_U32(sizeof(SHCIEventRequestConnection), m_pHCIBuffer->m_Address + 0x4); + AddEventToQueue(Event); + + // Log +#ifdef LOGGING + static char LinkType[][128] = + { + { "HCI_LINK_SCO 0x00 - Voice"}, + { "HCI_LINK_ACL 0x01 - Data"}, + { "HCI_LINK_eSCO 0x02 - eSCO"}, + }; +#endif LOG(WIIMOTE, "Event: SendEventRequestConnection"); LOG(WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x", @@ -525,97 +472,142 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRequestConnection() LOG(WIIMOTE, " COD[0]: 0x%02x", pEventRequestConnection->uclass[0]); LOG(WIIMOTE, " COD[1]: 0x%02x", pEventRequestConnection->uclass[1]); LOG(WIIMOTE, " COD[2]: 0x%02x", pEventRequestConnection->uclass[2]); - LOG(WIIMOTE, " LinkType: %i", pEventRequestConnection->LinkType); + LOG(WIIMOTE, " LinkType: %s", LinkType[pEventRequestConnection->LinkType]); return true; }; -bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventConnectionComplete() +bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventConnectionComplete(bdaddr_t _bd) { - CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(m_StateTempBD); + CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_bd); if (pWiiMote == NULL) { PanicAlert("Cant find WiiMote by bd: %02x:%02x:%02x:%02x:%02x:%02x", - m_StateTempBD.b[0], m_StateTempBD.b[1], m_StateTempBD.b[2], - m_StateTempBD.b[3], m_StateTempBD.b[4], m_StateTempBD.b[5]); + _bd.b[0], _bd.b[1], _bd.b[2], + _bd.b[3], _bd.b[4], _bd.b[5]); return false; } - ClearBD(m_StateTempBD); - SHCIEventConnectionComplete* pConnectionComplete = (SHCIEventConnectionComplete*)Memory::GetPointer(m_pHCIBuffer->PayloadBuffer[0].m_Address); + SQueuedEvent Event(sizeof(SHCIEventConnectionComplete)); + + SHCIEventConnectionComplete* pConnectionComplete = (SHCIEventConnectionComplete*)Event.m_buffer; pConnectionComplete->EventType = 0x03; - pConnectionComplete->PayloadLength = 13; + pConnectionComplete->PayloadLength = sizeof(SHCIEventConnectionComplete) - 2; pConnectionComplete->Status = 0x00; pConnectionComplete->Connection_Handle = pWiiMote->GetConnectionHandle(); pConnectionComplete->bdaddr = pWiiMote->GetBD(); pConnectionComplete->LinkType = 0x01; // ACL pConnectionComplete->EncryptionEnabled = 0x00; - // return reply buffer size - Memory::Write_U32(sizeof(SHCIEventConnectionComplete), m_pHCIBuffer->m_Address + 0x4); + AddEventToQueue(Event); + +#ifdef LOGGING + static char s_szLinkType[][128] = + { + { "HCI_LINK_SCO 0x00 - Voice"}, + { "HCI_LINK_ACL 0x01 - Data"}, + { "HCI_LINK_eSCO 0x02 - eSCO"}, + }; +#endif LOG(WIIMOTE, "Event: SendEventConnectionComplete"); LOG(WIIMOTE, " Connection_Handle: 0x%04x", pConnectionComplete->Connection_Handle); LOG(WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x", pConnectionComplete->bdaddr.b[0], pConnectionComplete->bdaddr.b[1], pConnectionComplete->bdaddr.b[2], pConnectionComplete->bdaddr.b[3], pConnectionComplete->bdaddr.b[4], pConnectionComplete->bdaddr.b[5]); - LOG(WIIMOTE, " LinkType: %i", pConnectionComplete->LinkType); + LOG(WIIMOTE, " LinkType: %s", s_szLinkType[pConnectionComplete->LinkType]); LOG(WIIMOTE, " EncryptionEnabled: %i", pConnectionComplete->EncryptionEnabled); return true; } -bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventReadClockOffsetComplete() -{ - CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(m_StateTempConnectionHandle); +bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRoleChange(bdaddr_t _bd) +{ + CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_bd); if (pWiiMote == NULL) { - PanicAlert("Cant find WiiMote by connection handle: %02x", m_StateTempConnectionHandle); + PanicAlert("Cant find WiiMote by bd: %02x:%02x:%02x:%02x:%02x:%02x", + _bd.b[0], _bd.b[1], _bd.b[2], + _bd.b[3], _bd.b[4], _bd.b[5]); return false; } - m_StateTempConnectionHandle = 0; - SHCIEventReadClockOffsetComplete* pReadClockOffsetComplete = (SHCIEventReadClockOffsetComplete*)Memory::GetPointer(m_pHCIBuffer->PayloadBuffer[0].m_Address); + SQueuedEvent Event(sizeof(SHCIEventRoleChange)); + + SHCIEventRoleChange* pRoleChange = (SHCIEventRoleChange*)Event.m_buffer; + + pRoleChange->EventType = 0x03; + pRoleChange->PayloadLength = sizeof(SHCIEventRoleChange) - 2; + pRoleChange->Status = 0x00; + pRoleChange->bdaddr = pWiiMote->GetBD(); + pRoleChange->NewRole = 0x00; + + AddEventToQueue(Event); + + LOG(WIIMOTE, "Event: SendEventRoleChange"); + LOG(WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x", + pRoleChange->bdaddr.b[0], pRoleChange->bdaddr.b[1], pRoleChange->bdaddr.b[2], + pRoleChange->bdaddr.b[3], pRoleChange->bdaddr.b[4], pRoleChange->bdaddr.b[5]); + LOG(WIIMOTE, " NewRole: %i", pRoleChange->NewRole); + + return true; +} + + + +bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventReadClockOffsetComplete(u16 _connectionHandle) +{ + CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_connectionHandle); + if (pWiiMote == NULL) + { + PanicAlert("Cant find WiiMote by connection handle: %02x", _connectionHandle); + return false; + } + + SQueuedEvent Event(sizeof(SHCIEventReadClockOffsetComplete)); + + SHCIEventReadClockOffsetComplete* pReadClockOffsetComplete = (SHCIEventReadClockOffsetComplete*)Event.m_buffer; pReadClockOffsetComplete->EventType = 0x1C; - pReadClockOffsetComplete->PayloadLength = 0x05; + pReadClockOffsetComplete->PayloadLength = sizeof(SHCIEventReadClockOffsetComplete) - 2; pReadClockOffsetComplete->status = 0x00; pReadClockOffsetComplete->ConnectionHandle = pWiiMote->GetConnectionHandle(); pReadClockOffsetComplete->ClockOffset = 0x3818; - // return reply buffer size - Memory::Write_U32(sizeof(SHCIEventReadClockOffsetComplete), m_pHCIBuffer->m_Address + 0x4); + AddEventToQueue(Event); - LOG(WIIMOTE, "Event: SendEventConnectionComplete"); + // Log + LOG(WIIMOTE, "Event: SendEventReadClockOffsetComplete"); LOG(WIIMOTE, " Connection_Handle: 0x%04x", pReadClockOffsetComplete->ConnectionHandle); LOG(WIIMOTE, " ClockOffset: 0x%04x", pReadClockOffsetComplete->ClockOffset); return true; } -bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventReadRemoteVerInfo() +bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventReadRemoteVerInfo(u16 _connectionHandle) { - CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(m_StateTempConnectionHandle); + CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_connectionHandle); if (pWiiMote == NULL) { - PanicAlert("Cant find WiiMote by connection handle: %02x", m_StateTempConnectionHandle); + PanicAlert("Cant find WiiMote by connection handle: %02x", _connectionHandle); return false; } - m_StateTempConnectionHandle = 0; - SHCIEventReadRemoteVerInfo* pReadRemoteVerInfo = (SHCIEventReadRemoteVerInfo*)Memory::GetPointer(m_pHCIBuffer->PayloadBuffer[0].m_Address); + SQueuedEvent Event(sizeof(SHCIEventReadRemoteVerInfo)); + + SHCIEventReadRemoteVerInfo* pReadRemoteVerInfo = (SHCIEventReadRemoteVerInfo*)Event.m_buffer; pReadRemoteVerInfo->EventType = 0x0C; - pReadRemoteVerInfo->PayloadLength = 0x05; + pReadRemoteVerInfo->PayloadLength = sizeof(SHCIEventReadRemoteVerInfo) - 2; pReadRemoteVerInfo->status = 0x00; pReadRemoteVerInfo->ConnectionHandle = pWiiMote->GetConnectionHandle(); - pReadRemoteVerInfo->lmp_version = 0x2; - pReadRemoteVerInfo->manufacturer = 0x000F; - pReadRemoteVerInfo->lmp_subversion = 0x229; + pReadRemoteVerInfo->lmp_version = pWiiMote->GetLMPVersion(); + pReadRemoteVerInfo->manufacturer = pWiiMote->GetManufactorID(); + pReadRemoteVerInfo->lmp_subversion = pWiiMote->GetLMPSubVersion(); - // control message has been sent... - Memory::Write_U32(sizeof(SHCIEventReadRemoteVerInfo), m_pHCIBuffer->m_Address + 0x4); + AddEventToQueue(Event); - LOG(WIIMOTE, "Event: SendEventReadReadRemoteVerInfo"); + // Log + LOG(WIIMOTE, "Event: SendEventReadRemoteVerInfo"); LOG(WIIMOTE, " Connection_Handle: 0x%04x", pReadRemoteVerInfo->ConnectionHandle); LOG(WIIMOTE, " lmp_version: 0x%02x", pReadRemoteVerInfo->lmp_version); LOG(WIIMOTE, " manufacturer: 0x%04x", pReadRemoteVerInfo->manufacturer); @@ -624,19 +616,20 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventReadRemoteVerInfo() return true; } -bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventReadRemoteFeatures() +bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventReadRemoteFeatures(u16 _connectionHandle) { - CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(m_StateTempConnectionHandle); + CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_connectionHandle); if (pWiiMote == NULL) { - PanicAlert("Cant find WiiMote by connection handle: %02x", m_StateTempConnectionHandle); + PanicAlert("Cant find WiiMote by connection handle: %02x", _connectionHandle); return false; } - m_StateTempConnectionHandle = 0; - SHCIEventReadRemoteFeatures* pReadRemoteFeatures = (SHCIEventReadRemoteFeatures*)Memory::GetPointer(m_pHCIBuffer->PayloadBuffer[0].m_Address); + SQueuedEvent Event(sizeof(SHCIEventReadRemoteFeatures)); + + SHCIEventReadRemoteFeatures* pReadRemoteFeatures = (SHCIEventReadRemoteFeatures*)Event.m_buffer; pReadRemoteFeatures->EventType = 0x0C; - pReadRemoteFeatures->PayloadLength = 11; + pReadRemoteFeatures->PayloadLength = sizeof(SHCIEventReadRemoteFeatures) - 2; pReadRemoteFeatures->status = 0x00; pReadRemoteFeatures->ConnectionHandle = pWiiMote->GetConnectionHandle(); pReadRemoteFeatures->features[0] = pWiiMote->GetFeatures()[0]; @@ -648,10 +641,10 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventReadRemoteFeatures() pReadRemoteFeatures->features[6] = pWiiMote->GetFeatures()[6]; pReadRemoteFeatures->features[7] = pWiiMote->GetFeatures()[7]; - // control message has been sent... - Memory::Write_U32(sizeof(SHCIEventReadRemoteFeatures), m_pHCIBuffer->m_Address + 0x4); + AddEventToQueue(Event); - LOG(WIIMOTE, "Event: SendEventReadReadRemoteVerInfo"); + // Log + LOG(WIIMOTE, "Event: SendEventReadRemoteFeatures"); LOG(WIIMOTE, " Connection_Handle: 0x%04x", pReadRemoteFeatures->ConnectionHandle); LOG(WIIMOTE, " features: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", pReadRemoteFeatures->features[0], pReadRemoteFeatures->features[1], pReadRemoteFeatures->features[2], @@ -661,14 +654,48 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventReadRemoteFeatures() return true; } +bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventNumberOfCompletedPackets(u16 _connectionHandle) +{ + CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_connectionHandle); + if (pWiiMote == NULL) + { + PanicAlert("Cant find WiiMote by connection handle: %02x", _connectionHandle); + return false; + } + SQueuedEvent Event(sizeof(SHCIEventNumberOfCompletedPackets)); + + SHCIEventNumberOfCompletedPackets* pNumberOfCompletedPackets = (SHCIEventNumberOfCompletedPackets*)Event.m_buffer; + pNumberOfCompletedPackets->EventType = 0x13; + pNumberOfCompletedPackets->PayloadLength = sizeof(SHCIEventReadRemoteFeatures) - 2; + pNumberOfCompletedPackets->value = 1; + pNumberOfCompletedPackets->Connection_Handle = _connectionHandle; + pNumberOfCompletedPackets->Number_Of_Completed_Packets = 1; + + AddEventToQueue(Event); + + // Log + LOG(WIIMOTE, "Event: SendEventNumberOfCompletedPackets"); + LOG(WIIMOTE, " Connection_Handle: 0x%04x", pNumberOfCompletedPackets->Connection_Handle); + LOG(WIIMOTE, " Number_Of_Completed_Packets: %i", pNumberOfCompletedPackets->Number_Of_Completed_Packets); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// +// --- command dispacther +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////// void CWII_IPC_HLE_Device_usb_oh1_57e_305::ExecuteHCICommandMessage(const SHCICommandMessage& _rHCICommandMessage) { u8* pInput = Memory::GetPointer(_rHCICommandMessage.m_PayLoadAddr + 3); SCommandMessage* pMsg = (SCommandMessage*)Memory::GetPointer(_rHCICommandMessage.m_PayLoadAddr); - LOG(WIIMOTE, "ExecuteHCICommandMessage(0x%04x)", pMsg->Opcode); + // LOG(WIIMOTE, "ExecuteHCICommandMessage(0x%04x)", pMsg->Opcode); switch(pMsg->Opcode) { @@ -803,15 +830,23 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::ExecuteHCICommandMessage(const SHCICom } } +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// +// --- command helper +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReset(u8* _Input) { // reply hci_status_rp Reply; Reply.status = 0x00; - SendEventCommandComplete(HCI_CMD_RESET, &Reply, sizeof(hci_status_rp)); - LOG(WIIMOTE, "Command: HCI_CMD_RESET"); + + SendEventCommandComplete(HCI_CMD_RESET, &Reply, sizeof(hci_status_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadBufferSize(u8* _Input) @@ -824,14 +859,14 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadBufferSize(u8* _Input) Reply.max_sco_size = 64; Reply.num_sco_pkts = 0; - SendEventCommandComplete(HCI_CMD_READ_BUFFER_SIZE, &Reply, sizeof(hci_read_buffer_size_rp)); - LOG(WIIMOTE, "Command: HCI_CMD_READ_BUFFER_SIZE:"); LOG(WIIMOTE, "return:"); LOG(WIIMOTE, " max_acl_size: %i", Reply.max_acl_size); LOG(WIIMOTE, " num_acl_pkts: %i", Reply.num_acl_pkts); LOG(WIIMOTE, " max_sco_size: %i", Reply.max_sco_size); LOG(WIIMOTE, " num_sco_pkts: %i", Reply.num_sco_pkts); + + SendEventCommandComplete(HCI_CMD_READ_BUFFER_SIZE, &Reply, sizeof(hci_read_buffer_size_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadLocalVer(u8* _Input) @@ -845,8 +880,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadLocalVer(u8* _Input) Reply.manufacturer = 0x000F; // manufacturer: reserved for tests Reply.lmp_subversion = 0x430e; // LMP subversion - SendEventCommandComplete(HCI_CMD_READ_LOCAL_VER, &Reply, sizeof(hci_read_local_ver_rp)); - LOG(WIIMOTE, "Command: HCI_CMD_READ_LOCAL_VER:"); LOG(WIIMOTE, "return:"); LOG(WIIMOTE, " status: %i", Reply.status); @@ -854,6 +887,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadLocalVer(u8* _Input) LOG(WIIMOTE, " lmp_version: %i", Reply.lmp_version); LOG(WIIMOTE, " manufacturer: %i", Reply.manufacturer); LOG(WIIMOTE, " lmp_subversion: %i", Reply.lmp_subversion); + + SendEventCommandComplete(HCI_CMD_READ_LOCAL_VER, &Reply, sizeof(hci_read_local_ver_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadBDAdrr(u8* _Input) @@ -863,13 +898,13 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadBDAdrr(u8* _Input) Reply.status = 0x00; Reply.bdaddr = m_ControllerBD; - SendEventCommandComplete(HCI_CMD_READ_BDADDR, &Reply, sizeof(hci_read_bdaddr_rp)); - LOG(WIIMOTE, "Command: HCI_CMD_READ_BDADDR:"); LOG(WIIMOTE, "return:"); LOG(WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x", Reply.bdaddr.b[0], Reply.bdaddr.b[1], Reply.bdaddr.b[2], Reply.bdaddr.b[3], Reply.bdaddr.b[4], Reply.bdaddr.b[5]); + + SendEventCommandComplete(HCI_CMD_READ_BDADDR, &Reply, sizeof(hci_read_bdaddr_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadLocalFeatures(u8* _Input) @@ -886,14 +921,14 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadLocalFeatures(u8* _Input) Reply.features[6] = 0x00; Reply.features[7] = 0x80; - SendEventCommandComplete(HCI_CMD_READ_LOCAL_FEATURES, &Reply, sizeof(hci_read_local_features_rp)); - LOG(WIIMOTE, "Command: HCI_CMD_READ_LOCAL_FEATURES:"); LOG(WIIMOTE, "return:"); LOG(WIIMOTE, " features: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", Reply.features[0], Reply.features[1], Reply.features[2], Reply.features[3], Reply.features[4], Reply.features[5], Reply.features[6], Reply.features[7]); + + SendEventCommandComplete(HCI_CMD_READ_LOCAL_FEATURES, &Reply, sizeof(hci_read_local_features_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadStoredLinkKey(u8* _Input) @@ -906,8 +941,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadStoredLinkKey(u8* _Input) hci_read_stored_link_key_rp Reply; Reply.status = 0x00; - SendEventCommandComplete(HCI_CMD_READ_STORED_LINK_KEY, &Reply, sizeof(hci_read_stored_link_key_rp)); - LOG(WIIMOTE, "Command: HCI_CMD_READ_STORED_LINK_KEY:"); LOG(WIIMOTE, "input:"); LOG(WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x", @@ -916,6 +949,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadStoredLinkKey(u8* _Input) LOG(WIIMOTE, " read_all_ %i", ReadStoredLinkKey->read_all); LOG(WIIMOTE, "return:"); LOG(WIIMOTE, " no idea what i should answer :)"); + + SendEventCommandComplete(HCI_CMD_READ_STORED_LINK_KEY, &Reply, sizeof(hci_read_stored_link_key_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteUnitClass(u8* _Input) @@ -930,13 +965,13 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteUnitClass(u8* _Input) hci_write_unit_class_rp Reply; Reply.status = 0x00; - SendEventCommandComplete(HCI_CMD_WRITE_UNIT_CLASS, &Reply, sizeof(hci_write_unit_class_rp)); - LOG(WIIMOTE, "Command: HCI_CMD_WRITE_UNIT_CLASS:"); LOG(WIIMOTE, "write:"); LOG(WIIMOTE, " COD[0]: 0x%02x", pWriteUnitClass->uclass[0]); LOG(WIIMOTE, " COD[1]: 0x%02x", pWriteUnitClass->uclass[1]); LOG(WIIMOTE, " COD[2]: 0x%02x", pWriteUnitClass->uclass[2]); + + SendEventCommandComplete(HCI_CMD_WRITE_UNIT_CLASS, &Reply, sizeof(hci_write_unit_class_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteLocalName(u8* _Input) @@ -949,11 +984,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteLocalName(u8* _Input) hci_write_local_name_rp Reply; Reply.status = 0x00; - SendEventCommandComplete(HCI_CMD_WRITE_LOCAL_NAME, &Reply, sizeof(hci_write_local_name_rp)); - LOG(WIIMOTE, "Command: HCI_CMD_WRITE_LOCAL_NAME:"); LOG(WIIMOTE, "write:"); LOG(WIIMOTE, " local_name: %s", pWriteLocalName->name); + + SendEventCommandComplete(HCI_CMD_WRITE_LOCAL_NAME, &Reply, sizeof(hci_write_local_name_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWritePinType(u8* _Input) @@ -966,11 +1001,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWritePinType(u8* _Input) hci_write_pin_type_rp Reply; Reply.status = 0x00; - SendEventCommandComplete(HCI_CMD_WRITE_PIN_TYPE, &Reply, sizeof(hci_write_pin_type_rp)); - LOG(WIIMOTE, "Command: HCI_CMD_WRITE_PIN_TYPE:"); LOG(WIIMOTE, "write:"); LOG(WIIMOTE, " pin_type: %x", pWritePinType->pin_type); + + SendEventCommandComplete(HCI_CMD_WRITE_PIN_TYPE, &Reply, sizeof(hci_write_pin_type_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandHostBufferSize(u8* _Input) @@ -986,14 +1021,14 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandHostBufferSize(u8* _Input) hci_host_buffer_size_rp Reply; Reply.status = 0x00; - SendEventCommandComplete(HCI_CMD_HOST_BUFFER_SIZE, &Reply, sizeof(hci_host_buffer_size_rp)); - LOG(WIIMOTE, "Command: HCI_CMD_HOST_BUFFER_SIZE:"); LOG(WIIMOTE, "write:"); LOG(WIIMOTE, " max_acl_size: %i", pHostBufferSize->max_acl_size); LOG(WIIMOTE, " max_sco_size: %i", pHostBufferSize->max_sco_size); LOG(WIIMOTE, " num_acl_pkts: %i", pHostBufferSize->num_acl_pkts); LOG(WIIMOTE, " num_sco_pkts: %i", pHostBufferSize->num_sco_pkts); + + SendEventCommandComplete(HCI_CMD_HOST_BUFFER_SIZE, &Reply, sizeof(hci_host_buffer_size_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWritePageTimeOut(u8* _Input) @@ -1007,11 +1042,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWritePageTimeOut(u8* _Input) hci_host_buffer_size_rp Reply; Reply.status = 0x00; - SendEventCommandComplete(HCI_CMD_WRITE_PAGE_TIMEOUT, &Reply, sizeof(hci_host_buffer_size_rp)); - LOG(WIIMOTE, "Command: HCI_CMD_WRITE_PAGE_TIMEOUT:"); LOG(WIIMOTE, "write:"); LOG(WIIMOTE, " timeout: %i", pWritePageTimeOut->timeout); + + SendEventCommandComplete(HCI_CMD_WRITE_PAGE_TIMEOUT, &Reply, sizeof(hci_host_buffer_size_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteScanEnable(u8* _Input) @@ -1024,8 +1059,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteScanEnable(u8* _Input) hci_write_scan_enable_rp Reply; Reply.status = 0x00; - SendEventCommandComplete(HCI_CMD_WRITE_SCAN_ENABLE, &Reply, sizeof(hci_write_scan_enable_rp)); - #ifdef LOGGING static char Scanning[][128] = { @@ -1040,7 +1073,19 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteScanEnable(u8* _Input) LOG(WIIMOTE, "write:"); LOG(WIIMOTE, " scan_enable: %s", Scanning[pWriteScanEnable->scan_enable]); - SetDelayedEvent(EVENT_REQUEST_CONNECTION); + SendEventCommandComplete(HCI_CMD_WRITE_SCAN_ENABLE, &Reply, sizeof(hci_write_scan_enable_rp)); + + // TODO: fix this ugly request connection hack :) + // for homebrew works this + if (pWriteScanEnable->scan_enable & 2) // check if page scan is enable + { + static bool first = true; + if (first) + { + first = false; + SendEventRequestConnection(); + } + } } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteInquiryMode(u8* _Input) @@ -1054,8 +1099,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteInquiryMode(u8* _Input) hci_write_inquiry_mode_rp Reply; Reply.status = 0x00; - SendEventCommandComplete(HCI_CMD_WRITE_INQUIRY_MODE, &Reply, sizeof(hci_write_inquiry_mode_rp)); - #ifdef LOGGING static char InquiryMode[][128] = { @@ -1067,6 +1110,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteInquiryMode(u8* _Input) LOG(WIIMOTE, "Command: HCI_CMD_WRITE_INQUIRY_MODE:"); LOG(WIIMOTE, "write:"); LOG(WIIMOTE, " mode: %s", InquiryMode[pInquiryMode->mode]); + + SendEventCommandComplete(HCI_CMD_WRITE_INQUIRY_MODE, &Reply, sizeof(hci_write_inquiry_mode_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWritePageScanType(u8* _Input) @@ -1080,8 +1125,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWritePageScanType(u8* _Input) hci_write_page_scan_type_rp Reply; Reply.status = 0x00; - SendEventCommandComplete(HCI_CMD_WRITE_PAGE_SCAN_TYPE, &Reply, sizeof(hci_write_page_scan_type_rp)); - #ifdef LOGGING static char PageScanType[][128] = { @@ -1093,6 +1136,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWritePageScanType(u8* _Input) LOG(WIIMOTE, "Command: HCI_CMD_WRITE_PAGE_SCAN_TYPE:"); LOG(WIIMOTE, "write:"); LOG(WIIMOTE, " type: %s", PageScanType[pWritePageScanType->type]); + + SendEventCommandComplete(HCI_CMD_WRITE_PAGE_SCAN_TYPE, &Reply, sizeof(hci_write_page_scan_type_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandSetEventFilter(u8* _Input) @@ -1106,12 +1151,12 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandSetEventFilter(u8* _Input) hci_set_event_filter_rp Reply; Reply.status = 0x00; - SendEventCommandComplete(HCI_CMD_SET_EVENT_FILTER, &Reply, sizeof(hci_set_event_filter_rp)); - LOG(WIIMOTE, "Command: HCI_CMD_SET_EVENT_FILTER:"); LOG(WIIMOTE, "write:"); LOG(WIIMOTE, " filter_type: %i", pSetEventFilter->filter_type); LOG(WIIMOTE, " filter_condition_type: %i", pSetEventFilter->filter_condition_type); + + SendEventCommandComplete(HCI_CMD_SET_EVENT_FILTER, &Reply, sizeof(hci_set_event_filter_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandInquiry(u8* _Input) @@ -1122,17 +1167,16 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandInquiry(u8* _Input) memcpy(lap, pInquiry->lap, HCI_LAP_SIZE); - _dbg_assert_msg_(WIIMOTE, m_State == STATE_NONE, "m_State != NONE"); - m_State = STATE_INQUIRY_RESPONSE; - SendEventCommandStatus(HCI_CMD_INQUIRY); - LOG(WIIMOTE, "Command: HCI_CMD_INQUIRY:"); LOG(WIIMOTE, "write:"); LOG(WIIMOTE, " LAP[0]: 0x%02x", pInquiry->lap[0]); LOG(WIIMOTE, " LAP[1]: 0x%02x", pInquiry->lap[1]); LOG(WIIMOTE, " LAP[2]: 0x%02x", pInquiry->lap[2]); LOG(WIIMOTE, " inquiry_length: %i (N x 1.28) sec", pInquiry->inquiry_length); - LOG(WIIMOTE, " num_responses: %i (N x 1.28) sec", pInquiry->num_responses); + LOG(WIIMOTE, " num_responses: %i (N x 1.28) sec", pInquiry->num_responses); + + SendEventCommandStatus(HCI_CMD_INQUIRY); + SendEventInquiryResponse(); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteInquiryScanType(u8* _Input) @@ -1145,11 +1189,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteInquiryScanType(u8* _Input hci_write_inquiry_scan_type_rp Reply; Reply.status = 0x00; - SendEventCommandComplete(HCI_CMD_WRITE_INQUIRY_SCAN_TYPE, &Reply, sizeof(hci_write_inquiry_scan_type_rp)); - LOG(WIIMOTE, "Command: HCI_CMD_WRITE_INQUIRY_SCAN_TYPE:"); LOG(WIIMOTE, "write:"); LOG(WIIMOTE, " type: %i", pSetEventFilter->type); + + SendEventCommandComplete(HCI_CMD_WRITE_INQUIRY_SCAN_TYPE, &Reply, sizeof(hci_write_inquiry_scan_type_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandVendorSpecific_FC4F(u8* _Input, u32 _Size) @@ -1165,14 +1209,14 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandVendorSpecific_FC4F(u8* _Input, hci_status_rp Reply; Reply.status = 0x00; - SendEventCommandComplete(0xFC4F, &Reply, sizeof(hci_status_rp)); - LOG(WIIMOTE, "Command: CommandVendorSpecific_FC4F:"); LOG(WIIMOTE, "input (size 0x%x):", _Size); for (u32 i=0; i<_Size; i++) LOG(WIIMOTE, " Data: 0x%02x", _Input[i]); LOG(WIIMOTE, "write:"); LOG(WIIMOTE, " callstack WUDiRemovePatch"); + + SendEventCommandComplete(0xFC4F, &Reply, sizeof(hci_status_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandVendorSpecific_FC4C(u8* _Input, u32 _Size) @@ -1181,14 +1225,14 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandVendorSpecific_FC4C(u8* _Input, hci_status_rp Reply; Reply.status = 0x00; - SendEventCommandComplete(0xFC4C, &Reply, sizeof(hci_status_rp)); - LOG(WIIMOTE, "Command: CommandVendorSpecific_FC4C:"); LOG(WIIMOTE, "input (size 0x%x):", _Size); for (u32 i=0; i<_Size; i++) LOG(WIIMOTE, " Data: 0x%02x", _Input[i]); LOG(WIIMOTE, "write:"); LOG(WIIMOTE, " perhaps append patch?"); + + SendEventCommandComplete(0xFC4C, &Reply, sizeof(hci_status_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandInquiryCancel(u8* _Input) @@ -1197,9 +1241,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandInquiryCancel(u8* _Input) hci_inquiry_cancel_rp Reply; Reply.status = 0x00; - SendEventCommandComplete(HCI_CMD_INQUIRY_CANCEL, &Reply, sizeof(hci_inquiry_cancel_rp)); - LOG(WIIMOTE, "Command: HCI_CMD_INQUIRY_CANCEL"); + + SendEventCommandComplete(HCI_CMD_INQUIRY_CANCEL, &Reply, sizeof(hci_inquiry_cancel_rp)); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandRemoteNameReq(u8* _Input) @@ -1207,11 +1251,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandRemoteNameReq(u8* _Input) // command parameters hci_remote_name_req_cp* pRemoteNameReq = (hci_remote_name_req_cp*)_Input; - _dbg_assert_msg_(WIIMOTE, m_State == STATE_NONE, "m_State != NONE"); - SendEventCommandStatus(HCI_CMD_REMOTE_NAME_REQ); - m_StateTempBD = pRemoteNameReq->bdaddr; - m_State = STATE_REMOTE_NAME_REQ; - LOG(WIIMOTE, "Command: HCI_CMD_REMOTE_NAME_REQ"); LOG(WIIMOTE, "Input:"); LOG(WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x", @@ -1219,7 +1258,10 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandRemoteNameReq(u8* _Input) pRemoteNameReq->bdaddr.b[3], pRemoteNameReq->bdaddr.b[4], pRemoteNameReq->bdaddr.b[5]); LOG(WIIMOTE, " page_scan_rep_mode: %i", pRemoteNameReq->page_scan_rep_mode); LOG(WIIMOTE, " page_scan_mode: %i", pRemoteNameReq->page_scan_mode); - LOG(WIIMOTE, " clock_offset: %i", pRemoteNameReq->clock_offset) + LOG(WIIMOTE, " clock_offset: %i", pRemoteNameReq->clock_offset); + + SendEventCommandStatus(HCI_CMD_REMOTE_NAME_REQ); + SendEventRemoteNameReq(pRemoteNameReq->bdaddr); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandCreateCon(u8* _Input) @@ -1227,11 +1269,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandCreateCon(u8* _Input) // command parameters hci_create_con_cp* pCreateCon = (hci_create_con_cp*)_Input; - _dbg_assert_msg_(WIIMOTE, m_State == STATE_NONE, "m_State != NONE"); - m_State = STATE_CONNECTION_COMPLETE_EVENT; - m_StateTempBD = pCreateCon->bdaddr; - SendEventCommandStatus(HCI_CMD_CREATE_CON); - LOG(WIIMOTE, "Command: HCI_CMD_CREATE_CON"); LOG(WIIMOTE, "Input:"); LOG(WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x", @@ -1243,6 +1280,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandCreateCon(u8* _Input) LOG(WIIMOTE, " page_scan_mode: %i", pCreateCon->page_scan_mode); LOG(WIIMOTE, " clock_offset: %i", pCreateCon->clock_offset); LOG(WIIMOTE, " accept_role_switch: %i", pCreateCon->accept_role_switch); + + SendEventCommandStatus(HCI_CMD_CREATE_CON); + SendEventConnectionComplete(pCreateCon->bdaddr); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandAcceptCon(u8* _Input) @@ -1250,25 +1290,23 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandAcceptCon(u8* _Input) // command parameters hci_accept_con_cp* pAcceptCon = (hci_accept_con_cp*)_Input; - _dbg_assert_msg_(WIIMOTE, m_State == STATE_NONE, "m_State != NONE"); - m_State = STATE_CONNECTION_COMPLETE_EVENT; - m_StateTempBD = pAcceptCon->bdaddr; - SendEventCommandStatus(HCI_CMD_ACCEPT_CON); +#ifdef LOGGING + static char s_szRole[][128] = + { + { "Master (0x00)"}, + { "Slave (0x01)"}, + }; +#endif LOG(WIIMOTE, "Command: HCI_CMD_ACCEPT_CON"); LOG(WIIMOTE, "Input:"); - LOG(WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x", + LOG(WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x", pAcceptCon->bdaddr.b[0], pAcceptCon->bdaddr.b[1], pAcceptCon->bdaddr.b[2], pAcceptCon->bdaddr.b[3], pAcceptCon->bdaddr.b[4], pAcceptCon->bdaddr.b[5]); - LOG(WIIMOTE, " role: %i", pAcceptCon->role); -} + LOG(WIIMOTE, " role: %s", s_szRole[pAcceptCon->role]); -void CWII_IPC_HLE_Device_usb_oh1_57e_305::SetDelayedEvent(EDelayedEvent e) -{ - if(m_DelayedEvent != EVENT_NONE) { - PanicAlert("WIIMOTE: Double delayed events!"); - } - m_DelayedEvent = e; + SendEventCommandStatus(HCI_CMD_ACCEPT_CON); + SendEventConnectionComplete(pAcceptCon->bdaddr); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadClockOffset(u8* _Input) @@ -1276,14 +1314,12 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadClockOffset(u8* _Input) // command parameters hci_read_clock_offset_cp* pReadClockOffset = (hci_read_clock_offset_cp*)_Input; - _dbg_assert_msg_(WIIMOTE, m_State == STATE_NONE, "m_State != NONE"); - m_State = STATE_READ_CLOCK_OFFSET; - m_StateTempConnectionHandle = pReadClockOffset->con_handle; - SendEventCommandStatus(HCI_CMD_READ_CLOCK_OFFSET); - LOG(WIIMOTE, "Command: HCI_CMD_READ_CLOCK_OFFSET"); LOG(WIIMOTE, "Input:"); LOG(WIIMOTE, " ConnectionHandle: 0x%02x", pReadClockOffset->con_handle); + + SendEventCommandStatus(HCI_CMD_READ_CLOCK_OFFSET); + SendEventReadClockOffsetComplete(pReadClockOffset->con_handle); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadRemoteVerInfo(u8* _Input) @@ -1291,14 +1327,12 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadRemoteVerInfo(u8* _Input) // command parameters hci_read_remote_ver_info_cp* pReadRemoteVerInfo = (hci_read_remote_ver_info_cp*)_Input; - _dbg_assert_msg_(WIIMOTE, m_State == STATE_NONE, "m_State != NONE (%i)", m_State); - m_State = STATE_READ_REMOTE_VER_INFO; - m_StateTempConnectionHandle = pReadRemoteVerInfo->con_handle; - SendEventCommandStatus(HCI_CMD_READ_REMOTE_VER_INFO); - LOG(WIIMOTE, "Command: HCI_CMD_READ_REMOTE_VER_INFO"); LOG(WIIMOTE, "Input:"); LOG(WIIMOTE, " ConnectionHandle: 0x%02x", pReadRemoteVerInfo->con_handle); + + SendEventCommandStatus(HCI_CMD_READ_REMOTE_VER_INFO); + SendEventReadRemoteVerInfo(pReadRemoteVerInfo->con_handle); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadRemoteFeatures(u8* _Input) @@ -1306,14 +1340,12 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadRemoteFeatures(u8* _Input) // command parameters hci_read_remote_features_cp* pReadRemoteFeatures = (hci_read_remote_features_cp*)_Input; - _dbg_assert_msg_(WIIMOTE, m_State == STATE_NONE, "m_State != NONE"); - m_State = STATE_READ_REMOTE_FEATURES; - m_StateTempConnectionHandle = pReadRemoteFeatures->con_handle; - SendEventCommandStatus(HCI_CMD_READ_REMOTE_FEATURES); - LOG(WIIMOTE, "Command: HCI_CMD_READ_REMOTE_FEATURES"); LOG(WIIMOTE, "Input:"); LOG(WIIMOTE, " ConnectionHandle: 0x%04x", pReadRemoteFeatures->con_handle); + + SendEventCommandStatus(HCI_CMD_READ_REMOTE_FEATURES); + SendEventReadRemoteFeatures(pReadRemoteFeatures->con_handle); } void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteLinkPolicy(u8* _Input) @@ -1321,17 +1353,27 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteLinkPolicy(u8* _Input) // command parameters hci_write_link_policy_settings_cp* pLinkPolicy = (hci_write_link_policy_settings_cp*)_Input; - _dbg_assert_msg_(WIIMOTE, m_State == STATE_NONE, "m_State != NONE"); - m_State = STATE_CONNECT_WIIMOTE; - m_StateTempConnectionHandle = pLinkPolicy->con_handle; - SendEventCommandStatus(HCI_CMD_WRITE_LINK_POLICY_SETTINGS); - LOG(WIIMOTE, "Command: HCI_CMD_WRITE_LINK_POLICY_SETTINGS"); LOG(WIIMOTE, "Input:"); LOG(WIIMOTE, " ConnectionHandle: 0x%04x", pLinkPolicy->con_handle); LOG(WIIMOTE, " Policy: 0x%04x", pLinkPolicy->settings); + + SendEventCommandStatus(HCI_CMD_WRITE_LINK_POLICY_SETTINGS); + + PanicAlert("The connect should be send after the command status... check it"); + + // for homebrew works this + CWII_IPC_HLE_WiiMote* pWiimote = AccessWiiMote(pLinkPolicy->con_handle); + pWiimote->Connect(); } +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// +// --- helper +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////// CWII_IPC_HLE_WiiMote* CWII_IPC_HLE_Device_usb_oh1_57e_305::AccessWiiMote(const bdaddr_t& _rAddr) { @@ -1358,7 +1400,3 @@ CWII_IPC_HLE_WiiMote* CWII_IPC_HLE_Device_usb_oh1_57e_305::AccessWiiMote(u16 _Co } return NULL; } -void CWII_IPC_HLE_Device_usb_oh1_57e_305::ClearBD(bdaddr_t& _rAddr) -{ - memset(_rAddr.b, 0, BLUETOOTH_BDADDR_SIZE); -} diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h index e73a95c700..fae6a1ba1a 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h @@ -41,6 +41,22 @@ union UACLHeader u32 Hex; }; +struct SQueuedEvent +{ + u8 m_buffer[1024]; + size_t m_size; + SQueuedEvent(size_t size) : + m_size(size) + {} +}; + +struct ACLFrame +{ + u16 ConnectionHandle; + u8* data; + u32 size; +}; + class CWII_IPC_HLE_Device_usb_oh1_57e_305 : public IWII_IPC_HLE_Device { public: @@ -60,6 +76,15 @@ public: private: + typedef std::queue CEventQueue; + CEventQueue m_EventQueue; + + void AddEventToQueue(const SQueuedEvent& _event) + { + m_EventQueue.push(_event); + } + + enum { USB_IOCTL_HCI_COMMAND_MESSAGE = 0, @@ -95,10 +120,9 @@ private: // STATE_TO_SAVE std::queue m_HCICommandMessageQueue; + std::queue m_AclFrameQue; - bool m_ACLAnswer; SIOCtlVBuffer* m_pACLBuffer; - SIOCtlVBuffer* m_pHCIBuffer; bool SendEventCommandStatus(u16 _Opcode); @@ -107,12 +131,14 @@ private: bool SendEventInquiryResponse(); bool SendEventInquiryComplete(); - bool SendEventRemoteNameReq(); + bool SendEventRemoteNameReq(bdaddr_t _bd); bool SendEventRequestConnection(); - bool SendEventConnectionComplete(); - bool SendEventReadClockOffsetComplete(); - bool SendEventReadRemoteVerInfo(); - bool SendEventReadRemoteFeatures(); + bool SendEventConnectionComplete(bdaddr_t _bd); + bool SendEventReadClockOffsetComplete(u16 _connectionHandle); + bool SendEventReadRemoteVerInfo(u16 _connectionHandle); + bool SendEventReadRemoteFeatures(u16 _connectionHandle); + bool SendEventRoleChange(bdaddr_t _bd); + bool SendEventNumberOfCompletedPackets(u16 _connectionHandle); void ExecuteHCICommandMessage(const SHCICommandMessage& _rCtrlMessage); @@ -147,45 +173,10 @@ private: void SendToDevice(u16 _ConnectionHandle, u8* _pData, u32 _Size); - enum EState - { - STATE_NONE, - STATE_INQUIRY_RESPONSE, - STATE_INQUIRY_COMPLETE, - STATE_START_REMOTE_NAME_REQ, - STATE_REMOTE_NAME_REQ, - STATE_CONNECTION_COMPLETE_EVENT, - STATE_READ_CLOCK_OFFSET, - STATE_READ_REMOTE_VER_INFO, - STATE_READ_REMOTE_FEATURES, - STATE_CONNECT_WIIMOTE - }; - EState m_State; u32 m_UpdateWaitCount; - bdaddr_t m_StateTempBD; - u16 m_StateTempConnectionHandle; - - struct ACLFrame { - u16 ConnectionHandle; - u8* data; - u32 size; - }; - - std::queue m_AclFrameQue; u8 scan_enable; - - //TODO: get rid of these, integrate into EState. - enum EDelayedEvent - { - EVENT_NONE, - EVENT_REQUEST_CONNECTION, - EVENT_CONNECTION_COMPLETE - }; - EDelayedEvent m_DelayedEvent; - void SetDelayedEvent(EDelayedEvent e); - bdaddr_t m_ControllerBD; u8 m_ClassOfDevice[HCI_CLASS_SIZE]; char m_LocalName[HCI_UNIT_NAME_SIZE]; @@ -203,8 +194,6 @@ public: //hack for wiimote plugin std::vector m_WiiMotes; CWII_IPC_HLE_WiiMote* AccessWiiMote(const bdaddr_t& _rAddr); CWII_IPC_HLE_WiiMote* AccessWiiMote(u16 _ConnectionHandle); - void ClearBD(bdaddr_t& _rAddr); - }; #endif diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp index 14224c27eb..ab1073ce52 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp @@ -20,6 +20,7 @@ #include "WII_IPC_HLE_WiiMote.h" #include "l2cap.h" +#include "WiiMote_HID_Attr.h" #if defined(_MSC_VER) #pragma pack(push, 1) @@ -29,10 +30,13 @@ #define HIDP_OUTPUT_CHANNEL 0x11 #define HIDP_INPUT_CHANNEL 0x13 -#define HID_OUTPUT_SCID 0x1234 -#define HID_INPUT_SCID 0x5678 +// #define HID_OUTPUT_SCID 0x1234 +// #define HID_INPUT_SCID 0x5678 +#define HID_OUTPUT_SCID 0x0040 +#define HID_INPUT_SCID 0x0040 + struct SL2CAP_Header { u16 Length; @@ -128,8 +132,8 @@ namespace Core { } CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305* _pHost, int _Number) -: m_Name("Nintendo RVL-CNT-01") -, m_pHost(_pHost) + : m_Name("Nintendo RVL-CNT-01") + , m_pHost(_pHost) { s_Usb = _pHost; LOG(WIIMOTE, "Wiimote %i constructed", _Number); @@ -143,9 +147,9 @@ CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305* m_ControllerConnectionHandle = 0x100 + _Number; - uclass[0]= 0x04; - uclass[1]= 0x25; - uclass[2]= 0x00; + uclass[0]= 0x00; + uclass[1]= 0x04; + uclass[2]= 0x48; features[0] = 0xBC; features[1] = 0x02; @@ -155,6 +159,9 @@ CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305* features[5] = 0x00; features[6] = 0x00; features[7] = 0x00; + + lmp_version = 0x2; + lmp_subversion = 0x229; } void CWII_IPC_HLE_WiiMote::SendACLFrame(u8* _pData, u32 _Size) @@ -190,12 +197,32 @@ void CWII_IPC_HLE_WiiMote::SendACLFrame(u8* _pData, u32 _Size) case 0x0001: SignalChannel(pData, DataSize); break; - case HID_OUTPUT_SCID: - HidOutput(pData, DataSize); - break; default: - PanicAlert("SendACLFrame to unknown channel"); + { + CChannelMap::iterator itr= m_Channel.find(pHeader->CID); + if (itr != m_Channel.end()) + { + SChannel& rChannel = itr->second; + switch(rChannel.PSM) + { + case 0x01: //SDP + { + HandleSDP(pHeader->CID, pData, DataSize); + } + break; + + default: + PanicAlert("channel %i has unknow PSM %x", pHeader->CID); + break; + } + } + else + { + PanicAlert("SendACLFrame to unknown channel %i", pHeader->CID); + } + + } break; } } @@ -223,16 +250,29 @@ void CWII_IPC_HLE_WiiMote::SendCommandToACL(u8 _Ident, u8 _Code, u8 _CommandLeng // send .... m_pHost->SendACLFrame(GetConnectionHandle(), DataFrame, pHeader->Length + sizeof(SL2CAP_Header)); - // stupid self-test - // SendACLFrame(DataFrame, pHeader->Length + sizeof(SL2CAP_Header)); + + // dump raw data + { + LOG(WIIMOTE, "m_pHost->SendACLFrame: 0x%x", GetConnectionHandle()); + std::string Temp; + for (u32 j=0; jLength + sizeof(SL2CAP_Header); j++) + { + char Buffer[128]; + sprintf(Buffer, "%02x ", DataFrame[j]); + Temp.append(Buffer); + } + LOG(WIIMOTE, " Data: %s", Temp.c_str()); + } } -void CWII_IPC_HLE_WiiMote::Connect() { +void CWII_IPC_HLE_WiiMote::Connect() +{ SendConnectionRequest(HID_OUTPUT_SCID, HIDP_OUTPUT_CHANNEL); SendConnectionRequest(HID_INPUT_SCID, HIDP_INPUT_CHANNEL); } -void CWII_IPC_HLE_WiiMote::SendConnectionRequest(u16 scid, u16 psm) { +void CWII_IPC_HLE_WiiMote::SendConnectionRequest(u16 scid, u16 psm) +{ // create the channel SChannel& rChannel = m_Channel[scid]; rChannel.PSM = psm; @@ -253,15 +293,33 @@ void CWII_IPC_HLE_WiiMote::SendConfigurationRequest(u16 scid) { _dbg_assert_(WIIMOTE, DoesChannelExist(scid)); SChannel& rChannel = m_Channel[scid]; - l2cap_conf_req cr; - cr.dcid = rChannel.DCID; - cr.flags = 0; //what goes here? check libogc. + u8 Buffer[1024]; + int Offset = 0; + + l2cap_conf_req* cr = (l2cap_conf_req*)Buffer; + cr->dcid = rChannel.DCID; + cr->flags = 0; //what goes here? check libogc. + + Offset += 2; + + /* + controller doesnt know this... + Buffer[Offset++] = 1; + Buffer[Offset++] = 2; + Buffer[Offset++] = 0; + Buffer[Offset++] = 1;*/ + + Buffer[Offset++] = 2; + Buffer[Offset++] = 2; + Buffer[Offset++] = 0xff; + Buffer[Offset++] = 0xff; + LOG(WIIMOTE, " SendConfigurationRequest()"); - LOG(WIIMOTE, " Dcid: 0x%04x", cr.dcid); - LOG(WIIMOTE, " Flags: 0x%04x", cr.flags); + LOG(WIIMOTE, " Dcid: 0x%04x", cr->dcid); + LOG(WIIMOTE, " Flags: 0x%04x", cr->flags); - SendCommandToACL(L2CAP_CONF_REQ, L2CAP_CONF_REQ, sizeof(cr), (u8*)&cr); + SendCommandToACL(L2CAP_CONF_REQ, L2CAP_CONF_REQ, Offset, Buffer); } @@ -367,6 +425,46 @@ void CWII_IPC_HLE_WiiMote::CommandConnectionReq(u8 _Ident, u8* _pData, u32 _Size SendCommandToACL(_Ident, L2CAP_CONN_RSP, sizeof(SL2CAP_ConnectionResponse), (u8*)&Rsp); } +class CConfigurationResponse +{ +public: + CConfigurationResponse(u8 identifier, u16 scid, u16 flags, u16 result) + { + buffer[0] = 0x05; + buffer[1] = identifier; + *(u16*)&buffer[4] = scid; + *(u16*)&buffer[6] = flags; + *(u16*)&buffer[8] = result; + + length = 10; + + UpdateLen(); + } + + void AddConfig(u8 type, u8 len, void* data) + { + buffer[length++] = type; + buffer[length++] = len; + memcpy(&buffer[length], data, len); + length += len; + + UpdateLen(); + } + + u16 getLen() { return length; } + u8* getBuffer() { return buffer; } + +private: + + void UpdateLen() + { + *(u16*)&buffer[2] = length; + } + + u8 buffer[1024]; + u16 length; +}; + void CWII_IPC_HLE_WiiMote::CommandCofigurationReq(u8 _Ident, u8* _pData, u32 _Size) { u32 Offset = 0; @@ -437,6 +535,9 @@ void CWII_IPC_HLE_WiiMote::CommandCofigurationReq(u8 _Ident, u8* _pData, u32 _Si SendCommandToACL(_Ident, L2CAP_CONF_RSP, RespLen, TempBuffer); + + // ugly + SendConfigurationRequest(Rsp->scid); } void CWII_IPC_HLE_WiiMote::CommandConnectionResponse(u8 _Ident, u8* _pData, u32 _Size) @@ -475,3 +576,219 @@ void CWII_IPC_HLE_WiiMote::CommandCofigurationResponse(u8 _Ident, u8* _pData, u3 _dbg_assert_(WIIMOTE, rsp->result == 0); } + + + + + +///////////////////////////////////////////////////////////////////////////////////////////////// + +#define SDP_UINT8 0x08 +#define SDP_UINT16 0x09 +#define SDP_UINT32 0x0A +#define SDP_SEQ8 0x35 +#define SDP_SEQ16 0x36 + + + + +void CWII_IPC_HLE_WiiMote::SDPSendServiceSearchResponse(u16 cid, u16 TransactionID, u8* pServiceSearchPattern, u16 MaximumServiceRecordCount) +{ + // verify block... we hanlde search pattern for HID service only + { + CBigEndianBuffer buffer(pServiceSearchPattern); + _dbg_assert_(WIIMOTE, buffer.Read8(0) == SDP_SEQ8); // data sequence + _dbg_assert_(WIIMOTE, buffer.Read8(1) == 0x03); // sequence size + + // HIDClassID + _dbg_assert_(WIIMOTE, buffer.Read8(2) == 0x19); + _dbg_assert_(WIIMOTE, buffer.Read16(3) == 0x1124); + } + + u8 DataFrame[1000]; + CBigEndianBuffer buffer(DataFrame); + + int Offset = 0; + SL2CAP_Header* pHeader = (SL2CAP_Header*)&DataFrame[Offset]; Offset += sizeof(SL2CAP_Header); + pHeader->CID = cid; + pHeader->Length = 0x14; + + buffer.Write8 (Offset, 0x03); Offset++; + buffer.Write16(Offset, TransactionID); Offset += 2; // transaction ID + buffer.Write16(Offset, 0x0009); Offset += 2; // param length + buffer.Write16(Offset, 0x0001); Offset += 2; // TotalServiceRecordCount + buffer.Write16(Offset, 0x0001); Offset += 2; // CurrentServiceRecordCount + buffer.Write32(Offset, 0x1234ABCD); Offset += 4; // ServiceRecordHandleList[4] + buffer.Write8( Offset, 0x00); Offset++; // no continuation state; + + pHeader->Length = Offset - sizeof(SL2CAP_Header); + + m_pHost->SendACLFrame(GetConnectionHandle(), DataFrame, Offset); +} + +void GetStartAndEndID(u8* pAttribIDList, u16& _startID, u16& _endID) +{ + u32 attribOffset = 0; + CBigEndianBuffer attribList(pAttribIDList); + + u8 sequence = attribList.Read8(attribOffset); attribOffset++; _dbg_assert_(WIIMOTE, sequence == SDP_SEQ8); + u8 seqSize = attribList.Read8(attribOffset); attribOffset++; + u8 typeID = attribList.Read8(attribOffset); attribOffset++; + + if (typeID == SDP_UINT32) + { + _startID = attribList.Read16(attribOffset); attribOffset += 2; + _endID = attribList.Read16(attribOffset); attribOffset += 2; + } + else + { + _startID = attribList.Read8(attribOffset); attribOffset += 2; + _endID = _startID; + PanicAlert("Read just a single attrib - not tested"); + } +} + + +void CWII_IPC_HLE_WiiMote::SDPSendServiceAttributeResponse(u16 cid, u16 TransactionID, u32 ServiceHandle, u8* pAttribIDList, u16 AttribListIDSize) +{ + u8 DataFrame[1000]; + CBigEndianBuffer buffer(DataFrame); + + int Offset = 0; + SL2CAP_Header* pHeader = (SL2CAP_Header*)&DataFrame[Offset]; Offset += sizeof(SL2CAP_Header); + pHeader->CID = cid; + + buffer.Write8 (Offset, 0x05); Offset++; + buffer.Write16(Offset, TransactionID); Offset += 2; // transaction ID + + { + u32 paraLenOffset = Offset; Offset += 2; + u32 AttributeListByteCountOffset = Offset; Offset += 2; + + buffer.Write8(Offset, SDP_SEQ16); Offset ++; // write 16 bit sequencer + u32 sequenceSizeOffset = Offset; Offset += 2; + + // get attrib range + u16 startAttrID; + u16 endAttrID; + GetStartAndEndID(pAttribIDList, startAttrID, endAttrID); + + // walk through the table + const CAttribTable& rAttribTable = GetAttribTable(); + CAttribTable::const_iterator itr = rAttribTable.begin(); + + u32 sequenceSize = 0; + while(itr != rAttribTable.end()) + { + const SAttrib& rAttrib = *itr; + + if ((rAttrib.ID >= startAttrID) && (rAttrib.ID <= endAttrID)) + { + _dbg_assert_(WIIMOTE, rAttrib.size <= 230); + + // ATTRIB TYPE ID + buffer.Write8(Offset, SDP_UINT16); Offset ++; + buffer.Write16(Offset, rAttrib.ID); Offset += 2; + sequenceSize += 3; + + // RAW ATTRIB DATA SEQ HEADER + buffer.Write8(Offset, SDP_SEQ8); Offset ++; + buffer.Write8(Offset, rAttrib.size); Offset ++; + sequenceSize += 2; + + // RAW ATTRIB DATA + memcpy(buffer.GetPointer(Offset), rAttrib.pData, rAttrib.size); + Offset += rAttrib.size; + + sequenceSize += rAttrib.size; + } + itr++; + } + + + buffer.Write16(sequenceSizeOffset, sequenceSize); + buffer.Write16(AttributeListByteCountOffset, sequenceSize + 4); // AttributeListByteCount + buffer.Write16(paraLenOffset, sequenceSize + 4 + 3); // param length + } + + buffer.Write8(Offset, 0x00); Offset++; // no continuation state; + + pHeader->Length = Offset - sizeof(SL2CAP_Header); + + + // dump raw data + { + LOG(WIIMOTE, "test response: 0x%x", GetConnectionHandle()); + std::string Temp; + for (u32 j=0; jLength + sizeof(SL2CAP_Header); j++) + { + char Buffer[128]; + sprintf(Buffer, "%02x ", DataFrame[j]); + Temp.append(Buffer); + } + LOG(WIIMOTE, " Data: %s", Temp.c_str()); + } + + m_pHost->SendACLFrame(GetConnectionHandle(), DataFrame, pHeader->Length + sizeof(SL2CAP_Header)); +} + +void CWII_IPC_HLE_WiiMote::HandleSDP(u16 cid, u8* _pData, u32 _Size) +{ + // dump raw data + { + LOG(WIIMOTE, "HandleSDP: 0x%x", GetConnectionHandle()); + std::string Temp; + for (u32 j=0; j<_Size; j++) + { + char Buffer[128]; + sprintf(Buffer, "%02x ", _pData[j]); + Temp.append(Buffer); + } + LOG(WIIMOTE, " Data: %s", Temp.c_str()); + } + + + + CBigEndianBuffer buffer(_pData); + + switch(buffer.Read8(0)) + { + // SDP_ServiceSearchRequest + case 0x02: + { + LOG(WIIMOTE, "!!! SDP_ServiceSearchRequest !!!"); + + _dbg_assert_(WIIMOTE, _Size == 13); + + u16 TransactionID = buffer.Read16(1); + u16 ParameterLength = buffer.Read16(3); + u8* pServiceSearchPattern = buffer.GetPointer(5); + u16 MaximumServiceRecordCount = buffer.Read16(10); + u8 ContinuationState = buffer.Read8(12); + + SDPSendServiceSearchResponse(cid, TransactionID, pServiceSearchPattern, MaximumServiceRecordCount); + } + break; + + // SDP_ServiceAttributeRequest + case 0x04: + { + LOG(WIIMOTE, "!!! SDP_ServiceAttributeRequest !!!"); + + u16 TransactionID = buffer.Read16(1); + u16 ParameterLength = buffer.Read16(3); + u32 ServiceHandle = buffer.Read32(5); + u16 MaximumAttributeByteCount = buffer.Read16(9); // MaximumAttributeByteCount + u8* pAttribIDList = buffer.GetPointer(11); + u8 ContinuationState = buffer.Read8(16); + + u8 AttribListIDSize = ParameterLength - sizeof(ContinuationState) - sizeof(ServiceHandle) -sizeof(MaximumAttributeByteCount); + SDPSendServiceAttributeResponse(cid, TransactionID, ServiceHandle, pAttribIDList, AttribListIDSize); + } + break; + + default: + PanicAlert("Unknown SDP command %x", _pData[0]); + break; + } +} \ No newline at end of file diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.h index 104db53b36..d95066e528 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.h @@ -22,6 +22,56 @@ class CWII_IPC_HLE_Device_usb_oh1_57e_305; + +class CBigEndianBuffer +{ +public: + CBigEndianBuffer(u8* pBuffer) + : m_pBuffer(pBuffer) + { + } + + u8 Read8(u32 offset) + { + return m_pBuffer[offset]; + } + + u16 Read16(u32 offset) + { + return Common::swap16(*(u16*)&m_pBuffer[offset]); + } + + u32 Read32(u32 offset) + { + return Common::swap32(*(u32*)&m_pBuffer[offset]); + } + + void Write8(u32 offset, u8 data) + { + m_pBuffer[offset] = data; + } + + void Write16(u32 offset, u16 data) + { + *(u16*)&m_pBuffer[offset] = Common::swap16(data); + } + + void Write32(u32 offset, u32 data) + { + *(u32*)&m_pBuffer[offset] = Common::swap32(data); + } + + u8* GetPointer(u32 offset) + { + return &m_pBuffer[offset]; + } + +private: + + u8* m_pBuffer; + +}; + class CWII_IPC_HLE_WiiMote { public: @@ -41,6 +91,12 @@ public: const char* GetName() const { return m_Name.c_str(); } + u8 GetLMPVersion() const { return lmp_version; } + + u16 GetLMPSubVersion() const { return lmp_subversion; } + + u8 GetManufactorID() const { return 0xF; } // Broadcom Corporation + void SendACLFrame(u8* _pData, u32 _Size); //to wiimote void Connect(); @@ -58,6 +114,11 @@ private: u8 features[HCI_FEATURES_SIZE]; + u8 lmp_version; + + u16 lmp_subversion; + + std::string m_Name; CWII_IPC_HLE_Device_usb_oh1_57e_305* m_pHost; @@ -71,7 +132,9 @@ private: u16 MTU; u16 FlushTimeOut; }; - std::map m_Channel; + + typedef std::map CChannelMap; + CChannelMap m_Channel; bool DoesChannelExist(u16 _SCID) { @@ -91,5 +154,18 @@ private: void CommandCofigurationReq(u8 _Ident, u8* _pData, u32 _Size); void CommandConnectionResponse(u8 _Ident, u8* _pData, u32 _Size); void CommandCofigurationResponse(u8 _Ident, u8* _pData, u32 _Size); + + + ////////////////// + // some new ugly stuff + // + // should be inside the plugin + // + void HandleSDP(u16 cid, u8* _pData, u32 _Size); + void SDPSendServiceSearchResponse(u16 cid, u16 TransactionID, u8* pServiceSearchPattern, u16 MaximumServiceRecordCount); + void SDPSendServiceAttributeResponse(u16 cid, u16 TransactionID, u32 ServiceHandle, u8* pAttribIDList, u16 AttribListIDSize); + + u16 AddAttribToList(int attribID, u8* pBuffer); }; + #endif diff --git a/Source/Core/Core/Src/IPC_HLE/WiiMote_HID_Attr.cpp b/Source/Core/Core/Src/IPC_HLE/WiiMote_HID_Attr.cpp new file mode 100644 index 0000000000..fea6e594b5 --- /dev/null +++ b/Source/Core/Core/Src/IPC_HLE/WiiMote_HID_Attr.cpp @@ -0,0 +1,175 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include +#include "WiiMote_HID_Attr.h" + +CAttribTable m_AttribTable; + + +// 0x00 +u8 ServiceRecordHandle[] = { 0x0a, 0x00, 0x01, 0x00, 0x00 }; +// 0x01 +u8 SrvClassIDList[] = { 0x35, 0x03, + 0x19, 0x11, 0x24 }; +// 0x04 +u8 ProtocolDescriptorList[] = { 0x35, 0x0D, + 0x35, 0x06, + 0x19, 0x01, 0x00, // Element 0 + 0x09, 0x00, 0x11, // Element 1 + 0x35, 0x03, + 0x19, 0x00, 0x11}; // Element 0 +// 0x5 +u8 BrowseGroupList[] = { 0x35, 0x03, 0x09, 0x10, 0x02 }; +// 0x6 +u8 LanguageBaseAttributeIDList[] = { 0x35, 0x09, + 0x09, 0x65, 0x6e, + 0x09, 0x00, 0x6a, + 0x09, 0x01, 0x00 }; +// 0x09 +u8 BluetoothProfileDescriptorList[] = { 0x35, 0x08, + 0x35, 0x06, + 0x19, 0x00, 0x11, + 0x09, 0x01, 0x00 }; +// 0x0D +u8 AdditionalProtocolDescriptorLists[] = { 0x35, 0x0a, + 0x35, 0x03, + 0x19, 0x01, 0x00, + 0x09, 0x00, 0x13, + 0x35, 0x03, + 0x19, 0x00, 0x11 }; +// 0x100 +u8 ServiceName[] = { 0x25, 0x13, 'N','i','n','t','e','n','d','o',' ','R','V','L','-','C','N','T','-','0','1' }; +// 0x101 +u8 ServiceDescription[] = { 0x25, 0x13, 'N','i','n','t','e','n','d','o',' ','R','V','L','-','C','N','T','-','0','1' }; +// 0x102 +u8 ProviderName [] = { 0x25, 0x8, 'N','i','n','t','e','n','d','o'}; + +// 0x200 +u8 HIDDeviceReleaseNumber[] = { 0x09, 0x01, 0x00 }; +// 0x201 +u8 HIDParserVersion[] = { 0x09, 0x01, 0x11 }; +// 0x202 +u8 HIDDeviceSubclass[] = { 0x09, 0x00, 0x04 }; +// 0x203 +u8 HIDCountryCode[] = { 0x09, 0x00, 0x33 }; +// 0x204 +u8 HIDVirtualCable[] = { 0x09, 0x00, 0x00 }; +// 0x205 +u8 HIDReconnectInitiate[] = { 0x09, 0x00, 0x01 }; + +// 0x206 +u8 HIDDescriptorList[] = { 0x35, 0xDF, + 0x35, 0xDD, + 0x08, 0x22, // Element 0 + 0x25, 0xD9, + + // 0xD9 Bytes - Element 1 + 0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x10, + 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, + 0x01, 0x06, 0x00, 0xff, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x11, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x12, 0x95, 0x02, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x13, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x14, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x15, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x16, 0x95, 0x15, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x17, 0x95, 0x06, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x18, 0x95, 0x15, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x19, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x1a, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x20, 0x95, 0x06, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x21, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x22, 0x95, 0x04, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x30, 0x95, 0x02, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x31, 0x95, 0x05, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x32, 0x95, 0x0a, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x33, 0x95, 0x11, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x34, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x35, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x36, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x37, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x3d, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x3e, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x3f, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0xc0 }; // end tag + + +// 0x207 +u8 HIDLANGIDBaseList[] = { 0x35, 0x08, + 0x35, 0x06, + 0x09, 0x04, 0x09, + 0x09, 0x01, 0x00 }; + +// 0x208 +u8 HIDSDPDisable[] = { 0x28, 0x00 }; +// 0x209 +u8 HIDBatteryPower[] = { 0x28, 0x01 }; +// 0x20a +u8 HIDRemoteWake[] = { 0x28, 0x01 }; +// 0x20b +u8 HIDUnk_020B[] = { 0x09, 0x01, 0x00 }; +// 0x20c +u8 HIDUnk_020C[] = { 0x09, 0x0c, 0x80 }; +// 0x20d +u8 HIDUnk_020D[] = { 0x09, 0x00, 0x00 }; +// 0x20e +u8 HIDBootDevice[] = { 0x28, 0x00 }; + + +void InitAttribTable() +{ + m_AttribTable.push_back(SAttrib(0x00, ServiceRecordHandle, sizeof(ServiceRecordHandle))); + m_AttribTable.push_back(SAttrib(0x01, SrvClassIDList, sizeof(SrvClassIDList))); + m_AttribTable.push_back(SAttrib(0x04, ProtocolDescriptorList, sizeof(ProtocolDescriptorList))); + m_AttribTable.push_back(SAttrib(0x05, BrowseGroupList, sizeof(BrowseGroupList))); + m_AttribTable.push_back(SAttrib(0x06, LanguageBaseAttributeIDList, sizeof(LanguageBaseAttributeIDList))); + m_AttribTable.push_back(SAttrib(0x09, BluetoothProfileDescriptorList, sizeof(BluetoothProfileDescriptorList))); + m_AttribTable.push_back(SAttrib(0x0D, AdditionalProtocolDescriptorLists, sizeof(AdditionalProtocolDescriptorLists))); + + + m_AttribTable.push_back(SAttrib(0x100, ServiceName, sizeof(ServiceName))); + m_AttribTable.push_back(SAttrib(0x101, ServiceDescription, sizeof(ServiceDescription))); + m_AttribTable.push_back(SAttrib(0x102, ProviderName, sizeof(ProviderName))); + + m_AttribTable.push_back(SAttrib(0x200, HIDDeviceReleaseNumber, sizeof(HIDDeviceReleaseNumber))); + m_AttribTable.push_back(SAttrib(0x201, HIDParserVersion, sizeof(HIDParserVersion))); + m_AttribTable.push_back(SAttrib(0x202, HIDDeviceSubclass, sizeof(HIDDeviceSubclass))); + m_AttribTable.push_back(SAttrib(0x203, HIDCountryCode, sizeof(HIDCountryCode))); + m_AttribTable.push_back(SAttrib(0x204, HIDVirtualCable, sizeof(HIDVirtualCable))); + m_AttribTable.push_back(SAttrib(0x205, HIDReconnectInitiate, sizeof(HIDReconnectInitiate))); + m_AttribTable.push_back(SAttrib(0x206, HIDDescriptorList, sizeof(HIDDescriptorList))); + m_AttribTable.push_back(SAttrib(0x207, HIDLANGIDBaseList, sizeof(HIDLANGIDBaseList))); + m_AttribTable.push_back(SAttrib(0x208, HIDSDPDisable, sizeof(HIDSDPDisable))); + m_AttribTable.push_back(SAttrib(0x209, HIDBatteryPower, sizeof(HIDBatteryPower))); + m_AttribTable.push_back(SAttrib(0x20a, HIDRemoteWake, sizeof(HIDRemoteWake))); + m_AttribTable.push_back(SAttrib(0x20b, HIDUnk_020B, sizeof(HIDUnk_020B))); + m_AttribTable.push_back(SAttrib(0x20c, HIDUnk_020C, sizeof(HIDUnk_020C))); + m_AttribTable.push_back(SAttrib(0x20d, HIDUnk_020D, sizeof(HIDUnk_020D))); + m_AttribTable.push_back(SAttrib(0x20e, HIDBootDevice, sizeof(HIDBootDevice))); +} + +const CAttribTable& GetAttribTable() +{ + if (m_AttribTable.empty()) + { + InitAttribTable(); + } + + return m_AttribTable; +} \ No newline at end of file diff --git a/Source/Core/Core/Src/IPC_HLE/WiiMote_HID_Attr.h b/Source/Core/Core/Src/IPC_HLE/WiiMote_HID_Attr.h new file mode 100644 index 0000000000..3b60ee7456 --- /dev/null +++ b/Source/Core/Core/Src/IPC_HLE/WiiMote_HID_Attr.h @@ -0,0 +1,38 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef WIIMOTE_HID_ATTR_H_ +#define WIIMOTE_HID_ATTR_H_ + +struct SAttrib +{ + u16 ID; + u8* pData; + u16 size; + + SAttrib(u16 _ID, u8* _Data, u16 _size) + : ID(_ID) + , pData(_Data) + , size(_size) + { } +}; + +typedef std::vector CAttribTable; + +const CAttribTable& GetAttribTable(); + +#endif \ No newline at end of file diff --git a/Source/Core/Core/Src/IPC_HLE/hci.h b/Source/Core/Core/Src/IPC_HLE/hci.h index cc2c611bcf..20e0115f03 100644 --- a/Source/Core/Core/Src/IPC_HLE/hci.h +++ b/Source/Core/Core/Src/IPC_HLE/hci.h @@ -2487,6 +2487,24 @@ struct SHCIEventConnectionComplete u8 EncryptionEnabled; }; +struct SHCIEventRoleChange +{ + u8 EventType; + u8 PayloadLength; + u8 Status; + bdaddr_t bdaddr; + u8 NewRole; +}; + +struct SHCIEventNumberOfCompletedPackets +{ + u8 EventType; + u8 PayloadLength; + u8 value; + u16 Connection_Handle; + u16 Number_Of_Completed_Packets; +}; + #ifdef __cplusplus } #endif diff --git a/Source/Core/Core/Src/IPC_HLE/wiimote_hid.h b/Source/Core/Core/Src/IPC_HLE/wiimote_hid.h deleted file mode 100644 index 0175a1c6b3..0000000000 --- a/Source/Core/Core/Src/IPC_HLE/wiimote_hid.h +++ /dev/null @@ -1,168 +0,0 @@ -#ifndef WIIMOTE_HID_H -#define WIIMOTE_HID_H - -#include - -#ifdef _MSC_VER -#pragma warning(disable:4200) -#pragma pack(push, 1) -#endif - -//source: HID_010_SPC_PFL/1.0 (official HID specification) - -struct hid_packet { - u8 param : 4; - u8 type : 4; - u8 data[0]; -}; - -#define HID_TYPE_SET_REPORT 5 -#define HID_TYPE_DATA 0xA - -#define HID_TYPE_HANDSHAKE 0 -#define HID_HANDSHAKE_SUCCESS 0 -#define HID_HANDSHAKE_WIIMOTE 8 //custom, reserved in HID specs. - -#define HID_PARAM_INPUT 1 -#define HID_PARAM_OUTPUT 2 - -//source: http://wiibrew.org/wiki/Wiimote - -struct wm_report { - u8 channel; - u8 data[0]; -}; - -#define WM_LEDS 0x11 -struct wm_leds { - u8 rumble : 1; - u8 : 3; - u8 leds : 4; -}; - -#define WM_DATA_REPORTING 0x12 -struct wm_data_reporting { - u8 rumble : 1; - u8 continuous : 1; - u8 : 6; - u8 mode; -}; - -#define WM_IR_PIXEL_CLOCK 0x13 -#define WM_IR_LOGIC 0x1A - -#define WM_REQUEST_STATUS 0x15 -struct wm_request_status { - u8 rumble : 1; - u8 : 7; -}; - -#define WM_STATUS_REPORT 0x20 -struct wm_status_report { - u8 padding1[2]; - u8 unknown : 1; - u8 extension : 1; - u8 speaker : 1; - u8 ir : 1; - u8 leds : 4; - u8 padding2[2]; - u8 battery; -}; - -#define WM_WRITE_DATA 0x16 -struct wm_write_data { - u8 rumble : 1; - u8 space : 2; //see WM_SPACE_* - u8 : 5; - u8 address[3]; - u8 size; - u8 data[16]; -}; - -#define WM_WRITE_DATA_REPLY 0x22 //empty, afaik - -#define WM_READ_DATA 0x17 -struct wm_read_data { - u8 rumble : 1; - u8 space : 2; //see WM_SPACE_* - u8 : 5; - u8 address[3]; - u8 size[2]; -}; - -#define WM_SPACE_EEPROM 0 -#define WM_SPACE_REGS1 1 -#define WM_SPACE_REGS2 2 -#define WM_SPACE_INVALID 3 - -#define WM_READ_DATA_REPLY 0x21 -struct wm_read_data_reply { - u16 buttons; - u8 error : 4; //see WM_RDERR_* - u8 size : 4; - u16 address; - u8 data[16]; -}; - -#define WM_RDERR_WOREG 7 -#define WM_RDERR_NOMEM 8 - -struct wm_core { - u8 left : 1; - u8 right : 1; - u8 down : 1; - u8 up : 1; - u8 plus : 1; - u8 : 3; - u8 two : 1; - u8 one : 1; - u8 b : 1; - u8 a : 1; - u8 minus : 1; - u8 : 2; - u8 home : 1; -}; - -struct wm_accel { - u8 x, y, z; -}; - -//filled with 0xFF if empty -struct wm_ir_extended { - u8 x; - u8 y; - u8 size : 4; - u8 xHi : 2; - u8 yHi : 2; -}; - -#define WM_REPORT_CORE 0x30 - -#define WM_REPORT_CORE_ACCEL 0x31 -struct wm_report_core_accel { - wm_core c; - wm_accel a; -}; - -#define WM_REPORT_CORE_EXT8 0x32 - -#define WM_REPORT_CORE_ACCEL_IR12 0x33 -struct wm_report_core_accel_ir12 { - wm_core c; - wm_accel a; - wm_ir_extended ir[4]; -}; - -#define WM_REPORT_CORE_EXT19 0x34 -#define WM_REPORT_CORE_ACCEL_EXT16 0x35 -#define WM_REPORT_CORE_IR10_EXT9 0x36 -#define WM_REPORT_CORE_ACCEL_IR10_EXT6 0x37 -#define WM_REPORT_EXT21 0x3d -#define WM_REPORT_INTERLEAVE1 0x3e -#define WM_REPORT_INTERLEAVE2 0x3f - -#if defined(_MSC_VER) -#pragma pack(pop) -#endif - -#endif //WIIMOTE_HID_H diff --git a/Source/Plugins/Plugin_Wiimote_Test/Src/Wiimote.cpp b/Source/Plugins/Plugin_Wiimote_Test/Src/Wiimote.cpp index b5eee4936e..a3b26e59ec 100644 --- a/Source/Plugins/Plugin_Wiimote_Test/Src/Wiimote.cpp +++ b/Source/Plugins/Plugin_Wiimote_Test/Src/Wiimote.cpp @@ -190,13 +190,45 @@ extern "C" void Wiimote_Output(const void* _pData, u32 _Size) { hid_packet* hidp = (hid_packet*) data; - if(hidp->type == HID_TYPE_SET_REPORT && - hidp->param == HID_PARAM_OUTPUT) + if ((hidp->param != HID_PARAM_INPUT) && (hidp->param != HID_PARAM_OUTPUT)) { - HidOutputReport((wm_report*)hidp->data); - } else { - PanicAlert("HidOutput: Unknown type 0x%02x", data[0]); + PanicAlert("hidp->param has a wrong parameter!!!"); } + + switch(hidp->type) + { + case HID_TYPE_HANDSHAKE: + if (hidp->param == HID_PARAM_INPUT) + { + PanicAlert("HID_TYPE_HANDSHAKE - HID_PARAM_INPUT"); + } + else + { + PanicAlert("HID_TYPE_HANDSHAKE - HID_PARAM_OUTPUT"); + } + g_ReportingMode = 0x33; + break; + + case HID_TYPE_SET_REPORT: + if (hidp->param == HID_PARAM_INPUT) + { + PanicAlert("HID_TYPE_SET_REPORT input"); + } + else + { + HidOutputReport((wm_report*)hidp->data); + } + break; + + case HID_TYPE_DATA: + PanicAlert("HID_TYPE_DATA %s", hidp->type, hidp->param == HID_PARAM_INPUT ? "input" : "output"); + break; + + default: + PanicAlert("HidOutput: Unknown type %x and param %x", hidp->type, hidp->param); + break; + } + } extern "C" void Wiimote_Update() { diff --git a/Source/Plugins/Plugin_Wiimote_Test/Src/wiimote_hid.h b/Source/Plugins/Plugin_Wiimote_Test/Src/wiimote_hid.h index 6dc5cf2dcb..46d3a68d18 100644 --- a/Source/Plugins/Plugin_Wiimote_Test/Src/wiimote_hid.h +++ b/Source/Plugins/Plugin_Wiimote_Test/Src/wiimote_hid.h @@ -16,10 +16,10 @@ struct hid_packet { u8 data[0]; }; +#define HID_TYPE_HANDSHAKE 0 #define HID_TYPE_SET_REPORT 5 #define HID_TYPE_DATA 0xA -#define HID_TYPE_HANDSHAKE 0 #define HID_HANDSHAKE_SUCCESS 0 #define HID_PARAM_INPUT 1