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
Name="IPC HLE"
>
<File
RelativePath=".\Src\IPC_HLE\hci.h"
>
</File>
<File
RelativePath=".\Src\IPC_HLE\l2cap.h"
>
</File>
<File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE.cpp"
>
@ -1226,22 +1218,10 @@
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device.h"
>
</File>
<File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_Error.h"
>
</File>
<File
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_Device_stm.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>
<Filter
Name="Keyboard"
>
@ -1255,8 +1235,24 @@
</File>
</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
RelativePath=".\Src\IPC_HLE\WII_IPC_HLE_WiiMote.cpp"
>
@ -1298,18 +1294,6 @@
>
</File>
</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
Name="DI -DVD Interface"
>
@ -1337,6 +1321,14 @@
<Filter
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
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
// http://code.google.com/p/dolphin-emu/
#ifndef _WII_IPC_HLE_DEVICE_USB_H_
#define _WII_IPC_HLE_DEVICE_USB_H_
#pragma once
#include "hci.h"
#include <vector>
@ -25,21 +24,6 @@
#include "WII_IPC_HLE_Device.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
{
u8 m_buffer[1024];
@ -55,6 +39,7 @@ struct SQueuedEvent
// i know this code sux...
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
{
public:
CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _DeviceID, const std::string& _rDeviceName);
virtual ~CWII_IPC_HLE_Device_usb_oh1_57e_305();
@ -79,16 +63,13 @@ public:
virtual u32 Update();
// Send ACL data back to bt stack
void SendACLPacket(u16 _ConnectionHandle, u8* _pData, u32 _Size);
void PurgeACLPool();
void PurgeHCIPool();
bool RemoteDisconnect(u16 _connectionHandle);
//hack for wiimote plugin
// hack for wiimote plugin
public:
std::vector<CWII_IPC_HLE_WiiMote> m_WiiMotes;
CWII_IPC_HLE_WiiMote* AccessWiiMote(const bdaddr_t& _rAddr);
CWII_IPC_HLE_WiiMote* AccessWiiMote(u16 _ConnectionHandle);
@ -98,27 +79,21 @@ public:
void NetPlay_WiimoteUpdate(int _number);
private:
enum
enum USBIOCtl
{
USB_IOCTL_HCI_COMMAND_MESSAGE = 0,
USB_IOCTL_BLKMSG = 1,
USB_IOCTL_INTRMSG = 2,
USB_IOCTL_SUSPENDDEV = 5,
USB_IOCTL_RESUMEDEV = 6,
USB_IOCTL_GETDEVLIST = 12,
USB_IOCTL_DEVREMOVALHOOK = 26,
USB_IOCTL_DEVINSERTHOOK = 27,
USBV0_IOCTL_CTRLMSG = 0,
USBV0_IOCTL_BLKMSG = 1,
USBV0_IOCTL_INTRMSG = 2,
};
enum
enum USBEndpoint
{
HCI_EVENT_ENDPOINT = 0x81,
ACL_DATA_BLK_OUT = 0x02,
ACL_DATA_ENDPOINT = 0x82,
HCI_CTRL = 0x00,
HCI_EVENT = 0x81,
ACL_DATA_IN = 0x82,
ACL_DATA_OUT = 0x02
};
struct SHCICommandMessage
{
u8 bRequestType;
@ -132,75 +107,75 @@ private:
u32 m_Address;
};
struct ACLPool
{
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)
{
}
};
// This is a lightweight/specialized version of SIOCtlVBuffer
struct CtrlBuffer
{
u32 m_address;
u32 m_buffer;
CtrlBuffer(u32 _Address)
: m_address(_Address)
CtrlBuffer(u32 _Address) : m_address(_Address), m_buffer()
{
if(_Address == 0)
if (m_address)
{
m_buffer = 0;
}
else
{
u32 _BufferVector = Memory::Read_U32(_Address + 0x18);
u32 _InBufferNum = Memory::Read_U32(_Address + 0x10);
m_buffer = Memory::Read_U32(_BufferVector + _InBufferNum * 8);
u32 InBufferNum = Memory::Read_U32(m_address + 0x10);
u32 BufferVector = Memory::Read_U32(m_address + 0x18);
m_buffer = Memory::Read_U32(
BufferVector + InBufferNum * sizeof(SIOCtlVBuffer::SBuffer));
}
}
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;
u8 m_ClassOfDevice[HCI_CLASS_SIZE];
char m_LocalName[HCI_UNIT_NAME_SIZE];
u8 m_PINType;
// this is used to trigger connecting via ACL
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;
CtrlBuffer m_HCIEndpoint;
std::queue<SQueuedEvent> m_EventQueue;
u32 m_ACLSetup;
CtrlBuffer m_HCIBuffer;
HCIPool m_HCIPool;
CtrlBuffer m_ACLBuffer;
ACLPool m_ACLPool;
u32 m_LastCmd;
CtrlBuffer m_ACLEndpoint;
struct ACLQ
{
u8* m_buffer;
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_FreqDividerMote;
u32 m_FreqDividerSync;
u32 m_WiimoteUpdate_Freq;
u32 m_NumCompPackets_Freq;
// Send ACL data to a device (wiimote)
void SendToDevice(u16 _ConnectionHandle, u8* _pData, u32 _Size);
// Events
void AddEventToQueue(const SQueuedEvent& _event);
@ -216,12 +191,12 @@ private:
bool SendEventReadRemoteVerInfo(u16 _connectionHandle);
bool SendEventReadRemoteFeatures(u16 _connectionHandle);
bool SendEventRoleChange(bdaddr_t _bd, bool _master);
bool SendEventNumberOfCompletedPackets(u16 _connectionHandle, u16 _count);
bool SendEventNumberOfCompletedPackets();
bool SendEventAuthenticationCompleted(u16 _connectionHandle);
bool SendEventModeChange(u16 _connectionHandle, u8 _mode, u16 _value);
bool SendEventDisconnect(u16 _connectionHandle, u8 _Reason);
bool SendEventRequestLinkKey(const bdaddr_t& _bd);
bool SendEventLinkKeyNotification(const CWII_IPC_HLE_WiiMote& _rWiiMote);
bool SendEventLinkKeyNotification(const u8 num_to_send);
// Execute HCI Message
void ExecuteHCICommandMessage(const SHCICommandMessage& _rCtrlMessage);
@ -271,45 +246,6 @@ private:
void CommandVendorSpecific_FC4C(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);
};
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 "../Host.h"
#include "../Core.h"
#include "l2cap.h" // Local
#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)
{
INFO_LOG(WII_IPC_WIIMOTE, "Wiimote: #%i Constructed", _Number);
DEBUG_LOG(WII_IPC_WIIMOTE, "Wiimote: #%i Constructed", _Number);
s_Usb = _pHost;
m_Connected = (ready) ? 0 : -1;
m_ConnectionState = (ready) ? CONN_READY : CONN_INACTIVE;
m_ConnectionHandle = 0x100 + _Number;
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)
{
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()
{
if (m_Connected != 2)
if (m_ConnectionState != CONN_LINKING)
return false;
// try to connect HID_CONTROL_CHANNEL
// try to connect L2CAP_PSM_HID_CNTL
if (!m_HIDControlChannel_Connected)
{
if (m_HIDControlChannel_ConnectedWait)
return false;
m_HIDControlChannel_ConnectedWait = true;
SendConnectionRequest(0x0040, HID_CONTROL_CHANNEL);
SendConnectionRequest(0x0040, L2CAP_PSM_HID_CNTL);
return true;
}
// try to config HID_CONTROL_CHANNEL
// try to config L2CAP_PSM_HID_CNTL
if (!m_HIDControlChannel_Config)
{
if (m_HIDControlChannel_ConfigWait)
@ -123,18 +122,18 @@ bool CWII_IPC_HLE_WiiMote::LinkChannel()
return true;
}
// try to connect HID_INTERRUPT_CHANNEL
// try to connect L2CAP_PSM_HID_INTR
if (!m_HIDInterruptChannel_Connected)
{
if (m_HIDInterruptChannel_ConnectedWait)
return false;
m_HIDInterruptChannel_ConnectedWait = true;
SendConnectionRequest(0x0041, HID_INTERRUPT_CHANNEL);
SendConnectionRequest(0x0041, L2CAP_PSM_HID_INTR);
return true;
}
// try to config HID_INTERRUPT_CHANNEL
// try to config L2CAP_PSM_HID_INTR
if (!m_HIDInterruptChannel_Config)
{
if (m_HIDInterruptChannel_ConfigWait)
@ -145,7 +144,8 @@ bool CWII_IPC_HLE_WiiMote::LinkChannel()
return true;
}
m_Connected = 3;
DEBUG_LOG(WII_IPC_WIIMOTE, "ConnectionState CONN_LINKING -> CONN_COMPLETE");
m_ConnectionState = CONN_COMPLETE;
return false;
}
@ -162,9 +162,9 @@ bool CWII_IPC_HLE_WiiMote::LinkChannel()
//
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)
{
@ -175,7 +175,8 @@ void CWII_IPC_HLE_WiiMote::Activate(bool ready)
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()
@ -184,21 +185,17 @@ void CWII_IPC_HLE_WiiMote::EventDisconnect()
u8 Message = WIIMOTE_DISCONNECT;
CPluginManager::GetInstance().GetWiimote()->Wiimote_ControlChannel(m_ConnectionHandle & 0xFF, 99, &Message, 0);
m_Connected = -1;
m_ConnectionState = CONN_INACTIVE;
// Clear channel flags
ResetChannels();
}
bool CWII_IPC_HLE_WiiMote::EventPagingChanged(u8 _pageMode)
{
if (m_Connected != 0)
return false;
if ((m_ConnectionState == CONN_READY) && (_pageMode & HCI_PAGE_SCAN_ENABLE))
return true;
if ((_pageMode & 0x2) == 0)
return false;
m_Connected = 1;
return true;
return false;
}
void CWII_IPC_HLE_WiiMote::ResetChannels()
@ -227,75 +224,69 @@ void CWII_IPC_HLE_WiiMote::ResetChannels()
//
// ===================================================
// 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)
{
// Debugger::PrintDataBuffer(LogTypes::WIIMOTE, _pData, _Size, "SendACLPacket: ");
// parse the command
SL2CAP_Header* pHeader = (SL2CAP_Header*)_pData;
u8* pData = _pData + sizeof(SL2CAP_Header);
u32 DataSize = _Size - sizeof(SL2CAP_Header);
INFO_LOG(WII_IPC_WIIMOTE, " CID 0x%04x, Len 0x%x, DataSize 0x%x", pHeader->CID, pHeader->Length, DataSize);
l2cap_hdr_t* pHeader = (l2cap_hdr_t*)_pData;
u8* pData = _pData + sizeof(l2cap_hdr_t);
u32 DataSize = _Size - sizeof(l2cap_hdr_t);
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.");
return;
}
switch (pHeader->CID)
switch (pHeader->dcid)
{
case 0x0001:
case L2CAP_SIGNAL_CID:
SignalChannel(pData, DataSize);
break;
default:
{
_dbg_assert_msg_(WII_IPC_WIIMOTE, DoesChannelExist(pHeader->CID), "L2CAP: SendACLPacket to unknown channel %i", pHeader->CID);
CChannelMap::iterator itr= m_Channel.find(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->dcid);
#if defined(HAVE_WX) && HAVE_WX
#if defined(HAVE_WX) && HAVE_WX
const int number = NetPlay_GetWiimoteNum(m_ConnectionHandle & 0xFF);
#else
#else
const int number = 0;
#endif
#endif
Common::PluginWiimote* mote = CPluginManager::GetInstance().GetWiimote();
if (itr != m_Channel.end())
{
SChannel& rChannel = itr->second;
switch(rChannel.PSM)
switch (rChannel.PSM)
{
case SDP_CHANNEL:
HandleSDP(pHeader->CID, pData, DataSize);
case L2CAP_PSM_SDP:
HandleSDP(pHeader->dcid, pData, DataSize);
break;
case HID_CONTROL_CHANNEL:
case L2CAP_PSM_HID_CNTL:
if (number < 4)
mote->Wiimote_ControlChannel(number, pHeader->CID, pData, DataSize);
mote->Wiimote_ControlChannel(number, pHeader->dcid, pData, DataSize);
break;
case HID_INTERRUPT_CHANNEL:
case L2CAP_PSM_HID_INTR:
{
if (number < 4)
{
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);
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;
default:
ERROR_LOG(WII_IPC_WIIMOTE, "channel 0x04%x has unknown PSM %x", pHeader->CID, rChannel.PSM);
PanicAlert("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);
break;
}
}
@ -303,55 +294,48 @@ void CWII_IPC_HLE_WiiMote::ExecuteL2capCmd(u8* _pData, u32 _Size)
break;
}
}
// ================
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;
_pData += sizeof(SL2CAP_Command);
_Size = _Size - sizeof(SL2CAP_Command) - pCommand->len;
l2cap_cmd_hdr_t* cmd_hdr = (l2cap_cmd_hdr_t*)_pData;
_pData += sizeof(l2cap_cmd_hdr_t);
_Size = _Size - sizeof(l2cap_cmd_hdr_t) - cmd_hdr->length;
switch(pCommand->code)
switch (cmd_hdr->code)
{
case L2CAP_COMMAND_REJ:
ERROR_LOG(WII_IPC_WIIMOTE, "SignalChannel - L2CAP_COMMAND_REJ (something went wrong)."
"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);
"Try to replace your SYSCONF file with a new copy.");
break;
case L2CAP_CONN_REQ:
ReceiveConnectionReq(pCommand->ident, _pData, pCommand->len);
case L2CAP_CONNECT_REQ:
ReceiveConnectionReq(cmd_hdr->ident, _pData, cmd_hdr->length);
break;
case L2CAP_CONN_RSP:
ReceiveConnectionResponse(pCommand->ident, _pData, pCommand->len);
case L2CAP_CONNECT_RSP:
ReceiveConnectionResponse(cmd_hdr->ident, _pData, cmd_hdr->length);
break;
case L2CAP_CONF_REQ:
ReceiveConfigurationReq(pCommand->ident, _pData, pCommand->len);
case L2CAP_CONFIG_REQ:
ReceiveConfigurationReq(cmd_hdr->ident, _pData, cmd_hdr->length);
break;
case L2CAP_CONF_RSP:
ReceiveConfigurationResponse(pCommand->ident, _pData, pCommand->len);
case L2CAP_CONFIG_RSP:
ReceiveConfigurationResponse(cmd_hdr->ident, _pData, cmd_hdr->length);
break;
case L2CAP_DISCONN_REQ:
ReceiveDisconnectionReq(pCommand->ident, _pData, pCommand->len);
case L2CAP_DISCONNECT_REQ:
ReceiveDisconnectionReq(cmd_hdr->ident, _pData, cmd_hdr->length);
break;
default:
ERROR_LOG(WII_IPC_WIIMOTE, " Unknown Command-Code (0x%02x)", pCommand->code);
PanicAlert("SignalChannel %x",pCommand->code);
ERROR_LOG(WII_IPC_WIIMOTE, " Unknown Command-Code (0x%02x)", cmd_hdr->code);
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)
{
SL2CAP_CommandConnectionReq* pCommandConnectionReq = (SL2CAP_CommandConnectionReq*)_pData;
l2cap_con_req_cp* pCommandConnectionReq = (l2cap_con_req_cp*)_pData;
// create the channel
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);
// response
SL2CAP_ConnectionResponse Rsp;
l2cap_con_rsp_cp Rsp;
Rsp.scid = rChannel.SCID;
Rsp.dcid = rChannel.DCID;
Rsp.result = 0x00;
Rsp.status = 0x00;
Rsp.result = L2CAP_SUCCESS;
Rsp.status = L2CAP_NO_INFO;
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)
{
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");
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, " Status: 0x%04x", rsp->status);
_dbg_assert_(WII_IPC_WIIMOTE, rsp->result == 0);
_dbg_assert_(WII_IPC_WIIMOTE, rsp->status == 0);
_dbg_assert_(WII_IPC_WIIMOTE, rsp->result == L2CAP_SUCCESS);
_dbg_assert_(WII_IPC_WIIMOTE, rsp->status == L2CAP_NO_INFO);
_dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(rsp->scid));
SChannel& rChannel = m_Channel[rsp->scid];
rChannel.DCID = rsp->dcid;
//
// AyuanX: I'm commenting this out because CPU thinks he is faster than WiiMote
// 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)
// update state machine
if (rChannel.PSM == L2CAP_PSM_HID_CNTL)
m_HIDControlChannel_Connected = true;
if (rChannel.PSM == HID_INTERRUPT_CHANNEL)
else if (rChannel.PSM == L2CAP_PSM_HID_INTR)
m_HIDInterruptChannel_Connected = true;
*/
}
void CWII_IPC_HLE_WiiMote::ReceiveConfigurationReq(u8 _Ident, u8* _pData, u32 _Size)
{
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, 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, " Flags: 0x%04x", pCommandConfigReq->flags);
Offset += sizeof(SL2CAP_CommandConfigurationReq);
Offset += sizeof(l2cap_cfg_req_cp);
u8 TempBuffer[1024];
u32 RespLen = 0;
SL2CAP_CommandConfigurationResponse* Rsp = (SL2CAP_CommandConfigurationResponse*)TempBuffer;
l2cap_cfg_rsp_cp* Rsp = (l2cap_cfg_rsp_cp*)TempBuffer;
Rsp->scid = rChannel.DCID;
Rsp->flags = 0x00;
Rsp->result = 0x00;
Rsp->result = L2CAP_SUCCESS;
RespLen += sizeof(SL2CAP_CommandConfigurationResponse);
RespLen += sizeof(l2cap_cfg_rsp_cp);
// read configuration options
while (Offset < _Size)
{
SL2CAP_Options* pOptions = (SL2CAP_Options*)&_pData[Offset];
Offset += sizeof(SL2CAP_Options);
l2cap_cfg_opt_t* pOptions = (l2cap_cfg_opt_t*)&_pData[Offset];
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);
SL2CAP_OptionsMTU* pMTU = (SL2CAP_OptionsMTU*)&_pData[Offset];
rChannel.MTU = 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
_dbg_assert_(WII_IPC_WIIMOTE, pOptions->length == L2CAP_OPT_MTU_SIZE);
l2cap_cfg_opt_val_t* pMTU = (l2cap_cfg_opt_val_t*)&_pData[Offset];
rChannel.MTU = pMTU->mtu;
DEBUG_LOG(WII_IPC_WIIMOTE, " MTU: 0x%04x", pMTU->mtu);
}
break;
case 0x02:
case L2CAP_OPT_FLUSH_TIMO:
{
_dbg_assert_(WII_IPC_WIIMOTE, pOptions->length == 2);
SL2CAP_OptionsFlushTimeOut* pFlushTimeOut = (SL2CAP_OptionsFlushTimeOut*)&_pData[Offset];
rChannel.FlushTimeOut = pFlushTimeOut->TimeOut;
DEBUG_LOG(WII_IPC_WIIMOTE, " FlushTimeOut: 0x%04x", pFlushTimeOut->TimeOut);
_dbg_assert_(WII_IPC_WIIMOTE, pOptions->length == L2CAP_OPT_FLUSH_TIMO_SIZE);
l2cap_cfg_opt_val_t* pFlushTimeOut = (l2cap_cfg_opt_val_t*)&_pData[Offset];
rChannel.FlushTimeOut = pFlushTimeOut->flush_timo;
DEBUG_LOG(WII_IPC_WIIMOTE, " FlushTimeOut: 0x%04x", pFlushTimeOut->flush_timo);
}
break;
@ -491,51 +471,44 @@ void CWII_IPC_HLE_WiiMote::ReceiveConfigurationReq(u8 _Ident, u8* _pData, u32 _S
Offset += pOptions->length;
u32 OptionSize = sizeof(SL2CAP_Options) + pOptions->length;
u32 OptionSize = sizeof(l2cap_cfg_opt_t) + pOptions->length;
memcpy(&TempBuffer[RespLen], pOptions, OptionSize);
RespLen += OptionSize;
}
INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] SendConfigurationResponse");
SendCommandToACL(_Ident, L2CAP_CONF_RSP, RespLen, TempBuffer);
SendCommandToACL(_Ident, L2CAP_CONFIG_RSP, RespLen, TempBuffer);
// update state machine
if (rChannel.PSM == HID_CONTROL_CHANNEL)
if (rChannel.PSM == L2CAP_PSM_HID_CNTL)
m_HIDControlChannel_Connected = true;
else if (rChannel.PSM == HID_INTERRUPT_CHANNEL)
else if (rChannel.PSM == L2CAP_PSM_HID_INTR)
m_HIDInterruptChannel_Connected = true;
}
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");
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, " 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
SChannel& rChannel = m_Channel[rsp->scid];
if (rChannel.PSM == HID_CONTROL_CHANNEL)
{
if (rChannel.PSM == L2CAP_PSM_HID_CNTL)
m_HIDControlChannel_Config = true;
INFO_LOG(WII_IPC_WIIMOTE, "Building HID_CONTROL_CHANNEL -- OK");
}
else if (rChannel.PSM == HID_INTERRUPT_CHANNEL)
{
else if (rChannel.PSM == L2CAP_PSM_HID_INTR)
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)
{
SL2CAP_CommandDisconnectionReq* pCommandDisconnectionReq = (SL2CAP_CommandDisconnectionReq*)_pData;
l2cap_discon_req_cp* pCommandDisconnectionReq = (l2cap_discon_req_cp*)_pData;
INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] ReceiveDisconnectionReq");
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);
// response
SL2CAP_CommandDisconnectionResponse Rsp;
l2cap_discon_req_cp Rsp;
Rsp.dcid = pCommandDisconnectionReq->dcid;
Rsp.scid = pCommandDisconnectionReq->scid;
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.SCID = scid;
l2cap_conn_req cr;
l2cap_con_req_cp cr;
cr.psm = psm;
cr.scid = scid;
INFO_LOG(WII_IPC_WIIMOTE, "-----------------------------------------");
INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] SendConnectionRequest");
DEBUG_LOG(WII_IPC_WIIMOTE, " Psm: 0x%04x", cr.psm);
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)
{
// create the channel
SChannel& rChannel = m_Channel[scid];
l2cap_disconn_req cr;
l2cap_discon_req_cp cr;
cr.dcid = rChannel.DCID;
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, " 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)
@ -607,36 +579,43 @@ void CWII_IPC_HLE_WiiMote::SendConfigurationRequest(u16 scid, u16 MTU, u16 Flush
u8 Buffer[1024];
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->flags = 0;
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;
cr->flags = 0; Offset += sizeof(l2cap_cfg_req_cp);
INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] SendConfigurationRequest");
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, " 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);
int Offset = 0;
SL2CAP_Header* pHeader = (SL2CAP_Header*)&DataFrame[Offset]; Offset += sizeof(SL2CAP_Header);
pHeader->CID = cid;
l2cap_hdr_t* pHeader = (l2cap_hdr_t*)&DataFrame[Offset]; Offset += sizeof(l2cap_hdr_t);
pHeader->dcid = cid;
buffer.Write8 (Offset, 0x03); Offset++;
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;
pHeader->Length = (u16)(Offset - sizeof(SL2CAP_Header));
m_pHost->SendACLPacket(GetConnectionHandle(), DataFrame, pHeader->Length + sizeof(SL2CAP_Header));
pHeader->length = (u16)(Offset - sizeof(l2cap_hdr_t));
m_pHost->SendACLPacket(GetConnectionHandle(), DataFrame, pHeader->length + sizeof(l2cap_hdr_t));
}
u32 ParseCont(u8* pCont)
@ -766,18 +745,18 @@ void CWII_IPC_HLE_WiiMote::SDPSendServiceAttributeResponse(u16 cid, u16 Transact
CBigEndianBuffer buffer(DataFrame);
int Offset = 0;
SL2CAP_Header* pHeader = (SL2CAP_Header*)&DataFrame[Offset]; Offset += sizeof(SL2CAP_Header);
pHeader->CID = cid;
l2cap_hdr_t* pHeader = (l2cap_hdr_t*)&DataFrame[Offset]; Offset += sizeof(l2cap_hdr_t);
pHeader->dcid = cid;
buffer.Write8 (Offset, 0x05); Offset++;
buffer.Write16(Offset, TransactionID); Offset += 2; // transaction ID
memcpy(buffer.GetPointer(Offset), pPacket, packetSize); Offset += packetSize;
pHeader->Length = (u16)(Offset - sizeof(SL2CAP_Header));
m_pHost->SendACLPacket(GetConnectionHandle(), DataFrame, pHeader->Length + sizeof(SL2CAP_Header));
pHeader->length = (u16)(Offset - sizeof(l2cap_hdr_t));
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)
@ -850,14 +829,14 @@ void CWII_IPC_HLE_WiiMote::SendCommandToACL(u8 _Ident, u8 _Code, u8 _CommandLeng
u8 DataFrame[1024];
u32 Offset = 0;
SL2CAP_Header* pHeader = (SL2CAP_Header*)&DataFrame[Offset]; Offset += sizeof(SL2CAP_Header);
pHeader->Length = sizeof(SL2CAP_Command) + _CommandLength;
pHeader->CID = 0x0001;
l2cap_hdr_t* pHeader = (l2cap_hdr_t*)&DataFrame[Offset]; Offset += sizeof(l2cap_hdr_t);
pHeader->length = sizeof(l2cap_cmd_hdr_t) + _CommandLength;
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->ident = _Ident;
pCommand->len = _CommandLength;
pCommand->length = _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);
// 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)
{
#if defined(HAVE_WX) && HAVE_WX
#if defined(HAVE_WX) && HAVE_WX
if (NetPlay_WiimoteInput(m_ConnectionHandle & 0xFF, scid, _pData, _Size))
return;
#endif
#endif
// Allocate DataFrame
u8 DataFrame[1024];
u32 Offset = 0;
SL2CAP_Header* pHeader = (SL2CAP_Header*)DataFrame;
Offset += sizeof(SL2CAP_Header);
l2cap_hdr_t* pHeader = (l2cap_hdr_t*)DataFrame;
Offset += sizeof(l2cap_hdr_t);
// Check if we are already reporting on this channel
_dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(scid));
SChannel& rChannel = m_Channel[scid];
// Add an additonal 4 byte header to the Wiimote report
pHeader->CID = rChannel.DCID;
pHeader->Length = _Size;
// Add an additional 4 byte header to the Wiimote report
pHeader->dcid = rChannel.DCID;
pHeader->length = _Size;
// Copy the Wiimote report to DataFrame
memcpy(DataFrame + Offset, _pData, _Size);
@ -922,7 +896,7 @@ namespace Core
INFO_LOG(WIIMOTE, "====================");
INFO_LOG(WIIMOTE, "Callback_WiimoteInterruptChannel: (Wiimote: #%i)", _number);
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);
}

View file

@ -26,111 +26,6 @@ class CWII_IPC_HLE_Device_usb_oh1_57e_305;
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
{
public:
@ -163,7 +58,7 @@ public:
// ugly Host handling....
// we really have to clean all this code
int IsConnected() const { return m_Connected; }
bool IsConnected() const { return m_ConnectionState == CONN_COMPLETE; }
bool LinkChannel();
void ResetChannels();
void Activate(bool ready);
@ -188,8 +83,14 @@ public:
const u8* GetLinkKey() const { return m_LinkKey; }
private:
// -1: inactive, 0: ready, 1: connecting 2: linking 3: connected & linked
int m_Connected;
enum ConnectionState
{
CONN_INACTIVE = -1,
CONN_READY,
CONN_LINKING,
CONN_COMPLETE
};
ConnectionState m_ConnectionState;
bool m_HIDControlChannel_Connected;
bool m_HIDControlChannel_ConnectedWait;
@ -207,7 +108,7 @@ private:
u8 features[HCI_FEATURES_SIZE];
u8 lmp_version;
u16 lmp_subversion;
u8 m_LinkKey[16];
u8 m_LinkKey[HCI_KEY_SIZE];
std::string m_Name;
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 @@
/*
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2000-2001 Qualcomm Incorporated
/* $NetBSD: l2cap.h,v 1.9 2009/09/13 18:45:11 pooka Exp $ */
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation;
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
/*-
* Copyright (c) 2005 Iain Hibbert.
* Copyright (c) 2006 Itronix Inc.
* 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.
* 3. The name of Itronix Inc. may not be used to endorse
* or promote products derived from this software without specific
* prior written permission.
*
* 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
typedef unsigned short __le16;
typedef unsigned short __u16;
typedef unsigned char __u8;
typedef unsigned long __u32;
#pragma once
#pragma pack(push)
#pragma pack(1)
/**************************************************************************
**************************************************************************
** Common defines and types (L2CAP)
**************************************************************************
**************************************************************************/
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4200)
#endif
/*
* Channel IDs are assigned per machine. So the total number of channels that
* a machine can have open at the same time is 0xffff - 0x0040 = 0xffbf (65471).
* This number does not depend on number of HCI connections.
*/
/* L2CAP defaults */
#define L2CAP_DEFAULT_MTU 672
#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
#define L2CAP_NULL_CID 0x0000 /* DO NOT USE THIS CID */
#define L2CAP_SIGNAL_CID 0x0001 /* signaling channel ID */
#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 */
#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */
/* L2CAP MTU */
#define L2CAP_MTU_MINIMUM 48
#define L2CAP_MTU_DEFAULT 672
#define L2CAP_MTU_MAXIMUM 0xffff
/* L2CAP socket address */
#ifdef NOT_DOLPHIN
struct sockaddr_l2 {
sa_family_t l2_family;
__le16 l2_psm;
bdaddr_t l2_bdaddr;
};
#endif
/* L2CAP flush and link timeouts */
#define L2CAP_FLUSH_TIMO_DEFAULT 0xffff /* always retransmit */
#define L2CAP_LINK_TIMO_DEFAULT 0xffff
/* L2CAP socket options */
#define L2CAP_OPTIONS 0x01
struct l2cap_options {
__u16 omtu;
__u16 imtu;
__u16 flush_to;
__u8 mode;
};
/* L2CAP Command Reject reasons */
#define L2CAP_REJ_NOT_UNDERSTOOD 0x0000
#define L2CAP_REJ_MTU_EXCEEDED 0x0001
#define L2CAP_REJ_INVALID_CID 0x0002
/* 0x0003 - 0xffff - reserved for future use */
#define L2CAP_CONNINFO 0x02
struct l2cap_conninfo {
__u16 hci_handle;
__u8 dev_class[3];
};
/* Protocol/Service Multiplexor (PSM) values */
#define L2CAP_PSM_ANY 0x0000 /* Any/Invalid PSM */
#define L2CAP_PSM_SDP 0x0001 /* Service Discovery Protocol */
#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_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
#define L2CAP_PSM_INVALID(psm) (((psm) & 0x0101) != 0x0001)
/* L2CAP command codes */
#define L2CAP_COMMAND_REJ 0x01
#define L2CAP_CONN_REQ 0x02
#define L2CAP_CONN_RSP 0x03
#define L2CAP_CONF_REQ 0x04
#define L2CAP_CONF_RSP 0x05
#define L2CAP_DISCONN_REQ 0x06
#define L2CAP_DISCONN_RSP 0x07
#define L2CAP_ECHO_REQ 0x08
#define L2CAP_ECHO_RSP 0x09
#define L2CAP_INFO_REQ 0x0a
#define L2CAP_INFO_RSP 0x0b
/* L2CAP Connection response command result codes */
#define L2CAP_SUCCESS 0x0000
#define L2CAP_PENDING 0x0001
#define L2CAP_PSM_NOT_SUPPORTED 0x0002
#define L2CAP_SECURITY_BLOCK 0x0003
#define L2CAP_NO_RESOURCES 0x0004
#define L2CAP_TIMEOUT 0xeeee
#define L2CAP_UNKNOWN 0xffff
/* 0x0005 - 0xffff - reserved for future use */
/* L2CAP structures */
struct l2cap_hdr {
__le16 len;
__le16 cid;
};
#define L2CAP_HDR_SIZE 4
/* L2CAP Connection response status codes */
#define L2CAP_NO_INFO 0x0000
#define L2CAP_AUTH_PENDING 0x0001
#define L2CAP_AUTZ_PENDING 0x0002
/* 0x0003 - 0xffff - reserved for future use */
struct l2cap_cmd_hdr {
__u8 code;
__u8 ident;
__le16 len;
};
#define L2CAP_CMD_HDR_SIZE 4
/* L2CAP Configuration response result codes */
#define L2CAP_UNACCEPTABLE_PARAMS 0x0001
#define L2CAP_REJECT 0x0002
#define L2CAP_UNKNOWN_OPTION 0x0003
/* 0x0003 - 0xffff - reserved for future use */
struct l2cap_cmd_rej {
__le16 reason;
};
/* L2CAP Configuration options */
#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 {
__le16 psm;
__le16 scid;
};
/* L2CAP Information request type codes */
#define L2CAP_CONNLESS_MTU 0x0001
#define L2CAP_EXTENDED_FEATURES 0x0002
/* 0x0003 - 0xffff - reserved for future use */
struct l2cap_conn_rsp {
__le16 dcid;
__le16 scid;
__le16 result;
__le16 status;
};
/* L2CAP Information response codes */
#define L2CAP_NOT_SUPPORTED 0x0001
/* 0x0002 - 0xffff - reserved for future use */
/* connect result */
#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
#pragma pack(push, 1)
/* connect status */
#define L2CAP_CS_NO_INFO 0x0000
#define L2CAP_CS_AUTHEN_PEND 0x0001
#define L2CAP_CS_AUTHOR_PEND 0x0002
/* L2CAP Quality of Service option */
typedef struct {
uint8_t flags; /* reserved for future use */
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 {
__le16 dcid;
__le16 flags;
__u8 data[0];
};
/* L2CAP QoS type */
#define L2CAP_QOS_NO_TRAFFIC 0x00
#define L2CAP_QOS_BEST_EFFORT 0x01 /* (default) */
#define L2CAP_QOS_GUARANTEED 0x02
/* 0x03 - 0xff - reserved for future use */
struct l2cap_conf_rsp {
__le16 scid;
__le16 flags;
__le16 result;
__u8 data[0];
};
/* L2CAP Retransmission & Flow Control option */
typedef struct {
uint8_t mode; /* RFC mode */
uint8_t window_size; /* bytes */
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
#define L2CAP_CONF_UNACCEPT 0x0001
#define L2CAP_CONF_REJECT 0x0002
#define L2CAP_CONF_UNKNOWN 0x0003
/* L2CAP RFC mode */
#define L2CAP_RFC_BASIC 0x00 /* (default) */
#define L2CAP_RFC_RETRANSMIT 0x01
#define L2CAP_RFC_FLOW 0x02
/* 0x03 - 0xff - reserved for future use */
struct l2cap_conf_opt {
__u8 type;
__u8 len;
__u8 val[0];
};
#define L2CAP_CONF_OPT_SIZE 2
/**************************************************************************
**************************************************************************
** Link level defines, headers and types
**************************************************************************
**************************************************************************/
#define L2CAP_CONF_MTU 0x01
#define L2CAP_CONF_FLUSH_TO 0x02
#define L2CAP_CONF_QOS 0x03
#define L2CAP_CONF_RFC 0x04
/* L2CAP header */
typedef struct {
uint16_t length; /* payload size */
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 {
__u8 mode;
__u8 txwin_size;
__u8 max_transmit;
__le16 retrans_timeout;
__le16 monitor_timeout;
__le16 max_pdu_size;
};
#define L2CAP_CLT_MTU_MAXIMUM \
(L2CAP_MTU_MAXIMUM - sizeof(l2cap_clt_hdr_t))
#define L2CAP_MODE_BASIC 0x00
#define L2CAP_MODE_RETRANS 0x01
#define L2CAP_MODE_FLOWCTL 0x02
/* L2CAP Command header (dcid == L2CAP_SIGNAL_CID) */
typedef struct {
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 {
__le16 dcid;
__le16 scid;
};
/* L2CAP Command Reject */
#define L2CAP_COMMAND_REJ 0x01
typedef struct {
uint16_t reason; /* reason to reject command */
uint16_t data[2];/* optional data */
} l2cap_cmd_rej_cp;
struct l2cap_disconn_rsp {
__le16 dcid;
__le16 scid;
};
/* L2CAP Connection Request */
#define L2CAP_CONNECT_REQ 0x02
typedef struct {
uint16_t psm; /* Protocol/Service Multiplexor (PSM) */
uint16_t scid; /* source channel ID */
} l2cap_con_req_cp;
struct l2cap_info_req {
__le16 type;
};
/* L2CAP Connection Response */
#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 {
__le16 type;
__le16 result;
__u8 data[0];
};
/* L2CAP Configuration Request */
#define L2CAP_CONFIG_REQ 0x04
typedef struct {
uint16_t dcid; /* destination channel ID */
uint16_t flags; /* flags */
/* uint8_t options[] -- options */
} l2cap_cfg_req_cp;
/* info type */
#define L2CAP_IT_CL_MTU 0x0001
#define L2CAP_IT_FEAT_MASK 0x0002
/* L2CAP Configuration Response */
#define L2CAP_CONFIG_RSP 0x05
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 */
#define L2CAP_IR_SUCCESS 0x0000
#define L2CAP_IR_NOTSUPP 0x0001
/* L2CAP configuration option */
typedef struct {
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)
struct value_string
{
u32 value;
char* string;
};
/**************************************************************************
**************************************************************************
** L2CAP Socket Definitions
**************************************************************************
**************************************************************************/
static const value_string command_code_vals[] = {
{ 0x01, (char *)"Command Reject" },
{ 0x02, (char *)"Connection Request" },
{ 0x03, (char *)"Connection Response" },
{ 0x04, (char *)"Configure Request" },
{ 0x05, (char *)"Configure Response" },
{ 0x06, (char *)"Disconnect Request" },
{ 0x07, (char *)"Disconnect Response" },
{ 0x08, (char *)"Echo Request" },
{ 0x09, (char *)"Echo Response" },
{ 0x0A, (char *)"Information Request" },
{ 0x0B, (char *)"Information Response" },
{ 0, NULL }
};
/* Socket options */
#define SO_L2CAP_IMTU 1 /* incoming MTU */
#define SO_L2CAP_OMTU 2 /* outgoing MTU */
#define SO_L2CAP_IQOS 3 /* incoming QoS */
#define SO_L2CAP_OQOS 4 /* outgoing QoS */
#define SO_L2CAP_FLUSH 5 /* flush timeout */
#define SO_L2CAP_LM 6 /* link mode */
static const value_string psm_vals[] = {
{ 0x0001, (char *)"SDP" },
{ 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 */
/* L2CAP link mode flags */
#define L2CAP_LM_AUTH (1<<0) /* want authentication */
#define L2CAP_LM_ENCRYPT (1<<1) /* want encryption */
#define L2CAP_LM_SECURE (1<<2) /* want secured link */

View file

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

View file

@ -117,8 +117,6 @@ void SendReportCore(u16 _channelID)
DEBUG_LOG(WIIMOTE, " Size: %08x", 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);
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);
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);
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);
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. */
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;
hid_packet* hidp = (hid_packet*)_pData;
@ -673,13 +668,11 @@ void ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
else
{
// 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);
u8 handshake = HID_HANDSHAKE_SUCCESS;
g_WiimoteInitialize.pWiimoteInterruptChannel(g_ID, _channelID, &handshake, 1);
PanicAlert("HID_TYPE_DATA - OUTPUT: Ambiguous Control Channel Report!");
}
break;

View file

@ -179,9 +179,6 @@ void WmSendAck(u16 _channelID, u8 _reportID)
DEBUG_LOG(WIIMOTE, " Report ID: %02x", _reportID);
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
_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);
// Debugging
//ReadDebugging(true, DataFrame, Offset);
}
//http://snzgoo.blogspot.com for more details on what this is doing

View file

@ -18,7 +18,7 @@
#ifndef MAIN_H
#define MAIN_H
#include <iostream> // System
#include <iostream>
#include <vector>
#include "CommonTypes.h"
@ -30,10 +30,8 @@
#include <X11/XKBlib.h>
extern Display* WMdisplay;
#endif
// Definitions and declarations
bool IsFocus();
//void InterruptDebugging(bool Emu, const void* _pData);
//void ReadDebugging(bool Emu, const void* _pData, int Size);
// Movement recording
#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);
WriteEvent._Size = _Size;
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();
}
@ -147,9 +143,10 @@ void ReadData()
// Send data to the Wiimote
if (!m_EventWriteQueue.empty())
{
//DEBUG_LOG(WIIMOTE, "Writing data to the Wiimote");
SEvent& rEvent = m_EventWriteQueue.front();
const SEvent& rEvent = m_EventWriteQueue.front();
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
if (m_pWiiMote->event == WIIUSE_UNEXPECTED_DISCONNECT)
{
@ -157,8 +154,6 @@ void ReadData()
}
#endif
m_EventWriteQueue.pop();
// InterruptDebugging(false, rEvent.m_PayLoad);
}
m_pCriticalSection->Leave();
@ -168,6 +163,8 @@ void ReadData()
if (wiiuse_io_read(m_pWiiMote))
{
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...
if (m_channelID > 0)
{
@ -191,6 +188,8 @@ void ReadData()
}
m_pCriticalSection->Leave();
}
memset((void*)&m_pWiiMote->event_buf,0,sizeof(m_pWiiMote->event_buf));
}
#ifdef _WIN32
else if (m_pWiiMote->event == WIIUSE_UNEXPECTED_DISCONNECT)
@ -277,9 +276,6 @@ void SendEvent(SEvent& _rEvent)
// Send it
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)
{
//DEBUG_LOG(WIIMOTE, "Real ControlChannel on WiiMote #%i", _WiimoteNumber);
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
//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)
PanicAlert("Wiimote: Unsupported Reporting mode.");
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);
switch(hidp->type)
switch (hidp->type)
{
case HID_TYPE_HANDSHAKE :
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
{
// 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);
u8 handshake = HID_HANDSHAKE_SUCCESS;
g_WiimoteInitialize.pWiimoteInterruptChannel(m_index, _channelID, &handshake, 1);
PanicAlert("HID_TYPE_DATA - OUTPUT: Ambiguous Control Channel Report!");
}
break;

View file

@ -118,7 +118,15 @@ void Wiimote::ControlChannel(const u16 channel, const void* const data, const u3
if (99 == channel)
Disconnect();
else
{
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)