Fix wiimote in homebrew

Marginally speed up old wiimote plugin by doing less memcpys
A lot of changes went into the bt dongle emulation, so please test for regressions :)

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6177 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Shawn Hoffman 2010-09-05 20:18:13 +00:00
parent 197202798d
commit 92eedc9cd3
16 changed files with 2454 additions and 2975 deletions

View File

@ -1206,14 +1206,6 @@
<Filter <Filter
Name="IPC HLE" Name="IPC HLE"
> >
<File
RelativePath=".\Src\IPC_HLE\hci.h"
>
</File>
<File
RelativePath=".\Src\IPC_HLE\l2cap.h"
>
</File>
<File <File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE.cpp" RelativePath=".\Src\IPC_HLE\WII_IPC_HLE.cpp"
> >
@ -1226,22 +1218,10 @@
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device.h" RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device.h"
> >
</File> </File>
<File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_Error.h"
>
</File>
<File <File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_stm.h" RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_stm.h"
> >
</File> </File>
<File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_usb.cpp"
>
</File>
<File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_usb.h"
>
</File>
<Filter <Filter
Name="Keyboard" Name="Keyboard"
> >
@ -1255,8 +1235,24 @@
</File> </File>
</Filter> </Filter>
<Filter <Filter
Name="WiiMote" Name="USB/BT/Wiimote"
> >
<File
RelativePath=".\Src\IPC_HLE\hci.h"
>
</File>
<File
RelativePath=".\Src\IPC_HLE\l2cap.h"
>
</File>
<File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_usb.cpp"
>
</File>
<File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_usb.h"
>
</File>
<File <File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_WiiMote.cpp" RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_WiiMote.cpp"
> >
@ -1298,18 +1294,6 @@
> >
</File> </File>
</Filter> </Filter>
<Filter
Name="FileIO"
>
<File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_FileIO.cpp"
>
</File>
<File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_FileIO.h"
>
</File>
</Filter>
<Filter <Filter
Name="DI -DVD Interface" Name="DI -DVD Interface"
> >
@ -1337,6 +1321,14 @@
<Filter <Filter
Name="FS" Name="FS"
> >
<File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_FileIO.cpp"
>
</File>
<File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_FileIO.h"
>
</File>
<File <File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_fs.cpp" RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_fs.cpp"
> >

File diff suppressed because it is too large Load Diff

View File

@ -15,8 +15,7 @@
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#ifndef _WII_IPC_HLE_DEVICE_USB_H_ #pragma once
#define _WII_IPC_HLE_DEVICE_USB_H_
#include "hci.h" #include "hci.h"
#include <vector> #include <vector>
@ -25,21 +24,6 @@
#include "WII_IPC_HLE_Device.h" #include "WII_IPC_HLE_Device.h"
#include "WII_IPC_HLE_WiiMote.h" #include "WII_IPC_HLE_WiiMote.h"
#define HCI_MAX_SIZE 128
#define ACL_MAX_SIZE 128
union UACLHeader
{
struct
{
unsigned ConnectionHandle : 12;
unsigned PBFlag : 2;
unsigned BCFlag : 2;
unsigned Size : 16;
};
u32 Hex;
};
struct SQueuedEvent struct SQueuedEvent
{ {
u8 m_buffer[1024]; u8 m_buffer[1024];
@ -55,6 +39,7 @@ struct SQueuedEvent
// i know this code sux... // i know this code sux...
PanicAlert("SQueuedEvent: allocate too big buffer!!"); PanicAlert("SQueuedEvent: allocate too big buffer!!");
} }
memset(m_buffer, 0, 1024);
} }
}; };
@ -66,7 +51,6 @@ struct SQueuedEvent
class CWII_IPC_HLE_Device_usb_oh1_57e_305 : public IWII_IPC_HLE_Device class CWII_IPC_HLE_Device_usb_oh1_57e_305 : public IWII_IPC_HLE_Device
{ {
public: public:
CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _DeviceID, const std::string& _rDeviceName); CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _DeviceID, const std::string& _rDeviceName);
virtual ~CWII_IPC_HLE_Device_usb_oh1_57e_305(); virtual ~CWII_IPC_HLE_Device_usb_oh1_57e_305();
@ -79,16 +63,13 @@ public:
virtual u32 Update(); virtual u32 Update();
// Send ACL data back to bt stack
void SendACLPacket(u16 _ConnectionHandle, u8* _pData, u32 _Size); void SendACLPacket(u16 _ConnectionHandle, u8* _pData, u32 _Size);
void PurgeACLPool();
void PurgeHCIPool();
bool RemoteDisconnect(u16 _connectionHandle); bool RemoteDisconnect(u16 _connectionHandle);
//hack for wiimote plugin // hack for wiimote plugin
public:
public:
std::vector<CWII_IPC_HLE_WiiMote> m_WiiMotes; std::vector<CWII_IPC_HLE_WiiMote> m_WiiMotes;
CWII_IPC_HLE_WiiMote* AccessWiiMote(const bdaddr_t& _rAddr); CWII_IPC_HLE_WiiMote* AccessWiiMote(const bdaddr_t& _rAddr);
CWII_IPC_HLE_WiiMote* AccessWiiMote(u16 _ConnectionHandle); CWII_IPC_HLE_WiiMote* AccessWiiMote(u16 _ConnectionHandle);
@ -98,28 +79,22 @@ public:
void NetPlay_WiimoteUpdate(int _number); void NetPlay_WiimoteUpdate(int _number);
private: private:
enum USBIOCtl
enum
{ {
USB_IOCTL_HCI_COMMAND_MESSAGE = 0, USBV0_IOCTL_CTRLMSG = 0,
USB_IOCTL_BLKMSG = 1, USBV0_IOCTL_BLKMSG = 1,
USB_IOCTL_INTRMSG = 2, USBV0_IOCTL_INTRMSG = 2,
USB_IOCTL_SUSPENDDEV = 5,
USB_IOCTL_RESUMEDEV = 6,
USB_IOCTL_GETDEVLIST = 12,
USB_IOCTL_DEVREMOVALHOOK = 26,
USB_IOCTL_DEVINSERTHOOK = 27,
}; };
enum enum USBEndpoint
{ {
HCI_EVENT_ENDPOINT = 0x81, HCI_CTRL = 0x00,
ACL_DATA_BLK_OUT = 0x02, HCI_EVENT = 0x81,
ACL_DATA_ENDPOINT = 0x82, ACL_DATA_IN = 0x82,
ACL_DATA_OUT = 0x02
}; };
struct SHCICommandMessage
struct SHCICommandMessage
{ {
u8 bRequestType; u8 bRequestType;
u8 bRequest; u8 bRequest;
@ -132,75 +107,75 @@ private:
u32 m_Address; u32 m_Address;
}; };
struct ACLPool // This is a lightweight/specialized version of SIOCtlVBuffer
{ struct CtrlBuffer
u32 m_number;
u8 m_data[ACL_MAX_SIZE * 16];
ACLPool(int num)
: m_number(num)
{
}
};
struct HCIPool
{
u32 m_number;
u8 m_data[HCI_MAX_SIZE * 16];
u8 m_size[16];
HCIPool(int num)
: m_number(num)
{
}
};
struct CtrlBuffer
{ {
u32 m_address; u32 m_address;
u32 m_buffer; u32 m_buffer;
CtrlBuffer(u32 _Address) CtrlBuffer(u32 _Address) : m_address(_Address), m_buffer()
: m_address(_Address)
{ {
if(_Address == 0) if (m_address)
{ {
m_buffer = 0; u32 InBufferNum = Memory::Read_U32(m_address + 0x10);
} u32 BufferVector = Memory::Read_U32(m_address + 0x18);
else m_buffer = Memory::Read_U32(
{ BufferVector + InBufferNum * sizeof(SIOCtlVBuffer::SBuffer));
u32 _BufferVector = Memory::Read_U32(_Address + 0x18);
u32 _InBufferNum = Memory::Read_U32(_Address + 0x10);
m_buffer = Memory::Read_U32(_BufferVector + _InBufferNum * 8);
} }
} }
inline void FillBuffer(const void* src, const size_t size) const
{
memcpy(Memory::GetPointer(m_buffer), src, size);
}
inline void SetRetVal(const u32 retval) const
{
Memory::Write_U32(retval, m_address + 4);
}
inline bool IsValid() const
{
return m_address != 0;
}
inline void Invalidate()
{
m_address = m_buffer = 0;
}
}; };
bdaddr_t m_ControllerBD; bdaddr_t m_ControllerBD;
u8 m_ClassOfDevice[HCI_CLASS_SIZE];
char m_LocalName[HCI_UNIT_NAME_SIZE]; // this is used to trigger connecting via ACL
u8 m_PINType;
u8 m_ScanEnable; u8 m_ScanEnable;
u8 m_EventFilterType;
u8 m_EventFilterCondition;
u16 m_HostMaxACLSize;
u8 m_HostMaxSCOSize;
u16 m_HostNumACLPackets;
u16 m_HostNumSCOPackets;
// STATE_TO_SAVE
SHCICommandMessage m_CtrlSetup; SHCICommandMessage m_CtrlSetup;
CtrlBuffer m_HCIEndpoint;
std::queue<SQueuedEvent> m_EventQueue;
u32 m_ACLSetup; u32 m_ACLSetup;
CtrlBuffer m_HCIBuffer; CtrlBuffer m_ACLEndpoint;
HCIPool m_HCIPool; struct ACLQ
CtrlBuffer m_ACLBuffer; {
ACLPool m_ACLPool; u8* m_buffer;
u32 m_LastCmd; size_t m_size;
u16 m_conn_handle;
ACLQ(const u8* data, const size_t size, const u16 conn_handle)
: m_size(size), m_conn_handle(conn_handle)
{
m_buffer = new u8[m_size];
memcpy(m_buffer, data, m_size);
}
};
std::queue<ACLQ> m_ACLQ;
u32 m_PacketCount[4]; u32 m_PacketCount[4];
u32 m_FreqDividerMote; u32 m_WiimoteUpdate_Freq;
u32 m_FreqDividerSync; u32 m_NumCompPackets_Freq;
// Send ACL data to a device (wiimote)
void SendToDevice(u16 _ConnectionHandle, u8* _pData, u32 _Size);
// Events // Events
void AddEventToQueue(const SQueuedEvent& _event); void AddEventToQueue(const SQueuedEvent& _event);
@ -216,12 +191,12 @@ private:
bool SendEventReadRemoteVerInfo(u16 _connectionHandle); bool SendEventReadRemoteVerInfo(u16 _connectionHandle);
bool SendEventReadRemoteFeatures(u16 _connectionHandle); bool SendEventReadRemoteFeatures(u16 _connectionHandle);
bool SendEventRoleChange(bdaddr_t _bd, bool _master); bool SendEventRoleChange(bdaddr_t _bd, bool _master);
bool SendEventNumberOfCompletedPackets(u16 _connectionHandle, u16 _count); bool SendEventNumberOfCompletedPackets();
bool SendEventAuthenticationCompleted(u16 _connectionHandle); bool SendEventAuthenticationCompleted(u16 _connectionHandle);
bool SendEventModeChange(u16 _connectionHandle, u8 _mode, u16 _value); bool SendEventModeChange(u16 _connectionHandle, u8 _mode, u16 _value);
bool SendEventDisconnect(u16 _connectionHandle, u8 _Reason); bool SendEventDisconnect(u16 _connectionHandle, u8 _Reason);
bool SendEventRequestLinkKey(const bdaddr_t& _bd); bool SendEventRequestLinkKey(const bdaddr_t& _bd);
bool SendEventLinkKeyNotification(const CWII_IPC_HLE_WiiMote& _rWiiMote); bool SendEventLinkKeyNotification(const u8 num_to_send);
// Execute HCI Message // Execute HCI Message
void ExecuteHCICommandMessage(const SHCICommandMessage& _rCtrlMessage); void ExecuteHCICommandMessage(const SHCICommandMessage& _rCtrlMessage);
@ -271,45 +246,6 @@ private:
void CommandVendorSpecific_FC4C(u8* _Input, u32 _Size); void CommandVendorSpecific_FC4C(u8* _Input, u32 _Size);
void CommandVendorSpecific_FC4F(u8* _Input, u32 _Size); void CommandVendorSpecific_FC4F(u8* _Input, u32 _Size);
void SendToDevice(u16 _ConnectionHandle, u8* _pData, u32 _Size); // Debugging
void LOG_LinkKey(const u8* _pLinkKey); void LOG_LinkKey(const u8* _pLinkKey);
}; };
class CWII_IPC_HLE_Device_usb_oh0 : public IWII_IPC_HLE_Device
{
public:
CWII_IPC_HLE_Device_usb_oh0(u32 _DeviceID, const std::string& _rDeviceName);
virtual ~CWII_IPC_HLE_Device_usb_oh0();
virtual bool Open(u32 _CommandAddress, u32 _Mode);
virtual bool Close(u32 _CommandAddress, bool _bForce); // hermes' dsp demo
virtual bool IOCtlV(u32 _CommandAddress);
virtual bool IOCtl(u32 _CommandAddress);
// virtual u32 Update();
};
// Addresses Human Interface Devices via the Wii's USB 2.0 ports.
// Used by Rock Band 1 + 2 instruments.
class CWII_IPC_HLE_Device_usb_hid : public IWII_IPC_HLE_Device
{
public:
CWII_IPC_HLE_Device_usb_hid(u32 _DeviceID, const std::string& _rDeviceName);
virtual ~CWII_IPC_HLE_Device_usb_hid();
virtual bool Open(u32 _CommandAddress, u32 _Mode);
virtual bool Close(u32 _CommandAddress, bool _bForce);
virtual bool IOCtlV(u32 _CommandAddress);
virtual bool IOCtl(u32 _CommandAddress);
// virtual u32 Update();
};
#endif

View File

@ -24,7 +24,6 @@
#include "../ConfigManager.h" #include "../ConfigManager.h"
#include "../Host.h" #include "../Host.h"
#include "../Core.h" #include "../Core.h"
#include "l2cap.h" // Local #include "l2cap.h" // Local
#include "WiiMote_HID_Attr.h" #include "WiiMote_HID_Attr.h"
@ -48,11 +47,11 @@ CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305*
, m_pHost(_pHost) , m_pHost(_pHost)
{ {
INFO_LOG(WII_IPC_WIIMOTE, "Wiimote: #%i Constructed", _Number); DEBUG_LOG(WII_IPC_WIIMOTE, "Wiimote: #%i Constructed", _Number);
s_Usb = _pHost; s_Usb = _pHost;
m_Connected = (ready) ? 0 : -1; m_ConnectionState = (ready) ? CONN_READY : CONN_INACTIVE;
m_ConnectionHandle = 0x100 + _Number; m_ConnectionHandle = 0x100 + _Number;
memset(m_LinkKey, 0xA0 + _Number, 16); memset(m_LinkKey, 0xA0 + _Number, 16);
@ -82,7 +81,7 @@ CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305*
void CWII_IPC_HLE_WiiMote::DoState(PointerWrap &p) void CWII_IPC_HLE_WiiMote::DoState(PointerWrap &p)
{ {
p.Do(m_Connected); p.Do(m_ConnectionState);
} }
// //
@ -98,21 +97,21 @@ void CWII_IPC_HLE_WiiMote::DoState(PointerWrap &p)
bool CWII_IPC_HLE_WiiMote::LinkChannel() bool CWII_IPC_HLE_WiiMote::LinkChannel()
{ {
if (m_Connected != 2) if (m_ConnectionState != CONN_LINKING)
return false; return false;
// try to connect HID_CONTROL_CHANNEL // try to connect L2CAP_PSM_HID_CNTL
if (!m_HIDControlChannel_Connected) if (!m_HIDControlChannel_Connected)
{ {
if (m_HIDControlChannel_ConnectedWait) if (m_HIDControlChannel_ConnectedWait)
return false; return false;
m_HIDControlChannel_ConnectedWait = true; m_HIDControlChannel_ConnectedWait = true;
SendConnectionRequest(0x0040, HID_CONTROL_CHANNEL); SendConnectionRequest(0x0040, L2CAP_PSM_HID_CNTL);
return true; return true;
} }
// try to config HID_CONTROL_CHANNEL // try to config L2CAP_PSM_HID_CNTL
if (!m_HIDControlChannel_Config) if (!m_HIDControlChannel_Config)
{ {
if (m_HIDControlChannel_ConfigWait) if (m_HIDControlChannel_ConfigWait)
@ -123,18 +122,18 @@ bool CWII_IPC_HLE_WiiMote::LinkChannel()
return true; return true;
} }
// try to connect HID_INTERRUPT_CHANNEL // try to connect L2CAP_PSM_HID_INTR
if (!m_HIDInterruptChannel_Connected) if (!m_HIDInterruptChannel_Connected)
{ {
if (m_HIDInterruptChannel_ConnectedWait) if (m_HIDInterruptChannel_ConnectedWait)
return false; return false;
m_HIDInterruptChannel_ConnectedWait = true; m_HIDInterruptChannel_ConnectedWait = true;
SendConnectionRequest(0x0041, HID_INTERRUPT_CHANNEL); SendConnectionRequest(0x0041, L2CAP_PSM_HID_INTR);
return true; return true;
} }
// try to config HID_INTERRUPT_CHANNEL // try to config L2CAP_PSM_HID_INTR
if (!m_HIDInterruptChannel_Config) if (!m_HIDInterruptChannel_Config)
{ {
if (m_HIDInterruptChannel_ConfigWait) if (m_HIDInterruptChannel_ConfigWait)
@ -145,7 +144,8 @@ bool CWII_IPC_HLE_WiiMote::LinkChannel()
return true; return true;
} }
m_Connected = 3; DEBUG_LOG(WII_IPC_WIIMOTE, "ConnectionState CONN_LINKING -> CONN_COMPLETE");
m_ConnectionState = CONN_COMPLETE;
return false; return false;
} }
@ -162,9 +162,9 @@ bool CWII_IPC_HLE_WiiMote::LinkChannel()
// //
void CWII_IPC_HLE_WiiMote::Activate(bool ready) void CWII_IPC_HLE_WiiMote::Activate(bool ready)
{ {
if (ready && m_Connected == -1) if (ready && (m_ConnectionState == CONN_INACTIVE))
{ {
m_Connected = 0; m_ConnectionState = CONN_READY;
} }
else if (!ready) else if (!ready)
{ {
@ -175,7 +175,8 @@ void CWII_IPC_HLE_WiiMote::Activate(bool ready)
void CWII_IPC_HLE_WiiMote::EventConnectionAccepted() void CWII_IPC_HLE_WiiMote::EventConnectionAccepted()
{ {
m_Connected = 2; DEBUG_LOG(WII_IPC_WIIMOTE, "ConnectionState %x -> CONN_LINKING", m_ConnectionState);
m_ConnectionState = CONN_LINKING;
} }
void CWII_IPC_HLE_WiiMote::EventDisconnect() void CWII_IPC_HLE_WiiMote::EventDisconnect()
@ -184,21 +185,17 @@ void CWII_IPC_HLE_WiiMote::EventDisconnect()
u8 Message = WIIMOTE_DISCONNECT; u8 Message = WIIMOTE_DISCONNECT;
CPluginManager::GetInstance().GetWiimote()->Wiimote_ControlChannel(m_ConnectionHandle & 0xFF, 99, &Message, 0); CPluginManager::GetInstance().GetWiimote()->Wiimote_ControlChannel(m_ConnectionHandle & 0xFF, 99, &Message, 0);
m_Connected = -1; m_ConnectionState = CONN_INACTIVE;
// Clear channel flags // Clear channel flags
ResetChannels(); ResetChannels();
} }
bool CWII_IPC_HLE_WiiMote::EventPagingChanged(u8 _pageMode) bool CWII_IPC_HLE_WiiMote::EventPagingChanged(u8 _pageMode)
{ {
if (m_Connected != 0) if ((m_ConnectionState == CONN_READY) && (_pageMode & HCI_PAGE_SCAN_ENABLE))
return false; return true;
if ((_pageMode & 0x2) == 0) return false;
return false;
m_Connected = 1;
return true;
} }
void CWII_IPC_HLE_WiiMote::ResetChannels() void CWII_IPC_HLE_WiiMote::ResetChannels()
@ -227,75 +224,69 @@ void CWII_IPC_HLE_WiiMote::ResetChannels()
// //
// ===================================================
// This function receives L2CAP commands from the CPU // This function receives L2CAP commands from the CPU
// It's called from SendToDevice() in WII_IPC_HLE_Device_usb.cpp.
// ---------------------------------------------------
void CWII_IPC_HLE_WiiMote::ExecuteL2capCmd(u8* _pData, u32 _Size) void CWII_IPC_HLE_WiiMote::ExecuteL2capCmd(u8* _pData, u32 _Size)
{ {
// Debugger::PrintDataBuffer(LogTypes::WIIMOTE, _pData, _Size, "SendACLPacket: ");
// parse the command // parse the command
SL2CAP_Header* pHeader = (SL2CAP_Header*)_pData; l2cap_hdr_t* pHeader = (l2cap_hdr_t*)_pData;
u8* pData = _pData + sizeof(SL2CAP_Header); u8* pData = _pData + sizeof(l2cap_hdr_t);
u32 DataSize = _Size - sizeof(SL2CAP_Header); u32 DataSize = _Size - sizeof(l2cap_hdr_t);
INFO_LOG(WII_IPC_WIIMOTE, " CID 0x%04x, Len 0x%x, DataSize 0x%x", pHeader->CID, pHeader->Length, DataSize); INFO_LOG(WII_IPC_WIIMOTE, " CID 0x%04x, Len 0x%x, DataSize 0x%x", pHeader->dcid, pHeader->length, DataSize);
if(pHeader->Length != DataSize) if(pHeader->length != DataSize)
{ {
INFO_LOG(WII_IPC_WIIMOTE, "Faulty packet. It is dropped."); INFO_LOG(WII_IPC_WIIMOTE, "Faulty packet. It is dropped.");
return; return;
} }
switch (pHeader->CID) switch (pHeader->dcid)
{ {
case 0x0001: case L2CAP_SIGNAL_CID:
SignalChannel(pData, DataSize); SignalChannel(pData, DataSize);
break; break;
default: default:
{ {
_dbg_assert_msg_(WII_IPC_WIIMOTE, DoesChannelExist(pHeader->CID), "L2CAP: SendACLPacket to unknown channel %i", pHeader->CID); _dbg_assert_msg_(WII_IPC_WIIMOTE, DoesChannelExist(pHeader->dcid), "L2CAP: SendACLPacket to unknown channel %i", pHeader->dcid);
CChannelMap::iterator itr= m_Channel.find(pHeader->CID); CChannelMap::iterator itr= m_Channel.find(pHeader->dcid);
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
const int number = NetPlay_GetWiimoteNum(m_ConnectionHandle & 0xFF); const int number = NetPlay_GetWiimoteNum(m_ConnectionHandle & 0xFF);
#else #else
const int number = 0; const int number = 0;
#endif #endif
Common::PluginWiimote* mote = CPluginManager::GetInstance().GetWiimote(); Common::PluginWiimote* mote = CPluginManager::GetInstance().GetWiimote();
if (itr != m_Channel.end()) if (itr != m_Channel.end())
{ {
SChannel& rChannel = itr->second; SChannel& rChannel = itr->second;
switch(rChannel.PSM) switch (rChannel.PSM)
{ {
case SDP_CHANNEL: case L2CAP_PSM_SDP:
HandleSDP(pHeader->CID, pData, DataSize); HandleSDP(pHeader->dcid, pData, DataSize);
break; break;
case HID_CONTROL_CHANNEL: case L2CAP_PSM_HID_CNTL:
if (number < 4) if (number < 4)
mote->Wiimote_ControlChannel(number, pHeader->CID, pData, DataSize); mote->Wiimote_ControlChannel(number, pHeader->dcid, pData, DataSize);
break; break;
case HID_INTERRUPT_CHANNEL: case L2CAP_PSM_HID_INTR:
{ {
if (number < 4) if (number < 4)
{ {
DEBUG_LOG(WIIMOTE, "Wiimote_InterruptChannel"); DEBUG_LOG(WIIMOTE, "Wiimote_InterruptChannel");
DEBUG_LOG(WIIMOTE, " Channel ID: %04x", pHeader->CID); DEBUG_LOG(WIIMOTE, " Channel ID: %04x", pHeader->dcid);
std::string Temp = ArrayToString((const u8*)pData, DataSize); std::string Temp = ArrayToString((const u8*)pData, DataSize);
DEBUG_LOG(WIIMOTE, " Data: %s", Temp.c_str()); DEBUG_LOG(WIIMOTE, " Data: %s", Temp.c_str());
mote->Wiimote_InterruptChannel(number, pHeader->CID, pData, DataSize); mote->Wiimote_InterruptChannel(number, pHeader->dcid, pData, DataSize);
} }
} }
break; break;
default: default:
ERROR_LOG(WII_IPC_WIIMOTE, "channel 0x04%x has unknown PSM %x", pHeader->CID, rChannel.PSM); ERROR_LOG(WII_IPC_WIIMOTE, "channel 0x04%x has unknown PSM %x", pHeader->dcid, rChannel.PSM);
PanicAlert("WIIMOTE: channel 0x04%x has unknown PSM %x", pHeader->CID, rChannel.PSM);
break; break;
} }
} }
@ -303,55 +294,48 @@ void CWII_IPC_HLE_WiiMote::ExecuteL2capCmd(u8* _pData, u32 _Size)
break; break;
} }
} }
// ================
void CWII_IPC_HLE_WiiMote::SignalChannel(u8* _pData, u32 _Size) void CWII_IPC_HLE_WiiMote::SignalChannel(u8* _pData, u32 _Size)
{ {
while (_Size >= sizeof(SL2CAP_Command)) while (_Size >= sizeof(l2cap_cmd_hdr_t))
{ {
SL2CAP_Command* pCommand = (SL2CAP_Command*)_pData; l2cap_cmd_hdr_t* cmd_hdr = (l2cap_cmd_hdr_t*)_pData;
_pData += sizeof(SL2CAP_Command); _pData += sizeof(l2cap_cmd_hdr_t);
_Size = _Size - sizeof(SL2CAP_Command) - pCommand->len; _Size = _Size - sizeof(l2cap_cmd_hdr_t) - cmd_hdr->length;
switch(pCommand->code) switch (cmd_hdr->code)
{ {
case L2CAP_COMMAND_REJ: case L2CAP_COMMAND_REJ:
ERROR_LOG(WII_IPC_WIIMOTE, "SignalChannel - L2CAP_COMMAND_REJ (something went wrong)." ERROR_LOG(WII_IPC_WIIMOTE, "SignalChannel - L2CAP_COMMAND_REJ (something went wrong)."
"Try to replace your SYSCONF file with a new copy." "Try to replace your SYSCONF file with a new copy.");
,pCommand->code);
PanicAlert(
"SignalChannel - L2CAP_COMMAND_REJ (something went wrong)."
"Try to replace your SYSCONF file with a new copy."
,pCommand->code);
break; break;
case L2CAP_CONN_REQ: case L2CAP_CONNECT_REQ:
ReceiveConnectionReq(pCommand->ident, _pData, pCommand->len); ReceiveConnectionReq(cmd_hdr->ident, _pData, cmd_hdr->length);
break; break;
case L2CAP_CONN_RSP: case L2CAP_CONNECT_RSP:
ReceiveConnectionResponse(pCommand->ident, _pData, pCommand->len); ReceiveConnectionResponse(cmd_hdr->ident, _pData, cmd_hdr->length);
break; break;
case L2CAP_CONF_REQ: case L2CAP_CONFIG_REQ:
ReceiveConfigurationReq(pCommand->ident, _pData, pCommand->len); ReceiveConfigurationReq(cmd_hdr->ident, _pData, cmd_hdr->length);
break; break;
case L2CAP_CONF_RSP: case L2CAP_CONFIG_RSP:
ReceiveConfigurationResponse(pCommand->ident, _pData, pCommand->len); ReceiveConfigurationResponse(cmd_hdr->ident, _pData, cmd_hdr->length);
break; break;
case L2CAP_DISCONN_REQ: case L2CAP_DISCONNECT_REQ:
ReceiveDisconnectionReq(pCommand->ident, _pData, pCommand->len); ReceiveDisconnectionReq(cmd_hdr->ident, _pData, cmd_hdr->length);
break; break;
default: default:
ERROR_LOG(WII_IPC_WIIMOTE, " Unknown Command-Code (0x%02x)", pCommand->code); ERROR_LOG(WII_IPC_WIIMOTE, " Unknown Command-Code (0x%02x)", cmd_hdr->code);
PanicAlert("SignalChannel %x",pCommand->code);
return; return;
} }
_pData += pCommand->len; _pData += cmd_hdr->length;
} }
} }
@ -368,7 +352,7 @@ void CWII_IPC_HLE_WiiMote::SignalChannel(u8* _pData, u32 _Size)
void CWII_IPC_HLE_WiiMote::ReceiveConnectionReq(u8 _Ident, u8* _pData, u32 _Size) void CWII_IPC_HLE_WiiMote::ReceiveConnectionReq(u8 _Ident, u8* _pData, u32 _Size)
{ {
SL2CAP_CommandConnectionReq* pCommandConnectionReq = (SL2CAP_CommandConnectionReq*)_pData; l2cap_con_req_cp* pCommandConnectionReq = (l2cap_con_req_cp*)_pData;
// create the channel // create the channel
SChannel& rChannel = m_Channel[pCommandConnectionReq->scid]; SChannel& rChannel = m_Channel[pCommandConnectionReq->scid];
@ -383,21 +367,29 @@ void CWII_IPC_HLE_WiiMote::ReceiveConnectionReq(u8 _Ident, u8* _pData, u32 _Size
DEBUG_LOG(WII_IPC_WIIMOTE, " DCID: 0x%04x", rChannel.DCID); DEBUG_LOG(WII_IPC_WIIMOTE, " DCID: 0x%04x", rChannel.DCID);
// response // response
SL2CAP_ConnectionResponse Rsp; l2cap_con_rsp_cp Rsp;
Rsp.scid = rChannel.SCID; Rsp.scid = rChannel.SCID;
Rsp.dcid = rChannel.DCID; Rsp.dcid = rChannel.DCID;
Rsp.result = 0x00; Rsp.result = L2CAP_SUCCESS;
Rsp.status = 0x00; Rsp.status = L2CAP_NO_INFO;
INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] SendConnectionResponse"); INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] SendConnectionResponse");
SendCommandToACL(_Ident, L2CAP_CONN_RSP, sizeof(SL2CAP_ConnectionResponse), (u8*)&Rsp); SendCommandToACL(_Ident, L2CAP_CONNECT_RSP, sizeof(l2cap_con_rsp_cp), (u8*)&Rsp);
// update state machine
/*
if (rChannel.PSM == L2CAP_PSM_HID_CNTL)
m_HIDControlChannel_Connected = true;
else if (rChannel.PSM == L2CAP_PSM_HID_INTR)
m_HIDInterruptChannel_Connected = true;
*/
} }
void CWII_IPC_HLE_WiiMote::ReceiveConnectionResponse(u8 _Ident, u8* _pData, u32 _Size) void CWII_IPC_HLE_WiiMote::ReceiveConnectionResponse(u8 _Ident, u8* _pData, u32 _Size)
{ {
l2cap_conn_rsp* rsp = (l2cap_conn_rsp*)_pData; l2cap_con_rsp_cp* rsp = (l2cap_con_rsp_cp*)_pData;
_dbg_assert_(WII_IPC_WIIMOTE, _Size == sizeof(l2cap_conn_rsp)); _dbg_assert_(WII_IPC_WIIMOTE, _Size == sizeof(l2cap_con_rsp_cp));
INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] ReceiveConnectionResponse"); INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] ReceiveConnectionResponse");
DEBUG_LOG(WII_IPC_WIIMOTE, " DCID: 0x%04x", rsp->dcid); DEBUG_LOG(WII_IPC_WIIMOTE, " DCID: 0x%04x", rsp->dcid);
@ -405,32 +397,24 @@ void CWII_IPC_HLE_WiiMote::ReceiveConnectionResponse(u8 _Ident, u8* _pData, u32
DEBUG_LOG(WII_IPC_WIIMOTE, " Result: 0x%04x", rsp->result); DEBUG_LOG(WII_IPC_WIIMOTE, " Result: 0x%04x", rsp->result);
DEBUG_LOG(WII_IPC_WIIMOTE, " Status: 0x%04x", rsp->status); DEBUG_LOG(WII_IPC_WIIMOTE, " Status: 0x%04x", rsp->status);
_dbg_assert_(WII_IPC_WIIMOTE, rsp->result == 0); _dbg_assert_(WII_IPC_WIIMOTE, rsp->result == L2CAP_SUCCESS);
_dbg_assert_(WII_IPC_WIIMOTE, rsp->status == 0); _dbg_assert_(WII_IPC_WIIMOTE, rsp->status == L2CAP_NO_INFO);
_dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(rsp->scid)); _dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(rsp->scid));
SChannel& rChannel = m_Channel[rsp->scid]; SChannel& rChannel = m_Channel[rsp->scid];
rChannel.DCID = rsp->dcid; rChannel.DCID = rsp->dcid;
// // update state machine
// AyuanX: I'm commenting this out because CPU thinks he is faster than WiiMote if (rChannel.PSM == L2CAP_PSM_HID_CNTL)
// and basically CPU will take the initiative to config channel
// in any case we don't want to race against CPU, or we are doomed
// so we wait for CPU to request first
//
/*
if (rChannel.PSM == HID_CONTROL_CHANNEL)
m_HIDControlChannel_Connected = true; m_HIDControlChannel_Connected = true;
else if (rChannel.PSM == L2CAP_PSM_HID_INTR)
if (rChannel.PSM == HID_INTERRUPT_CHANNEL)
m_HIDInterruptChannel_Connected = true; m_HIDInterruptChannel_Connected = true;
*/
} }
void CWII_IPC_HLE_WiiMote::ReceiveConfigurationReq(u8 _Ident, u8* _pData, u32 _Size) void CWII_IPC_HLE_WiiMote::ReceiveConfigurationReq(u8 _Ident, u8* _pData, u32 _Size)
{ {
u32 Offset = 0; u32 Offset = 0;
SL2CAP_CommandConfigurationReq* pCommandConfigReq = (SL2CAP_CommandConfigurationReq*)_pData; l2cap_cfg_req_cp* pCommandConfigReq = (l2cap_cfg_req_cp*)_pData;
_dbg_assert_(WII_IPC_WIIMOTE, pCommandConfigReq->flags == 0x00); // 1 means that the options are send in multi-packets _dbg_assert_(WII_IPC_WIIMOTE, pCommandConfigReq->flags == 0x00); // 1 means that the options are send in multi-packets
_dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(pCommandConfigReq->dcid)); _dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(pCommandConfigReq->dcid));
@ -442,45 +426,41 @@ void CWII_IPC_HLE_WiiMote::ReceiveConfigurationReq(u8 _Ident, u8* _pData, u32 _S
DEBUG_LOG(WII_IPC_WIIMOTE, " DCID: 0x%04x", pCommandConfigReq->dcid); DEBUG_LOG(WII_IPC_WIIMOTE, " DCID: 0x%04x", pCommandConfigReq->dcid);
DEBUG_LOG(WII_IPC_WIIMOTE, " Flags: 0x%04x", pCommandConfigReq->flags); DEBUG_LOG(WII_IPC_WIIMOTE, " Flags: 0x%04x", pCommandConfigReq->flags);
Offset += sizeof(SL2CAP_CommandConfigurationReq); Offset += sizeof(l2cap_cfg_req_cp);
u8 TempBuffer[1024]; u8 TempBuffer[1024];
u32 RespLen = 0; u32 RespLen = 0;
SL2CAP_CommandConfigurationResponse* Rsp = (SL2CAP_CommandConfigurationResponse*)TempBuffer; l2cap_cfg_rsp_cp* Rsp = (l2cap_cfg_rsp_cp*)TempBuffer;
Rsp->scid = rChannel.DCID; Rsp->scid = rChannel.DCID;
Rsp->flags = 0x00; Rsp->flags = 0x00;
Rsp->result = 0x00; Rsp->result = L2CAP_SUCCESS;
RespLen += sizeof(SL2CAP_CommandConfigurationResponse); RespLen += sizeof(l2cap_cfg_rsp_cp);
// read configuration options // read configuration options
while (Offset < _Size) while (Offset < _Size)
{ {
SL2CAP_Options* pOptions = (SL2CAP_Options*)&_pData[Offset]; l2cap_cfg_opt_t* pOptions = (l2cap_cfg_opt_t*)&_pData[Offset];
Offset += sizeof(SL2CAP_Options); Offset += sizeof(l2cap_cfg_opt_t);
switch(pOptions->type) switch (pOptions->type)
{ {
case 0x01: case L2CAP_OPT_MTU:
{ {
_dbg_assert_(WII_IPC_WIIMOTE, pOptions->length == 2); _dbg_assert_(WII_IPC_WIIMOTE, pOptions->length == L2CAP_OPT_MTU_SIZE);
SL2CAP_OptionsMTU* pMTU = (SL2CAP_OptionsMTU*)&_pData[Offset]; l2cap_cfg_opt_val_t* pMTU = (l2cap_cfg_opt_val_t*)&_pData[Offset];
rChannel.MTU = pMTU->MTU; rChannel.MTU = pMTU->mtu;
DEBUG_LOG(WII_IPC_WIIMOTE, " MTU: 0x%04x", pMTU->MTU); DEBUG_LOG(WII_IPC_WIIMOTE, " MTU: 0x%04x", pMTU->mtu);
// AyuanX: My experiment shows that the MTU is always set to 640 bytes
// This means that we only need temp_frame_size of 640B instead 1024B
// Actually I've never seen a frame bigger than 64B
// But... who cares of several KB mem today? Never mind
} }
break; break;
case 0x02: case L2CAP_OPT_FLUSH_TIMO:
{ {
_dbg_assert_(WII_IPC_WIIMOTE, pOptions->length == 2); _dbg_assert_(WII_IPC_WIIMOTE, pOptions->length == L2CAP_OPT_FLUSH_TIMO_SIZE);
SL2CAP_OptionsFlushTimeOut* pFlushTimeOut = (SL2CAP_OptionsFlushTimeOut*)&_pData[Offset]; l2cap_cfg_opt_val_t* pFlushTimeOut = (l2cap_cfg_opt_val_t*)&_pData[Offset];
rChannel.FlushTimeOut = pFlushTimeOut->TimeOut; rChannel.FlushTimeOut = pFlushTimeOut->flush_timo;
DEBUG_LOG(WII_IPC_WIIMOTE, " FlushTimeOut: 0x%04x", pFlushTimeOut->TimeOut); DEBUG_LOG(WII_IPC_WIIMOTE, " FlushTimeOut: 0x%04x", pFlushTimeOut->flush_timo);
} }
break; break;
@ -491,51 +471,44 @@ void CWII_IPC_HLE_WiiMote::ReceiveConfigurationReq(u8 _Ident, u8* _pData, u32 _S
Offset += pOptions->length; Offset += pOptions->length;
u32 OptionSize = sizeof(SL2CAP_Options) + pOptions->length; u32 OptionSize = sizeof(l2cap_cfg_opt_t) + pOptions->length;
memcpy(&TempBuffer[RespLen], pOptions, OptionSize); memcpy(&TempBuffer[RespLen], pOptions, OptionSize);
RespLen += OptionSize; RespLen += OptionSize;
} }
INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] SendConfigurationResponse"); INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] SendConfigurationResponse");
SendCommandToACL(_Ident, L2CAP_CONF_RSP, RespLen, TempBuffer); SendCommandToACL(_Ident, L2CAP_CONFIG_RSP, RespLen, TempBuffer);
// update state machine // update state machine
if (rChannel.PSM == HID_CONTROL_CHANNEL) if (rChannel.PSM == L2CAP_PSM_HID_CNTL)
m_HIDControlChannel_Connected = true; m_HIDControlChannel_Connected = true;
else if (rChannel.PSM == HID_INTERRUPT_CHANNEL) else if (rChannel.PSM == L2CAP_PSM_HID_INTR)
m_HIDInterruptChannel_Connected = true; m_HIDInterruptChannel_Connected = true;
} }
void CWII_IPC_HLE_WiiMote::ReceiveConfigurationResponse(u8 _Ident, u8* _pData, u32 _Size) void CWII_IPC_HLE_WiiMote::ReceiveConfigurationResponse(u8 _Ident, u8* _pData, u32 _Size)
{ {
l2cap_conf_rsp* rsp = (l2cap_conf_rsp*)_pData; l2cap_cfg_rsp_cp* rsp = (l2cap_cfg_rsp_cp*)_pData;
INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] ReceiveConfigurationResponse"); INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] ReceiveConfigurationResponse");
DEBUG_LOG(WII_IPC_WIIMOTE, " SCID: 0x%04x", rsp->scid); DEBUG_LOG(WII_IPC_WIIMOTE, " SCID: 0x%04x", rsp->scid);
DEBUG_LOG(WII_IPC_WIIMOTE, " Flags: 0x%04x", rsp->flags); DEBUG_LOG(WII_IPC_WIIMOTE, " Flags: 0x%04x", rsp->flags);
DEBUG_LOG(WII_IPC_WIIMOTE, " Result: 0x%04x", rsp->result); DEBUG_LOG(WII_IPC_WIIMOTE, " Result: 0x%04x", rsp->result);
_dbg_assert_(WII_IPC_WIIMOTE, rsp->result == 0); _dbg_assert_(WII_IPC_WIIMOTE, rsp->result == L2CAP_SUCCESS);
// update state machine // update state machine
SChannel& rChannel = m_Channel[rsp->scid]; SChannel& rChannel = m_Channel[rsp->scid];
if (rChannel.PSM == HID_CONTROL_CHANNEL) if (rChannel.PSM == L2CAP_PSM_HID_CNTL)
{
m_HIDControlChannel_Config = true; m_HIDControlChannel_Config = true;
INFO_LOG(WII_IPC_WIIMOTE, "Building HID_CONTROL_CHANNEL -- OK"); else if (rChannel.PSM == L2CAP_PSM_HID_INTR)
}
else if (rChannel.PSM == HID_INTERRUPT_CHANNEL)
{
m_HIDInterruptChannel_Config = true; m_HIDInterruptChannel_Config = true;
INFO_LOG(WII_IPC_WIIMOTE, "Building HID_INTERRUPT_CHANNEL -- OK");
}
} }
void CWII_IPC_HLE_WiiMote::ReceiveDisconnectionReq(u8 _Ident, u8* _pData, u32 _Size) void CWII_IPC_HLE_WiiMote::ReceiveDisconnectionReq(u8 _Ident, u8* _pData, u32 _Size)
{ {
SL2CAP_CommandDisconnectionReq* pCommandDisconnectionReq = (SL2CAP_CommandDisconnectionReq*)_pData; l2cap_discon_req_cp* pCommandDisconnectionReq = (l2cap_discon_req_cp*)_pData;
INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] ReceiveDisconnectionReq"); INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] ReceiveDisconnectionReq");
DEBUG_LOG(WII_IPC_WIIMOTE, " Ident: 0x%02x", _Ident); DEBUG_LOG(WII_IPC_WIIMOTE, " Ident: 0x%02x", _Ident);
@ -543,12 +516,12 @@ void CWII_IPC_HLE_WiiMote::ReceiveDisconnectionReq(u8 _Ident, u8* _pData, u32 _S
DEBUG_LOG(WII_IPC_WIIMOTE, " SCID: 0x%04x", pCommandDisconnectionReq->scid); DEBUG_LOG(WII_IPC_WIIMOTE, " SCID: 0x%04x", pCommandDisconnectionReq->scid);
// response // response
SL2CAP_CommandDisconnectionResponse Rsp; l2cap_discon_req_cp Rsp;
Rsp.dcid = pCommandDisconnectionReq->dcid; Rsp.dcid = pCommandDisconnectionReq->dcid;
Rsp.scid = pCommandDisconnectionReq->scid; Rsp.scid = pCommandDisconnectionReq->scid;
INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] SendDisconnectionResponse"); INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] SendDisconnectionResponse");
SendCommandToACL(_Ident, L2CAP_DISCONN_RSP, sizeof(SL2CAP_CommandDisconnectionResponse), (u8*)&Rsp); SendCommandToACL(_Ident, L2CAP_DISCONNECT_RSP, sizeof(l2cap_discon_req_cp), (u8*)&Rsp);
} }
// //
@ -570,25 +543,24 @@ void CWII_IPC_HLE_WiiMote::SendConnectionRequest(u16 scid, u16 psm)
rChannel.PSM = psm; rChannel.PSM = psm;
rChannel.SCID = scid; rChannel.SCID = scid;
l2cap_conn_req cr; l2cap_con_req_cp cr;
cr.psm = psm; cr.psm = psm;
cr.scid = scid; cr.scid = scid;
INFO_LOG(WII_IPC_WIIMOTE, "-----------------------------------------");
INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] SendConnectionRequest"); INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] SendConnectionRequest");
DEBUG_LOG(WII_IPC_WIIMOTE, " Psm: 0x%04x", cr.psm); DEBUG_LOG(WII_IPC_WIIMOTE, " Psm: 0x%04x", cr.psm);
DEBUG_LOG(WII_IPC_WIIMOTE, " Scid: 0x%04x", cr.scid); DEBUG_LOG(WII_IPC_WIIMOTE, " Scid: 0x%04x", cr.scid);
SendCommandToACL(L2CAP_CONN_REQ, L2CAP_CONN_REQ, sizeof(l2cap_conn_req), (u8*)&cr); SendCommandToACL(L2CAP_CONNECT_REQ, L2CAP_CONNECT_REQ, sizeof(l2cap_con_req_cp), (u8*)&cr);
} }
// We don't initiatively disconnet Wiimote though ... // We don't initially disconnect Wiimote though ...
void CWII_IPC_HLE_WiiMote::SendDisconnectRequest(u16 scid) void CWII_IPC_HLE_WiiMote::SendDisconnectRequest(u16 scid)
{ {
// create the channel // create the channel
SChannel& rChannel = m_Channel[scid]; SChannel& rChannel = m_Channel[scid];
l2cap_disconn_req cr; l2cap_discon_req_cp cr;
cr.dcid = rChannel.DCID; cr.dcid = rChannel.DCID;
cr.scid = rChannel.SCID; cr.scid = rChannel.SCID;
@ -596,7 +568,7 @@ void CWII_IPC_HLE_WiiMote::SendDisconnectRequest(u16 scid)
DEBUG_LOG(WII_IPC_WIIMOTE, " Dcid: 0x%04x", cr.dcid); DEBUG_LOG(WII_IPC_WIIMOTE, " Dcid: 0x%04x", cr.dcid);
DEBUG_LOG(WII_IPC_WIIMOTE, " Scid: 0x%04x", cr.scid); DEBUG_LOG(WII_IPC_WIIMOTE, " Scid: 0x%04x", cr.scid);
SendCommandToACL(L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ, sizeof(l2cap_disconn_req), (u8*)&cr); SendCommandToACL(L2CAP_DISCONNECT_REQ, L2CAP_DISCONNECT_REQ, sizeof(l2cap_discon_req_cp), (u8*)&cr);
} }
void CWII_IPC_HLE_WiiMote::SendConfigurationRequest(u16 scid, u16 MTU, u16 FlushTimeOut) void CWII_IPC_HLE_WiiMote::SendConfigurationRequest(u16 scid, u16 MTU, u16 FlushTimeOut)
@ -607,36 +579,43 @@ void CWII_IPC_HLE_WiiMote::SendConfigurationRequest(u16 scid, u16 MTU, u16 Flush
u8 Buffer[1024]; u8 Buffer[1024];
int Offset = 0; int Offset = 0;
l2cap_conf_req* cr = (l2cap_conf_req*)&Buffer[Offset]; l2cap_cfg_req_cp* cr = (l2cap_cfg_req_cp*)&Buffer[Offset];
cr->dcid = rChannel.DCID; cr->dcid = rChannel.DCID;
cr->flags = 0; cr->flags = 0; Offset += sizeof(l2cap_cfg_req_cp);
Offset += sizeof(l2cap_conf_req);
SL2CAP_Options* pOptions;
if (MTU == 0) MTU = rChannel.MTU;
pOptions = (SL2CAP_Options*)&Buffer[Offset];
Offset += sizeof(SL2CAP_Options);
pOptions->type = 1;
pOptions->length = 2;
*(u16*)&Buffer[Offset] = MTU;
Offset += 2;
if (FlushTimeOut == 0) FlushTimeOut = rChannel.FlushTimeOut;
pOptions = (SL2CAP_Options*)&Buffer[Offset];
Offset += sizeof(SL2CAP_Options);
pOptions->type = 2;
pOptions->length = 2;
*(u16*)&Buffer[Offset] = FlushTimeOut;
Offset += 2;
INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] SendConfigurationRequest"); INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] SendConfigurationRequest");
DEBUG_LOG(WII_IPC_WIIMOTE, " Dcid: 0x%04x", cr->dcid); DEBUG_LOG(WII_IPC_WIIMOTE, " Dcid: 0x%04x", cr->dcid);
DEBUG_LOG(WII_IPC_WIIMOTE, " Flags: 0x%04x", cr->flags); DEBUG_LOG(WII_IPC_WIIMOTE, " Flags: 0x%04x", cr->flags);
DEBUG_LOG(WII_IPC_WIIMOTE, " MTU: 0x%04x", MTU);
DEBUG_LOG(WII_IPC_WIIMOTE, " FlushTimeOut: 0x%04x", FlushTimeOut);
SendCommandToACL(L2CAP_CONF_REQ, L2CAP_CONF_REQ, Offset, Buffer); l2cap_cfg_opt_t* pOptions;
// (shuffle2) currently we end up not appending options. this is because we don't
// negotiate after trying to set MTU = 0 fails (stack will respond with
// "configuration failed" msg...). This is still fine, we'll just use whatever the
// bt stack defaults to.
if (MTU || rChannel.MTU)
{
if (MTU == 0)
MTU = rChannel.MTU;
pOptions = (l2cap_cfg_opt_t*)&Buffer[Offset]; Offset += sizeof(l2cap_cfg_opt_t);
pOptions->type = L2CAP_OPT_MTU;
pOptions->length = L2CAP_OPT_MTU_SIZE;
*(u16*)&Buffer[Offset] = MTU; Offset += L2CAP_OPT_MTU_SIZE;
DEBUG_LOG(WII_IPC_WIIMOTE, " MTU: 0x%04x", MTU);
}
if (FlushTimeOut || rChannel.FlushTimeOut)
{
if (FlushTimeOut == 0)
FlushTimeOut = rChannel.FlushTimeOut;
pOptions = (l2cap_cfg_opt_t*)&Buffer[Offset]; Offset += sizeof(l2cap_cfg_opt_t);
pOptions->type = L2CAP_OPT_FLUSH_TIMO;
pOptions->length = L2CAP_OPT_FLUSH_TIMO_SIZE;
*(u16*)&Buffer[Offset] = FlushTimeOut; Offset += L2CAP_OPT_FLUSH_TIMO_SIZE;
DEBUG_LOG(WII_IPC_WIIMOTE, " FlushTimeOut: 0x%04x", FlushTimeOut);
}
SendCommandToACL(L2CAP_CONFIG_REQ, L2CAP_CONFIG_REQ, Offset, Buffer);
} }
@ -674,8 +653,8 @@ void CWII_IPC_HLE_WiiMote::SDPSendServiceSearchResponse(u16 cid, u16 Transaction
CBigEndianBuffer buffer(DataFrame); CBigEndianBuffer buffer(DataFrame);
int Offset = 0; int Offset = 0;
SL2CAP_Header* pHeader = (SL2CAP_Header*)&DataFrame[Offset]; Offset += sizeof(SL2CAP_Header); l2cap_hdr_t* pHeader = (l2cap_hdr_t*)&DataFrame[Offset]; Offset += sizeof(l2cap_hdr_t);
pHeader->CID = cid; pHeader->dcid = cid;
buffer.Write8 (Offset, 0x03); Offset++; buffer.Write8 (Offset, 0x03); Offset++;
buffer.Write16(Offset, TransactionID); Offset += 2; // transaction ID buffer.Write16(Offset, TransactionID); Offset += 2; // transaction ID
@ -686,8 +665,8 @@ void CWII_IPC_HLE_WiiMote::SDPSendServiceSearchResponse(u16 cid, u16 Transaction
buffer.Write8(Offset, 0x00); Offset++; // no continuation state; buffer.Write8(Offset, 0x00); Offset++; // no continuation state;
pHeader->Length = (u16)(Offset - sizeof(SL2CAP_Header)); pHeader->length = (u16)(Offset - sizeof(l2cap_hdr_t));
m_pHost->SendACLPacket(GetConnectionHandle(), DataFrame, pHeader->Length + sizeof(SL2CAP_Header)); m_pHost->SendACLPacket(GetConnectionHandle(), DataFrame, pHeader->length + sizeof(l2cap_hdr_t));
} }
u32 ParseCont(u8* pCont) u32 ParseCont(u8* pCont)
@ -766,18 +745,18 @@ void CWII_IPC_HLE_WiiMote::SDPSendServiceAttributeResponse(u16 cid, u16 Transact
CBigEndianBuffer buffer(DataFrame); CBigEndianBuffer buffer(DataFrame);
int Offset = 0; int Offset = 0;
SL2CAP_Header* pHeader = (SL2CAP_Header*)&DataFrame[Offset]; Offset += sizeof(SL2CAP_Header); l2cap_hdr_t* pHeader = (l2cap_hdr_t*)&DataFrame[Offset]; Offset += sizeof(l2cap_hdr_t);
pHeader->CID = cid; pHeader->dcid = cid;
buffer.Write8 (Offset, 0x05); Offset++; buffer.Write8 (Offset, 0x05); Offset++;
buffer.Write16(Offset, TransactionID); Offset += 2; // transaction ID buffer.Write16(Offset, TransactionID); Offset += 2; // transaction ID
memcpy(buffer.GetPointer(Offset), pPacket, packetSize); Offset += packetSize; memcpy(buffer.GetPointer(Offset), pPacket, packetSize); Offset += packetSize;
pHeader->Length = (u16)(Offset - sizeof(SL2CAP_Header)); pHeader->length = (u16)(Offset - sizeof(l2cap_hdr_t));
m_pHost->SendACLPacket(GetConnectionHandle(), DataFrame, pHeader->Length + sizeof(SL2CAP_Header)); m_pHost->SendACLPacket(GetConnectionHandle(), DataFrame, pHeader->length + sizeof(l2cap_hdr_t));
// Debugger::PrintDataBuffer(LogTypes::WIIMOTE, DataFrame, pHeader->Length + sizeof(SL2CAP_Header), "test response: "); // Debugger::PrintDataBuffer(LogTypes::WIIMOTE, DataFrame, pHeader->length + sizeof(l2cap_hdr_t), "test response: ");
} }
void CWII_IPC_HLE_WiiMote::HandleSDP(u16 cid, u8* _pData, u32 _Size) void CWII_IPC_HLE_WiiMote::HandleSDP(u16 cid, u8* _pData, u32 _Size)
@ -850,14 +829,14 @@ void CWII_IPC_HLE_WiiMote::SendCommandToACL(u8 _Ident, u8 _Code, u8 _CommandLeng
u8 DataFrame[1024]; u8 DataFrame[1024];
u32 Offset = 0; u32 Offset = 0;
SL2CAP_Header* pHeader = (SL2CAP_Header*)&DataFrame[Offset]; Offset += sizeof(SL2CAP_Header); l2cap_hdr_t* pHeader = (l2cap_hdr_t*)&DataFrame[Offset]; Offset += sizeof(l2cap_hdr_t);
pHeader->Length = sizeof(SL2CAP_Command) + _CommandLength; pHeader->length = sizeof(l2cap_cmd_hdr_t) + _CommandLength;
pHeader->CID = 0x0001; pHeader->dcid = L2CAP_SIGNAL_CID;
SL2CAP_Command* pCommand = (SL2CAP_Command*)&DataFrame[Offset]; Offset += sizeof(SL2CAP_Command); l2cap_cmd_hdr_t* pCommand = (l2cap_cmd_hdr_t*)&DataFrame[Offset]; Offset += sizeof(l2cap_cmd_hdr_t);
pCommand->code = _Code; pCommand->code = _Code;
pCommand->ident = _Ident; pCommand->ident = _Ident;
pCommand->len = _CommandLength; pCommand->length = _CommandLength;
memcpy(&DataFrame[Offset], _pCommandData, _CommandLength); memcpy(&DataFrame[Offset], _pCommandData, _CommandLength);
@ -866,36 +845,31 @@ void CWII_IPC_HLE_WiiMote::SendCommandToACL(u8 _Ident, u8 _Code, u8 _CommandLeng
DEBUG_LOG(WII_IPC_WIIMOTE, " Code: 0x%02x", _Code); DEBUG_LOG(WII_IPC_WIIMOTE, " Code: 0x%02x", _Code);
// send .... // send ....
m_pHost->SendACLPacket(GetConnectionHandle(), DataFrame, pHeader->Length + sizeof(SL2CAP_Header)); m_pHost->SendACLPacket(GetConnectionHandle(), DataFrame, pHeader->length + sizeof(l2cap_hdr_t));
// Debugger::PrintDataBuffer(LogTypes::WIIMOTE, DataFrame, pHeader->Length + sizeof(SL2CAP_Header), "m_pHost->SendACLPacket: "); //Debugger::PrintDataBuffer(LogTypes::WIIMOTE, DataFrame, pHeader->length + sizeof(l2cap_hdr_t), "m_pHost->SendACLPacket: ");
} }
// ===================================================
// On a second boot the _dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(scid)) makes a report.
// However the game eventually starts and the Wiimote connects, but it takes at least ten seconds.
// ---------------------------------------------------
void CWII_IPC_HLE_WiiMote::ReceiveL2capData(u16 scid, const void* _pData, u32 _Size) void CWII_IPC_HLE_WiiMote::ReceiveL2capData(u16 scid, const void* _pData, u32 _Size)
{ {
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
if (NetPlay_WiimoteInput(m_ConnectionHandle & 0xFF, scid, _pData, _Size)) if (NetPlay_WiimoteInput(m_ConnectionHandle & 0xFF, scid, _pData, _Size))
return; return;
#endif #endif
// Allocate DataFrame // Allocate DataFrame
u8 DataFrame[1024]; u8 DataFrame[1024];
u32 Offset = 0; u32 Offset = 0;
SL2CAP_Header* pHeader = (SL2CAP_Header*)DataFrame; l2cap_hdr_t* pHeader = (l2cap_hdr_t*)DataFrame;
Offset += sizeof(SL2CAP_Header); Offset += sizeof(l2cap_hdr_t);
// Check if we are already reporting on this channel // Check if we are already reporting on this channel
_dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(scid)); _dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(scid));
SChannel& rChannel = m_Channel[scid]; SChannel& rChannel = m_Channel[scid];
// Add an additonal 4 byte header to the Wiimote report // Add an additional 4 byte header to the Wiimote report
pHeader->CID = rChannel.DCID; pHeader->dcid = rChannel.DCID;
pHeader->Length = _Size; pHeader->length = _Size;
// Copy the Wiimote report to DataFrame // Copy the Wiimote report to DataFrame
memcpy(DataFrame + Offset, _pData, _Size); memcpy(DataFrame + Offset, _pData, _Size);
@ -922,7 +896,7 @@ namespace Core
INFO_LOG(WIIMOTE, "===================="); INFO_LOG(WIIMOTE, "====================");
INFO_LOG(WIIMOTE, "Callback_WiimoteInterruptChannel: (Wiimote: #%i)", _number); INFO_LOG(WIIMOTE, "Callback_WiimoteInterruptChannel: (Wiimote: #%i)", _number);
DEBUG_LOG(WIIMOTE, " Data: %s", ArrayToString(pData, _Size, 0, 50).c_str()); DEBUG_LOG(WIIMOTE, " Data: %s", ArrayToString(pData, _Size, 0, 50).c_str());
DEBUG_LOG(WIIMOTE, " Channel: %u", _channelID); DEBUG_LOG(WIIMOTE, " Channel: %x", _channelID);
s_Usb->m_WiiMotes[_number].ReceiveL2capData(_channelID, _pData, _Size); s_Usb->m_WiiMotes[_number].ReceiveL2capData(_channelID, _pData, _Size);
} }

View File

@ -26,111 +26,6 @@ class CWII_IPC_HLE_Device_usb_oh1_57e_305;
CWII_IPC_HLE_Device_usb_oh1_57e_305* GetUsbPointer(); CWII_IPC_HLE_Device_usb_oh1_57e_305* GetUsbPointer();
enum
{
SDP_CHANNEL = 0x01,
HID_CONTROL_CHANNEL = 0x11,
HID_INTERRUPT_CHANNEL= 0x13,
// L2CAP command codes
L2CAP_COMMAND_REJ = 0x01,
L2CAP_CONN_REQ = 0x02,
L2CAP_CONN_RSP = 0x03,
L2CAP_CONF_REQ = 0x04,
L2CAP_CONF_RSP = 0x05,
L2CAP_DISCONN_REQ = 0x06,
L2CAP_DISCONN_RSP = 0x07,
L2CAP_ECHO_REQ = 0x08,
L2CAP_ECHO_RSP = 0x09,
L2CAP_INFO_REQ = 0x0a,
L2CAP_INFO_RSP = 0x0b,
// connect result
L2CAP_CR_SUCCESS = 0x0000,
L2CAP_CR_PEND = 0x0001,
L2CAP_CR_BAD_PSM = 0x0002,
L2CAP_CR_SEC_BLOCK = 0x0003,
L2CAP_CR_NO_MEM = 0x0004,
//connect status
L2CAP_CS_NO_INFO = 0x0000,
L2CAP_CS_AUTHEN_PEND = 0x0001,
L2CAP_CS_AUTHOR_PEND = 0x0002,
};
#pragma pack(push, 1)
struct SL2CAP_Header
{
u16 Length;
u16 CID;
};
struct SL2CAP_Command
{
u8 code;
u8 ident;
u16 len;
};
struct SL2CAP_CommandConnectionReq // 0x02
{
u16 psm;
u16 scid;
};
struct SL2CAP_ConnectionResponse // 0x03
{
u16 dcid;
u16 scid;
u16 result;
u16 status;
};
struct SL2CAP_Options
{
u8 type;
u8 length;
};
struct SL2CAP_OptionsMTU
{
u16 MTU;
};
struct SL2CAP_OptionsFlushTimeOut
{
u16 TimeOut;
};
struct SL2CAP_CommandConfigurationReq // 0x04
{
u16 dcid;
u16 flags;
};
struct SL2CAP_CommandConfigurationResponse // 0x05
{
u16 scid;
u16 flags;
u16 result;
};
struct SL2CAP_CommandDisconnectionReq // 0x06
{
u16 dcid;
u16 scid;
};
struct SL2CAP_CommandDisconnectionResponse // 0x07
{
u16 dcid;
u16 scid;
};
#pragma pack(pop)
class CBigEndianBuffer class CBigEndianBuffer
{ {
public: public:
@ -163,7 +58,7 @@ public:
// ugly Host handling.... // ugly Host handling....
// we really have to clean all this code // we really have to clean all this code
int IsConnected() const { return m_Connected; } bool IsConnected() const { return m_ConnectionState == CONN_COMPLETE; }
bool LinkChannel(); bool LinkChannel();
void ResetChannels(); void ResetChannels();
void Activate(bool ready); void Activate(bool ready);
@ -188,8 +83,14 @@ public:
const u8* GetLinkKey() const { return m_LinkKey; } const u8* GetLinkKey() const { return m_LinkKey; }
private: private:
// -1: inactive, 0: ready, 1: connecting 2: linking 3: connected & linked enum ConnectionState
int m_Connected; {
CONN_INACTIVE = -1,
CONN_READY,
CONN_LINKING,
CONN_COMPLETE
};
ConnectionState m_ConnectionState;
bool m_HIDControlChannel_Connected; bool m_HIDControlChannel_Connected;
bool m_HIDControlChannel_ConnectedWait; bool m_HIDControlChannel_ConnectedWait;
@ -207,7 +108,7 @@ private:
u8 features[HCI_FEATURES_SIZE]; u8 features[HCI_FEATURES_SIZE];
u8 lmp_version; u8 lmp_version;
u16 lmp_subversion; u16 lmp_subversion;
u8 m_LinkKey[16]; u8 m_LinkKey[HCI_KEY_SIZE];
std::string m_Name; std::string m_Name;
CWII_IPC_HLE_Device_usb_oh1_57e_305* m_pHost; CWII_IPC_HLE_Device_usb_oh1_57e_305* m_pHost;

File diff suppressed because it is too large Load Diff

View File

@ -1,353 +1,353 @@
/* /* $NetBSD: l2cap.h,v 1.9 2009/09/13 18:45:11 pooka Exp $ */
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2000-2001 Qualcomm Incorporated
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> /*-
* Copyright (c) 2005 Iain Hibbert.
This program is free software; you can redistribute it and/or modify * Copyright (c) 2006 Itronix Inc.
it under the terms of the GNU General Public License version 2 as * All rights reserved.
published by the Free Software Foundation; *
* Redistribution and use in source and binary forms, with or without
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * modification, are permitted provided that the following conditions
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * are met:
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. * 1. Redistributions of source code must retain the above copyright
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY * notice, this list of conditions and the following disclaimer.
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES * 2. Redistributions in binary form must reproduce the above copyright
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * notice, this list of conditions and the following disclaimer in the
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * documentation and/or other materials provided with the distribution.
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * 3. The name of Itronix Inc. may not be used to endorse
* or promote products derived from this software without specific
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, * prior written permission.
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS *
SOFTWARE IS DISCLAIMED. * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*-
* Copyright (c) Maksim Yevmenkin <m_evmenkin@yahoo.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: l2cap.h,v 1.9 2009/09/13 18:45:11 pooka Exp $
* $FreeBSD: src/sys/netgraph/bluetooth/include/l2cap.h,v 1.4 2005/08/31 18:13:23 emax Exp $
*/ */
#ifndef __L2CAP_H /*
#define __L2CAP_H * This file contains everything that application needs to know about
* Link Layer Control and Adaptation Protocol (L2CAP). All information
* was obtained from Bluetooth Specification Books (v1.1 and up)
*
* This file can be included by both kernel and userland applications.
*/
//Dolphin - define missing types #pragma once
typedef unsigned short __le16;
typedef unsigned short __u16;
typedef unsigned char __u8;
typedef unsigned long __u32;
#pragma pack(push) /**************************************************************************
#pragma pack(1) **************************************************************************
** Common defines and types (L2CAP)
**************************************************************************
**************************************************************************/
#ifdef _MSC_VER /*
#pragma warning(push) * Channel IDs are assigned per machine. So the total number of channels that
#pragma warning(disable:4200) * a machine can have open at the same time is 0xffff - 0x0040 = 0xffbf (65471).
#endif * This number does not depend on number of HCI connections.
*/
/* L2CAP defaults */ #define L2CAP_NULL_CID 0x0000 /* DO NOT USE THIS CID */
#define L2CAP_DEFAULT_MTU 672 #define L2CAP_SIGNAL_CID 0x0001 /* signaling channel ID */
#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF #define L2CAP_CLT_CID 0x0002 /* connectionless channel ID */
/* 0x0003 - 0x003f Reserved */
#define L2CAP_FIRST_CID 0x0040 /* dynamically alloc. (start) */
#define L2CAP_LAST_CID 0xffff /* dynamically alloc. (end) */
#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */ /* L2CAP MTU */
#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */ #define L2CAP_MTU_MINIMUM 48
#define L2CAP_MTU_DEFAULT 672
#define L2CAP_MTU_MAXIMUM 0xffff
/* L2CAP socket address */ /* L2CAP flush and link timeouts */
#ifdef NOT_DOLPHIN #define L2CAP_FLUSH_TIMO_DEFAULT 0xffff /* always retransmit */
struct sockaddr_l2 { #define L2CAP_LINK_TIMO_DEFAULT 0xffff
sa_family_t l2_family;
__le16 l2_psm;
bdaddr_t l2_bdaddr;
};
#endif
/* L2CAP socket options */ /* L2CAP Command Reject reasons */
#define L2CAP_OPTIONS 0x01 #define L2CAP_REJ_NOT_UNDERSTOOD 0x0000
struct l2cap_options { #define L2CAP_REJ_MTU_EXCEEDED 0x0001
__u16 omtu; #define L2CAP_REJ_INVALID_CID 0x0002
__u16 imtu; /* 0x0003 - 0xffff - reserved for future use */
__u16 flush_to;
__u8 mode;
};
#define L2CAP_CONNINFO 0x02 /* Protocol/Service Multiplexor (PSM) values */
struct l2cap_conninfo { #define L2CAP_PSM_ANY 0x0000 /* Any/Invalid PSM */
__u16 hci_handle; #define L2CAP_PSM_SDP 0x0001 /* Service Discovery Protocol */
__u8 dev_class[3]; #define L2CAP_PSM_RFCOMM 0x0003 /* RFCOMM protocol */
}; #define L2CAP_PSM_TCP 0x0005 /* Telephony Control Protocol */
#define L2CAP_PSM_TCS 0x0007 /* TCS cordless */
#define L2CAP_PSM_BNEP 0x000f /* Bluetooth Network */
/* Encapsulation Protocol*/
#define L2CAP_PSM_HID_CNTL 0x0011 /* HID Control */
#define L2CAP_PSM_HID_INTR 0x0013 /* HID Interrupt */
#define L2CAP_PSM_ESDP 0x0015 /* Extended Service */
/* Discovery Profile */
#define L2CAP_PSM_AVCTP 0x0017 /* Audio/Visual Control */
/* Transport Protocol */
#define L2CAP_PSM_AVDTP 0x0019 /* Audio/Visual Distribution */
/* Transport Protocol */
/* 0x0019 - 0x1000 - reserved for future use */
#define L2CAP_LM 0x03 #define L2CAP_PSM_INVALID(psm) (((psm) & 0x0101) != 0x0001)
#define L2CAP_LM_MASTER 0x0001
#define L2CAP_LM_AUTH 0x0002
#define L2CAP_LM_ENCRYPT 0x0004
#define L2CAP_LM_TRUSTED 0x0008
#define L2CAP_LM_RELIABLE 0x0010
#define L2CAP_LM_SECURE 0x0020
/* L2CAP command codes */ /* L2CAP Connection response command result codes */
#define L2CAP_COMMAND_REJ 0x01 #define L2CAP_SUCCESS 0x0000
#define L2CAP_CONN_REQ 0x02 #define L2CAP_PENDING 0x0001
#define L2CAP_CONN_RSP 0x03 #define L2CAP_PSM_NOT_SUPPORTED 0x0002
#define L2CAP_CONF_REQ 0x04 #define L2CAP_SECURITY_BLOCK 0x0003
#define L2CAP_CONF_RSP 0x05 #define L2CAP_NO_RESOURCES 0x0004
#define L2CAP_DISCONN_REQ 0x06 #define L2CAP_TIMEOUT 0xeeee
#define L2CAP_DISCONN_RSP 0x07 #define L2CAP_UNKNOWN 0xffff
#define L2CAP_ECHO_REQ 0x08 /* 0x0005 - 0xffff - reserved for future use */
#define L2CAP_ECHO_RSP 0x09
#define L2CAP_INFO_REQ 0x0a
#define L2CAP_INFO_RSP 0x0b
/* L2CAP structures */ /* L2CAP Connection response status codes */
struct l2cap_hdr { #define L2CAP_NO_INFO 0x0000
__le16 len; #define L2CAP_AUTH_PENDING 0x0001
__le16 cid; #define L2CAP_AUTZ_PENDING 0x0002
}; /* 0x0003 - 0xffff - reserved for future use */
#define L2CAP_HDR_SIZE 4
struct l2cap_cmd_hdr { /* L2CAP Configuration response result codes */
__u8 code; #define L2CAP_UNACCEPTABLE_PARAMS 0x0001
__u8 ident; #define L2CAP_REJECT 0x0002
__le16 len; #define L2CAP_UNKNOWN_OPTION 0x0003
}; /* 0x0003 - 0xffff - reserved for future use */
#define L2CAP_CMD_HDR_SIZE 4
struct l2cap_cmd_rej { /* L2CAP Configuration options */
__le16 reason; #define L2CAP_OPT_CFLAG_BIT 0x0001
}; #define L2CAP_OPT_CFLAG(flags) ((flags) & L2CAP_OPT_CFLAG_BIT)
#define L2CAP_OPT_HINT_BIT 0x80
#define L2CAP_OPT_HINT(type) ((type) & L2CAP_OPT_HINT_BIT)
#define L2CAP_OPT_HINT_MASK 0x7f
#define L2CAP_OPT_MTU 0x01
#define L2CAP_OPT_MTU_SIZE sizeof(uint16_t)
#define L2CAP_OPT_FLUSH_TIMO 0x02
#define L2CAP_OPT_FLUSH_TIMO_SIZE sizeof(uint16_t)
#define L2CAP_OPT_QOS 0x03
#define L2CAP_OPT_QOS_SIZE sizeof(l2cap_qos_t)
#define L2CAP_OPT_RFC 0x04
#define L2CAP_OPT_RFC_SIZE sizeof(l2cap_rfc_t)
/* 0x05 - 0xff - reserved for future use */
struct l2cap_conn_req { /* L2CAP Information request type codes */
__le16 psm; #define L2CAP_CONNLESS_MTU 0x0001
__le16 scid; #define L2CAP_EXTENDED_FEATURES 0x0002
}; /* 0x0003 - 0xffff - reserved for future use */
struct l2cap_conn_rsp { /* L2CAP Information response codes */
__le16 dcid; #define L2CAP_NOT_SUPPORTED 0x0001
__le16 scid; /* 0x0002 - 0xffff - reserved for future use */
__le16 result;
__le16 status;
};
/* connect result */ #pragma pack(push, 1)
#define L2CAP_CR_SUCCESS 0x0000
#define L2CAP_CR_PEND 0x0001
#define L2CAP_CR_BAD_PSM 0x0002
#define L2CAP_CR_SEC_BLOCK 0x0003
#define L2CAP_CR_NO_MEM 0x0004
/* connect status */ /* L2CAP Quality of Service option */
#define L2CAP_CS_NO_INFO 0x0000 typedef struct {
#define L2CAP_CS_AUTHEN_PEND 0x0001 uint8_t flags; /* reserved for future use */
#define L2CAP_CS_AUTHOR_PEND 0x0002 uint8_t service_type; /* service type */
uint32_t token_rate; /* bytes per second */
uint32_t token_bucket_size; /* bytes */
uint32_t peak_bandwidth; /* bytes per second */
uint32_t latency; /* microseconds */
uint32_t delay_variation; /* microseconds */
} l2cap_qos_t;
struct l2cap_conf_req { /* L2CAP QoS type */
__le16 dcid; #define L2CAP_QOS_NO_TRAFFIC 0x00
__le16 flags; #define L2CAP_QOS_BEST_EFFORT 0x01 /* (default) */
__u8 data[0]; #define L2CAP_QOS_GUARANTEED 0x02
}; /* 0x03 - 0xff - reserved for future use */
struct l2cap_conf_rsp { /* L2CAP Retransmission & Flow Control option */
__le16 scid; typedef struct {
__le16 flags; uint8_t mode; /* RFC mode */
__le16 result; uint8_t window_size; /* bytes */
__u8 data[0]; uint8_t max_transmit; /* max retransmissions */
}; uint16_t retransmit_timo; /* milliseconds */
uint16_t monitor_timo; /* milliseconds */
uint16_t max_pdu_size; /* bytes */
} l2cap_rfc_t;
#define L2CAP_CONF_SUCCESS 0x0000 /* L2CAP RFC mode */
#define L2CAP_CONF_UNACCEPT 0x0001 #define L2CAP_RFC_BASIC 0x00 /* (default) */
#define L2CAP_CONF_REJECT 0x0002 #define L2CAP_RFC_RETRANSMIT 0x01
#define L2CAP_CONF_UNKNOWN 0x0003 #define L2CAP_RFC_FLOW 0x02
/* 0x03 - 0xff - reserved for future use */
struct l2cap_conf_opt { /**************************************************************************
__u8 type; **************************************************************************
__u8 len; ** Link level defines, headers and types
__u8 val[0]; **************************************************************************
}; **************************************************************************/
#define L2CAP_CONF_OPT_SIZE 2
#define L2CAP_CONF_MTU 0x01 /* L2CAP header */
#define L2CAP_CONF_FLUSH_TO 0x02 typedef struct {
#define L2CAP_CONF_QOS 0x03 uint16_t length; /* payload size */
#define L2CAP_CONF_RFC 0x04 uint16_t dcid; /* destination channel ID */
} l2cap_hdr_t;
#define L2CAP_CONF_MAX_SIZE 22 /* L2CAP ConnectionLess Traffic (dcid == L2CAP_CLT_CID) */
typedef struct {
uint16_t psm; /* Protocol/Service Multiplexor */
} l2cap_clt_hdr_t;
struct l2cap_conf_rfc { #define L2CAP_CLT_MTU_MAXIMUM \
__u8 mode; (L2CAP_MTU_MAXIMUM - sizeof(l2cap_clt_hdr_t))
__u8 txwin_size;
__u8 max_transmit;
__le16 retrans_timeout;
__le16 monitor_timeout;
__le16 max_pdu_size;
};
#define L2CAP_MODE_BASIC 0x00 /* L2CAP Command header (dcid == L2CAP_SIGNAL_CID) */
#define L2CAP_MODE_RETRANS 0x01 typedef struct {
#define L2CAP_MODE_FLOWCTL 0x02 uint8_t code; /* command OpCode */
uint8_t ident; /* identifier to match request and response */
uint16_t length; /* command parameters length */
} l2cap_cmd_hdr_t;
struct l2cap_disconn_req { /* L2CAP Command Reject */
__le16 dcid; #define L2CAP_COMMAND_REJ 0x01
__le16 scid; typedef struct {
}; uint16_t reason; /* reason to reject command */
uint16_t data[2];/* optional data */
} l2cap_cmd_rej_cp;
struct l2cap_disconn_rsp { /* L2CAP Connection Request */
__le16 dcid; #define L2CAP_CONNECT_REQ 0x02
__le16 scid; typedef struct {
}; uint16_t psm; /* Protocol/Service Multiplexor (PSM) */
uint16_t scid; /* source channel ID */
} l2cap_con_req_cp;
struct l2cap_info_req { /* L2CAP Connection Response */
__le16 type; #define L2CAP_CONNECT_RSP 0x03
}; typedef struct {
uint16_t dcid; /* destination channel ID */
uint16_t scid; /* source channel ID */
uint16_t result; /* 0x00 - success */
uint16_t status; /* more info if result != 0x00 */
} l2cap_con_rsp_cp;
struct l2cap_info_rsp { /* L2CAP Configuration Request */
__le16 type; #define L2CAP_CONFIG_REQ 0x04
__le16 result; typedef struct {
__u8 data[0]; uint16_t dcid; /* destination channel ID */
}; uint16_t flags; /* flags */
/* uint8_t options[] -- options */
} l2cap_cfg_req_cp;
/* info type */ /* L2CAP Configuration Response */
#define L2CAP_IT_CL_MTU 0x0001 #define L2CAP_CONFIG_RSP 0x05
#define L2CAP_IT_FEAT_MASK 0x0002 typedef struct {
uint16_t scid; /* source channel ID */
uint16_t flags; /* flags */
uint16_t result; /* 0x00 - success */
/* uint8_t options[] -- options */
} l2cap_cfg_rsp_cp;
/* info result */ /* L2CAP configuration option */
#define L2CAP_IR_SUCCESS 0x0000 typedef struct {
#define L2CAP_IR_NOTSUPP 0x0001 uint8_t type;
uint8_t length;
/* uint8_t value[] -- option value (depends on type) */
} l2cap_cfg_opt_t;
/* L2CAP configuration option value */
typedef union {
uint16_t mtu; /* L2CAP_OPT_MTU */
uint16_t flush_timo; /* L2CAP_OPT_FLUSH_TIMO */
l2cap_qos_t qos; /* L2CAP_OPT_QOS */
l2cap_rfc_t rfc; /* L2CAP_OPT_RFC */
} l2cap_cfg_opt_val_t;
/* L2CAP Disconnect Request */
#define L2CAP_DISCONNECT_REQ 0x06
typedef struct {
uint16_t dcid; /* destination channel ID */
uint16_t scid; /* source channel ID */
} l2cap_discon_req_cp;
/* L2CAP Disconnect Response */
#define L2CAP_DISCONNECT_RSP 0x07
typedef l2cap_discon_req_cp l2cap_discon_rsp_cp;
/* L2CAP Echo Request */
#define L2CAP_ECHO_REQ 0x08
/* No command parameters, only optional data */
/* L2CAP Echo Response */
#define L2CAP_ECHO_RSP 0x09
#define L2CAP_MAX_ECHO_SIZE \
(L2CAP_MTU_MAXIMUM - sizeof(l2cap_cmd_hdr_t))
/* No command parameters, only optional data */
/* L2CAP Information Request */
#define L2CAP_INFO_REQ 0x0a
typedef struct {
uint16_t type; /* requested information type */
} l2cap_info_req_cp;
/* L2CAP Information Response */
#define L2CAP_INFO_RSP 0x0b
typedef struct {
uint16_t type; /* requested information type */
uint16_t result; /* 0x00 - success */
/* uint8_t info[] -- info data (depends on type)
*
* L2CAP_CONNLESS_MTU - 2 bytes connectionless MTU
*/
} l2cap_info_rsp_cp;
typedef union {
/* L2CAP_CONNLESS_MTU */
struct {
uint16_t mtu;
} mtu;
} l2cap_info_rsp_data_t;
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#pragma pack(pop) #pragma pack(pop)
struct value_string /**************************************************************************
{ **************************************************************************
u32 value; ** L2CAP Socket Definitions
char* string; **************************************************************************
}; **************************************************************************/
static const value_string command_code_vals[] = { /* Socket options */
{ 0x01, (char *)"Command Reject" }, #define SO_L2CAP_IMTU 1 /* incoming MTU */
{ 0x02, (char *)"Connection Request" }, #define SO_L2CAP_OMTU 2 /* outgoing MTU */
{ 0x03, (char *)"Connection Response" }, #define SO_L2CAP_IQOS 3 /* incoming QoS */
{ 0x04, (char *)"Configure Request" }, #define SO_L2CAP_OQOS 4 /* outgoing QoS */
{ 0x05, (char *)"Configure Response" }, #define SO_L2CAP_FLUSH 5 /* flush timeout */
{ 0x06, (char *)"Disconnect Request" }, #define SO_L2CAP_LM 6 /* link mode */
{ 0x07, (char *)"Disconnect Response" },
{ 0x08, (char *)"Echo Request" },
{ 0x09, (char *)"Echo Response" },
{ 0x0A, (char *)"Information Request" },
{ 0x0B, (char *)"Information Response" },
{ 0, NULL }
};
/* L2CAP link mode flags */
#define L2CAP_LM_AUTH (1<<0) /* want authentication */
static const value_string psm_vals[] = { #define L2CAP_LM_ENCRYPT (1<<1) /* want encryption */
{ 0x0001, (char *)"SDP" }, #define L2CAP_LM_SECURE (1<<2) /* want secured link */
{ 0x0003, (char *)"RFCOMM" },
{ 0x0005, (char *)"TCS-BIN" },
{ 0x0007, (char *)"TCS-BIN-CORDLESS" },
{ 0x000F, (char *)"BNEP" },
{ 0x0011, (char *)"HID_CONTROL" },
{ 0x0013, (char *)"HID_INTERRUPT" },
{ 0x0015, (char *)"UPnP" },
{ 0x0017, (char *)"AVCTP" },
{ 0x0019, (char *)"AVDTP" },
{ 0x001D, (char *)"UDI_C-Plane" },
{ 0, NULL }
};
static const value_string result_vals[] = {
{ 0x0000, (char *)"Connection successful" },
{ 0x0001, (char *)"Connection pending" },
{ 0x0002, (char *)"Connection Refused - PSM not supported" },
{ 0x0003, (char *)"Connection refused - security block" },
{ 0x0004, (char *)"Connection refused - no resources available" },
{ 0, NULL }
};
static const value_string status_vals[] = {
{ 0x0000, (char *)"No further information available" },
{ 0x0001, (char *)"Authentication panding" },
{ 0x0002, (char *)"Authorization pending" },
{ 0, NULL }
};
#ifdef NOT_DOLPHIN
/* ----- L2CAP connections ----- */
struct l2cap_chan_list {
struct sock *head;
rwlock_t lock;
long num;
};
struct l2cap_conn {
struct hci_conn *hcon;
bdaddr_t *dst;
bdaddr_t *src;
unsigned int mtu;
__u32 feat_mask;
__u8 info_state;
__u8 info_ident;
struct timer_list info_timer;
spinlock_t lock;
struct sk_buff *rx_skb;
__u32 rx_len;
__u8 rx_ident;
__u8 tx_ident;
struct l2cap_chan_list chan_list;
};
#define L2CAP_INFO_CL_MTU_REQ_SENT 0x01
#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x02
/* ----- L2CAP channel and socket info ----- */
#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
struct l2cap_pinfo {
struct bt_sock bt;
__le16 psm;
__u16 dcid;
__u16 scid;
__u16 imtu;
__u16 omtu;
__u16 flush_to;
__u32 link_mode;
__u8 conf_req[64];
__u8 conf_len;
__u8 conf_state;
__u8 conf_retry;
__u8 ident;
__le16 sport;
struct l2cap_conn *conn;
struct sock *next_c;
struct sock *prev_c;
};
#define L2CAP_CONF_REQ_SENT 0x01
#define L2CAP_CONF_INPUT_DONE 0x02
#define L2CAP_CONF_OUTPUT_DONE 0x04
#define L2CAP_CONF_MAX_RETRIES 2
void l2cap_load(void);
#endif //NOT_DOLPHIN
#endif /* __L2CAP_H */

View File

@ -1335,13 +1335,13 @@ void CFrame::UpdateGUI()
if (Initialized && SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) if (Initialized && SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
{ {
GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE1)->Check(GetUsbPointer()-> GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE1)->Check(GetUsbPointer()->
AccessWiiMote(0x0100)->IsConnected() == 3); AccessWiiMote(0x0100)->IsConnected());
GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE2)->Check(GetUsbPointer()-> GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE2)->Check(GetUsbPointer()->
AccessWiiMote(0x0101)->IsConnected() == 3); AccessWiiMote(0x0101)->IsConnected());
GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE3)->Check(GetUsbPointer()-> GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE3)->Check(GetUsbPointer()->
AccessWiiMote(0x0102)->IsConnected() == 3); AccessWiiMote(0x0102)->IsConnected());
GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE4)->Check(GetUsbPointer()-> GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE4)->Check(GetUsbPointer()->
AccessWiiMote(0x0103)->IsConnected() == 3); AccessWiiMote(0x0103)->IsConnected());
} }
if (Running) if (Running)

View File

@ -117,8 +117,6 @@ void SendReportCore(u16 _channelID)
DEBUG_LOG(WIIMOTE, " Size: %08x", Offset); DEBUG_LOG(WIIMOTE, " Size: %08x", Offset);
g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, DataFrame, Offset); g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, DataFrame, Offset);
// Debugging
//ReadDebugging(true, DataFrame, Offset);
} }
@ -142,9 +140,6 @@ void SendReportCoreAccel(u16 _channelID)
DEBUG_LOG(WIIMOTE, " Size: %08x", Offset); DEBUG_LOG(WIIMOTE, " Size: %08x", Offset);
g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, DataFrame, Offset); g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, DataFrame, Offset);
// Debugging
//ReadDebugging(true, DataFrame, Offset);
} }
@ -171,9 +166,6 @@ void SendReportCoreAccelIr12(u16 _channelID) {
DEBUG_LOG(WIIMOTE, " Size: %08x", Offset); DEBUG_LOG(WIIMOTE, " Size: %08x", Offset);
g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, DataFrame, Offset); g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, DataFrame, Offset);
// Debugging
//ReadDebugging(true, DataFrame, Offset);
} }
@ -216,9 +208,6 @@ void SendReportCoreAccelExt16(u16 _channelID)
DEBUG_LOG(WIIMOTE, " Size: %08x", Offset); DEBUG_LOG(WIIMOTE, " Size: %08x", Offset);
g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, DataFrame, Offset); g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, DataFrame, Offset);
// Debugging
//ReadDebugging(true, DataFrame, Offset);
} }
@ -291,9 +280,6 @@ void SendReportCoreAccelIr10Ext(u16 _channelID)
DEBUG_LOG(WIIMOTE, " Size: %08x", Offset); DEBUG_LOG(WIIMOTE, " Size: %08x", Offset);
g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, DataFrame, Offset); g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, DataFrame, Offset);
// Debugging
//ReadDebugging(true, DataFrame, Offset);
} }

View File

@ -605,11 +605,6 @@ void DoState(PointerWrap &p)
response to Output from the Wii. */ response to Output from the Wii. */
void InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size) void InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
{ {
/* Debugging. We have not yet decided how much of 'data' we will use, it's
not determined by sizeof(data). We have to determine it by looking at
the data cases. */
//InterruptDebugging(true, (const void*)_pData);
g_ID = _number; g_ID = _number;
hid_packet* hidp = (hid_packet*)_pData; hid_packet* hidp = (hid_packet*)_pData;
@ -673,13 +668,11 @@ void ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
else else
{ {
// AyuanX: My experiment shows Control Channel is never used // AyuanX: My experiment shows Control Channel is never used
// shuffle2: but homebrew uses this, so we'll do what we must :) // shuffle2: but lwbt uses this, so we'll do what we must :)
HidOutputReport(_channelID, (wm_report*)hidp->data); HidOutputReport(_channelID, (wm_report*)hidp->data);
u8 handshake = HID_HANDSHAKE_SUCCESS; u8 handshake = HID_HANDSHAKE_SUCCESS;
g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, &handshake, 1); g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, &handshake, 1);
PanicAlert("HID_TYPE_DATA - OUTPUT: Ambiguous Control Channel Report!");
} }
break; break;

