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:
parent
197202798d
commit
92eedc9cd3
|
@ -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
|
@ -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
|
||||
|
||||
public:
|
||||
|
||||
// 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,28 +79,22 @@ 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
|
||||
struct SHCICommandMessage
|
||||
{
|
||||
u8 bRequestType;
|
||||
u8 bRequest;
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct CtrlBuffer
|
||||
// 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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue