From 5cfa33a8a81fc1903601acc4e7814669ad6e6b75 Mon Sep 17 00:00:00 2001 From: Juan Sebastian Casallas Date: Mon, 16 Jan 2012 21:40:16 -0600 Subject: [PATCH] [mac] Reopen outputChannel on wiiuse_io_write failure -The first write on ouputChannel may fail -Subsequent write calls are also prone to failure -Reopening the channel on failure should solve this problem --- src/io_mac.m | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/io_mac.m b/src/io_mac.m index a586417..80ab33d 100755 --- a/src/io_mac.m +++ b/src/io_mac.m @@ -755,8 +755,40 @@ int wiiuse_io_write(struct wiimote_t* wm, byte* buf, int len) IOBluetoothL2CAPChannel* channel = [IOBluetoothL2CAPChannel withL2CAPChannelRef:wm->outputCh]; IOReturn error = [channel writeSync:buf length:length]; - if (error != kIOReturnSuccess) - WIIUSE_ERROR("Unable to write over the output channel (id %i).", wm->unid); + + if (error != kIOReturnSuccess) + { + WIIUSE_ERROR("Unable to write over the output channel (id %i).", wm->unid); + WIIUSE_INFO("Attempting to reopen the output channel (id %i).", wm->unid); + + IOReturn error = [channel closeChannel]; + if (error != kIOReturnSuccess) + WIIUSE_ERROR("Unable to close the output channel (id %i).", wm->unid); + [channel setDelegate:nil]; + usleep(10000); + [channel release]; + wm->outputCh = 0; + + WiiConnect* connect = (WiiConnect*)(wm->connectionHandler); + + IOBluetoothDevice* device = [IOBluetoothDevice withDeviceRef:wm->device]; + channel = [connect openL2CAPChannelWithPSM:WM_OUTPUT_CHANNEL device:device delegate:connect]; + if (!channel) { + WIIUSE_ERROR("Unable to open L2CAP output channel (id %i).", wm->unid); + [device closeConnection]; + return kIOReturnNotOpen; + } + wm->outputCh = [[channel retain] getL2CAPChannelRef]; + usleep(20000); + + WIIUSE_INFO("Attempting to write again through the output channel (id %i).", wm->unid); + error = [channel writeSync:buf length:length]; + if (error != kIOReturnSuccess) + { + WIIUSE_ERROR("Unable to write again over the output channel (id %i).", wm->unid); + } + } + usleep(10000); [pool drain];