View File

@ -179,9 +179,6 @@ void WmSendAck(u16 _channelID, u8 _reportID)
DEBUG_LOG(WIIMOTE, " Report ID: %02x", _reportID); DEBUG_LOG(WIIMOTE, " Report ID: %02x", _reportID);
g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, DataFrame, Offset); g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, DataFrame, Offset);
// Debugging
//ReadDebugging(true, DataFrame, Offset);
} }
@ -367,9 +364,6 @@ void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _AddressHI,
// Update the size that is left // Update the size that is left
_Size -= copySize; _Size -= copySize;
// Debugging
//ReadDebugging(true, DataFrame, Offset);
} }
} }
@ -542,9 +536,6 @@ void WmRequestStatus(u16 _channelID, wm_request_status* rs, int Extension)
g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, DataFrame, Offset); g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, DataFrame, Offset);
// Debugging
//ReadDebugging(true, DataFrame, Offset);
} }
//http://snzgoo.blogspot.com for more details on what this is doing //http://snzgoo.blogspot.com for more details on what this is doing

View File

@ -18,7 +18,7 @@
#ifndef MAIN_H #ifndef MAIN_H
#define MAIN_H #define MAIN_H
#include <iostream> // System #include <iostream>
#include <vector> #include <vector>
#include "CommonTypes.h" #include "CommonTypes.h"
@ -30,10 +30,8 @@
#include <X11/XKBlib.h> #include <X11/XKBlib.h>
extern Display* WMdisplay; extern Display* WMdisplay;
#endif #endif
// Definitions and declarations
bool IsFocus(); bool IsFocus();
//void InterruptDebugging(bool Emu, const void* _pData);
//void ReadDebugging(bool Emu, const void* _pData, int Size);
// Movement recording // Movement recording
#define RECORDING_ROWS 15 #define RECORDING_ROWS 15

