Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'comex-wiimote-fixes'
Should fix issue 6574.
  • Loading branch information
comex committed Sep 5, 2013
2 parents 0df5975 + 8992f58 commit 2fb0147
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 127 deletions.
7 changes: 5 additions & 2 deletions Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp
Expand Up @@ -43,12 +43,12 @@ bool WiimoteScanner::IsReady() const
return false;
}

bool Wiimote::Connect()
bool Wiimote::ConnectInternal()
{
return 0;
}

void Wiimote::Disconnect()
void Wiimote::DisconnectInternal()
{
return;
}
Expand All @@ -58,6 +58,9 @@ bool Wiimote::IsConnected() const
return false;
}

void Wiimote::IOWakeup()
{}

int Wiimote::IORead(u8* buf)
{
return 0;
Expand Down
32 changes: 24 additions & 8 deletions Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp
Expand Up @@ -27,8 +27,7 @@ namespace WiimoteReal
{

WiimoteScanner::WiimoteScanner()
: m_run_thread()
, m_want_wiimotes()
: m_want_wiimotes()
, device_id(-1)
, device_sock(-1)
{
Expand Down Expand Up @@ -135,7 +134,7 @@ void WiimoteScanner::FindWiimotes(std::vector<Wiimote*> & found_wiimotes, Wiimot
}

// Connect to a wiimote with a known address.
bool Wiimote::Connect()
bool Wiimote::ConnectInternal()
{
sockaddr_l2 addr;
addr.l2_family = AF_BLUETOOTH;
Expand Down Expand Up @@ -168,7 +167,7 @@ bool Wiimote::Connect()
return true;
}

void Wiimote::Disconnect()
void Wiimote::DisconnectInternal()
{
close(cmd_sock);
close(int_sock);
Expand All @@ -182,26 +181,43 @@ bool Wiimote::IsConnected() const
return cmd_sock != -1;// && int_sock != -1;
}

void Wiimote::IOWakeup()
{
char c = 0;
if (write(wakeup_pipe_w, &c, 1) != 1)
{
ERROR_LOG(WIIMOTE, "Unable to write to wakeup pipe.");
}
}

// positive = read packet
// negative = didn't read packet
// zero = error
int Wiimote::IORead(u8* buf)
{
// Block select for 1/2000th of a second
timeval tv;
tv.tv_sec = 0;
tv.tv_usec = WIIMOTE_DEFAULT_TIMEOUT * 1000;

fd_set fds;
FD_ZERO(&fds);
FD_SET(int_sock, &fds);
FD_SET(wakeup_pipe_r, &fds);

if (select(int_sock + 1, &fds, NULL, NULL, &tv) == -1)
if (select(int_sock + 1, &fds, NULL, NULL, NULL) == -1)
{
ERROR_LOG(WIIMOTE, "Unable to select wiimote %i input socket.", index + 1);
return -1;
}

if (FD_ISSET(wakeup_pipe_r, &fds))
{
char c;
if (read(wakeup_pipe_r, &c, 1) != 1)
{
ERROR_LOG(WIIMOTE, "Unable to read from wakeup pipe.");
}
return -1;
}

if (!FD_ISSET(int_sock, &fds))
return -1;

Expand Down
24 changes: 18 additions & 6 deletions Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp
Expand Up @@ -142,6 +142,7 @@ namespace WiimoteReal

int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, int len);
int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index);
void _IOWakeup(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read);

template <typename T>
void ProcessWiimotes(bool new_scan, T& callback);
Expand Down Expand Up @@ -459,7 +460,7 @@ bool WiimoteScanner::IsReady() const
}

// Connect to a wiimote with a known device path.
bool Wiimote::Connect()
bool Wiimote::ConnectInternal()
{
if (IsConnected())
return false;
Expand Down Expand Up @@ -535,7 +536,7 @@ bool Wiimote::Connect()
return true;
}

void Wiimote::Disconnect()
void Wiimote::DisconnectInternal()
{
if (!IsConnected())
return;
Expand All @@ -557,6 +558,11 @@ bool Wiimote::IsConnected() const
return dev_handle != 0;
}

void _IOWakeup(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read)
{
CancelIoEx(dev_handle, &hid_overlap_read);
}

// positive = read packet
// negative = didn't read packet
// zero = error
Expand All @@ -575,7 +581,7 @@ int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index

if (ERROR_IO_PENDING == read_err)
{
auto const wait_result = WaitForSingleObject(hid_overlap_read.hEvent, WIIMOTE_DEFAULT_TIMEOUT);
auto const wait_result = WaitForSingleObject(hid_overlap_read.hEvent, INFINITE);
if (WAIT_TIMEOUT == wait_result)
{
CancelIo(dev_handle);
Expand All @@ -592,10 +598,10 @@ int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index

if (ERROR_OPERATION_ABORTED == overlapped_err)
{
/*
if (buf[1] != 0)
WARN_LOG(WIIMOTE, "Packet ignored. This may indicate a problem (timeout is %i ms).",
WIIMOTE_DEFAULT_TIMEOUT);

WARN_LOG(WIIMOTE, "Packet ignored. This may indicate a problem.");
*/
return -1;
}

Expand All @@ -615,6 +621,12 @@ int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index
return bytes + 1;
}

void Wiimote::IOWakeup()
{
_IOWakeup(dev_handle, hid_overlap_read);
}


// positive = read packet
// negative = didn't read packet
// zero = error
Expand Down
84 changes: 47 additions & 37 deletions Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm
Expand Up @@ -7,6 +7,7 @@
@interface SearchBT: NSObject {
@public
unsigned int maxDevices;
bool done;
}
@end

Expand All @@ -15,6 +16,7 @@ - (void) deviceInquiryComplete: (IOBluetoothDeviceInquiry *) sender
error: (IOReturn) error
aborted: (BOOL) aborted
{
done = true;
CFRunLoopStop(CFRunLoopGetCurrent());
}

Expand Down Expand Up @@ -62,7 +64,7 @@ - (void) l2capChannelData: (IOBluetoothL2CAPChannel *) l2capChannel
return;
}

if (wm->inputlen != 0) {
if (wm->inputlen != -1) {
WARN_LOG(WIIMOTE, "Dropping packet for wiimote %i, queue full",
wm->index + 1);
return;
Expand All @@ -71,9 +73,8 @@ - (void) l2capChannelData: (IOBluetoothL2CAPChannel *) l2capChannel
memcpy(wm->input, data, length);
wm->inputlen = length;

(void)wm->Read();

(void)UpdateSystemActivity(UsrActivity);
CFRunLoopStop(CFRunLoopGetCurrent());
}

- (void) l2capChannelClosed: (IOBluetoothL2CAPChannel *) l2capChannel
Expand All @@ -98,7 +99,7 @@ - (void) l2capChannelClosed: (IOBluetoothL2CAPChannel *) l2capChannel

WARN_LOG(WIIMOTE, "Lost channel to wiimote %i", wm->index + 1);

wm->Disconnect();
wm->DisconnectInternal();
}
@end

Expand Down Expand Up @@ -139,14 +140,18 @@ - (void) l2capChannelClosed: (IOBluetoothL2CAPChannel *) l2capChannel
[bti setDelegate: sbt];
[bti setInquiryLength: 2];

if ([bti start] == kIOReturnSuccess)
[bti retain];
else
if ([bti start] != kIOReturnSuccess)
{
ERROR_LOG(WIIMOTE, "Unable to do bluetooth discovery");
return;
}

CFRunLoopRun();
do
{
CFRunLoopRun();
}
while(!sbt->done);

[bti stop];
int found_devices = [[bti foundDevices] count];

if (found_devices)
Expand All @@ -160,7 +165,7 @@ - (void) l2capChannelClosed: (IOBluetoothL2CAPChannel *) l2capChannel
continue;

Wiimote *wm = new Wiimote();
wm->btd = dev;
wm->btd = [dev retain];

if(IsBalanceBoardName([[dev name] UTF8String]))
{
Expand All @@ -184,31 +189,36 @@ - (void) l2capChannelClosed: (IOBluetoothL2CAPChannel *) l2capChannel
}

// Connect to a wiimote with a known address.
bool Wiimote::Connect()
bool Wiimote::ConnectInternal()
{
if (IsConnected())
return false;

ConnectBT *cbt = [[ConnectBT alloc] init];

cchan = ichan = nil;

[btd openL2CAPChannelSync: &cchan
withPSM: kBluetoothL2CAPPSMHIDControl delegate: cbt];
[btd openL2CAPChannelSync: &ichan
withPSM: kBluetoothL2CAPPSMHIDInterrupt delegate: cbt];
if (ichan == NULL || cchan == NULL)
// Apple docs claim:
// "The L2CAP channel object is already retained when this function returns
// success; the channel must be released when the caller is done with it."
// But without this, the channels get over-autoreleased, even though the
// refcounting behavior here is clearly correct.
[ichan retain];
[cchan retain];
if (ichan == nil || cchan == nil)
{
ERROR_LOG(WIIMOTE, "Unable to open L2CAP channels "
"for wiimote %i", index + 1);
Disconnect();

DisconnectInternal();
[cbt release];
[ichan release];
[cchan release];
return false;
}

// As of 10.8 these need explicit retaining or writing to the wiimote has a very high
// chance of crashing and burning.
[ichan retain];
[cchan retain];

NOTICE_LOG(WIIMOTE, "Connected to wiimote %i at %s",
index + 1, [[btd addressString] UTF8String]);
Expand All @@ -220,20 +230,19 @@ - (void) l2capChannelClosed: (IOBluetoothL2CAPChannel *) l2capChannel
}

// Disconnect a wiimote.
void Wiimote::Disconnect()
void Wiimote::DisconnectInternal()
{
if (btd != NULL)
[btd closeConnection];

if (ichan != NULL)
[ichan release];
[ichan closeChannel];
[ichan release];
ichan = NULL;

if (cchan != NULL)
[cchan release];
[cchan closeChannel];
[cchan release];
cchan = NULL;

[btd closeConnection];
[btd release];
btd = NULL;
cchan = NULL;
ichan = NULL;

if (!IsConnected())
return;
Expand All @@ -248,18 +257,19 @@ - (void) l2capChannelClosed: (IOBluetoothL2CAPChannel *) l2capChannel
return m_connected;
}

int Wiimote::IORead(unsigned char *buf)
void Wiimote::IOWakeup()
{
int bytes;
CFRunLoopStop(m_wiimote_thread_run_loop);
}

if (!IsConnected())
return 0;
int Wiimote::IORead(unsigned char *buf)
{
input = buf;
inputlen = -1;

bytes = inputlen;
memcpy(buf, input, bytes);
inputlen = 0;
CFRunLoopRun();

return bytes;
return inputlen;
}

int Wiimote::IOWrite(const unsigned char *buf, int len)
Expand Down

0 comments on commit 2fb0147

Please sign in to comment.