View File

@ -127,10 +127,6 @@ void SendData(u16 _channelID, const u8* _pData, u32 _Size)
memcpy(WriteEvent.m_PayLoad, _pData, _Size); memcpy(WriteEvent.m_PayLoad, _pData, _Size);
WriteEvent._Size = _Size; WriteEvent._Size = _Size;
m_EventWriteQueue.push(WriteEvent); m_EventWriteQueue.push(WriteEvent);
// Debugging
//std::string Temp = ArrayToString(WriteEvent.m_PayLoad, 28, 0, 30);
//DEBUG_LOG(WIIMOTE, "Wiimote Write:\n%s", Temp.c_str());
} }
m_pCriticalSection->Leave(); m_pCriticalSection->Leave();
} }
@ -147,9 +143,10 @@ void ReadData()
// Send data to the Wiimote // Send data to the Wiimote
if (!m_EventWriteQueue.empty()) if (!m_EventWriteQueue.empty())
{ {
//DEBUG_LOG(WIIMOTE, "Writing data to the Wiimote"); const SEvent& rEvent = m_EventWriteQueue.front();
SEvent& rEvent = m_EventWriteQueue.front();
wiiuse_io_write(m_pWiiMote, (byte*)rEvent.m_PayLoad, rEvent._Size); wiiuse_io_write(m_pWiiMote, (byte*)rEvent.m_PayLoad, rEvent._Size);
//std::string Temp = ArrayToString(rEvent.m_PayLoad, rEvent._Size);
//DEBUG_LOG(WIIMOTE, "Wiimote Write:\n%s:%d", Temp.c_str(), ret);
#ifdef _WIN32 #ifdef _WIN32
if (m_pWiiMote->event == WIIUSE_UNEXPECTED_DISCONNECT) if (m_pWiiMote->event == WIIUSE_UNEXPECTED_DISCONNECT)
{ {
@ -157,8 +154,6 @@ void ReadData()
} }
#endif #endif
m_EventWriteQueue.pop(); m_EventWriteQueue.pop();
// InterruptDebugging(false, rEvent.m_PayLoad);
} }
m_pCriticalSection->Leave(); m_pCriticalSection->Leave();
@ -168,6 +163,8 @@ void ReadData()
if (wiiuse_io_read(m_pWiiMote)) if (wiiuse_io_read(m_pWiiMote))
{ {
const byte* pBuffer = m_pWiiMote->event_buf; const byte* pBuffer = m_pWiiMote->event_buf;
//std::string Temp = ArrayToString(pBuffer, 20);
//DEBUG_LOG(WIIMOTE, "Wiimote Read:\n%s", Temp.c_str());
// Check if we have a channel (connection) if so save the data... // Check if we have a channel (connection) if so save the data...
if (m_channelID > 0) if (m_channelID > 0)
{ {
@ -191,6 +188,8 @@ void ReadData()
} }
m_pCriticalSection->Leave(); m_pCriticalSection->Leave();
} }
memset((void*)&m_pWiiMote->event_buf,0,sizeof(m_pWiiMote->event_buf));
} }
#ifdef _WIN32 #ifdef _WIN32
else if (m_pWiiMote->event == WIIUSE_UNEXPECTED_DISCONNECT) else if (m_pWiiMote->event == WIIUSE_UNEXPECTED_DISCONNECT)
@ -277,9 +276,6 @@ void SendEvent(SEvent& _rEvent)
// Send it // Send it
g_WiimoteInitialize.pWiimoteInterruptChannel(m_WiimoteNumber, m_channelID, Buffer, Offset); g_WiimoteInitialize.pWiimoteInterruptChannel(m_WiimoteNumber, m_channelID, Buffer, Offset);
// Debugging
// ReadDebugging(false, Buffer, Offset);
} }
}; };
@ -541,8 +537,14 @@ void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u3
void ControlChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size) void ControlChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size)
{ {
//DEBUG_LOG(WIIMOTE, "Real ControlChannel on WiiMote #%i", _WiimoteNumber);
g_WiiMotes[_WiimoteNumber]->SendData(_channelID, (const u8*)_pData, _Size); g_WiiMotes[_WiimoteNumber]->SendData(_channelID, (const u8*)_pData, _Size);
const hid_packet* const hidp = (hid_packet*)_pData;
if (hidp->type == HID_TYPE_SET_REPORT)
{
u8 handshake_ok = HID_HANDSHAKE_SUCCESS;
g_WiimoteInitialize.pWiimoteInterruptChannel(_WiimoteNumber, _channelID, &handshake_ok, sizeof(handshake_ok));
}
} }

View File

@ -68,9 +68,6 @@ void Wiimote::ReportMode(const wm_report_mode* const dr)
// reset IR camera // reset IR camera
//memset(m_reg_ir, 0, sizeof(*m_reg_ir)); //ugly hack //memset(m_reg_ir, 0, sizeof(*m_reg_ir)); //ugly hack
if (false == m_reporting_auto)
PanicAlert("Wiimote: Reporting is set to OFF! Everything should be fine, but games never do this.");
if (dr->mode > 0x37) if (dr->mode > 0x37)
PanicAlert("Wiimote: Unsupported Reporting mode."); PanicAlert("Wiimote: Unsupported Reporting mode.");
else if (dr->mode < WM_REPORT_CORE) else if (dr->mode < WM_REPORT_CORE)

View File

@ -763,7 +763,7 @@ void Wiimote::ControlChannel(const u16 _channelID, const void* _pData, u32 _Size
INFO_LOG(WIIMOTE, "Emu ControlChannel (page: %i, type: 0x%02x, param: 0x%02x)", m_index, hidp->type, hidp->param); INFO_LOG(WIIMOTE, "Emu ControlChannel (page: %i, type: 0x%02x, param: 0x%02x)", m_index, hidp->type, hidp->param);
switch(hidp->type) switch (hidp->type)
{ {
case HID_TYPE_HANDSHAKE : case HID_TYPE_HANDSHAKE :
PanicAlert("HID_TYPE_HANDSHAKE - %s", (hidp->param == HID_PARAM_INPUT) ? "INPUT" : "OUPUT"); PanicAlert("HID_TYPE_HANDSHAKE - %s", (hidp->param == HID_PARAM_INPUT) ? "INPUT" : "OUPUT");
@ -777,13 +777,11 @@ void Wiimote::ControlChannel(const u16 _channelID, const void* _pData, u32 _Size
else else
{ {
// AyuanX: My experiment shows Control Channel is never used // AyuanX: My experiment shows Control Channel is never used
// shuffle2: but homebrew uses this, so we'll do what we must :) // shuffle2: but lwbt uses this, so we'll do what we must :)
HidOutputReport((wm_report*)hidp->data); HidOutputReport((wm_report*)hidp->data);
u8 handshake = HID_HANDSHAKE_SUCCESS; u8 handshake = HID_HANDSHAKE_SUCCESS;
g_WiimoteInitialize.pWiimoteInterruptChannel(m_index, _channelID, &handshake, 1); g_WiimoteInitialize.pWiimoteInterruptChannel(m_index, _channelID, &handshake, 1);
PanicAlert("HID_TYPE_DATA - OUTPUT: Ambiguous Control Channel Report!");
} }
break; break;

View File

@ -118,7 +118,15 @@ void Wiimote::ControlChannel(const u16 channel, const void* const data, const u3
if (99 == channel) if (99 == channel)
Disconnect(); Disconnect();
else else
{
InterruptChannel(channel, data, size); InterruptChannel(channel, data, size);
const hid_packet* const hidp = (hid_packet*)data;
if (hidp->type == HID_TYPE_SET_REPORT)
{
u8 handshake_ok = HID_HANDSHAKE_SUCCESS;
g_WiimoteInitialize.pWiimoteInterruptChannel(index, channel, &handshake_ok, sizeof(handshake_ok));
}
}
} }
void Wiimote::InterruptChannel(const u16 channel, const void* const data, const u32 size) void Wiimote::InterruptChannel(const u16 channel, const void* const data, const u32 size)