PDA

View Full Version : Bluetooth connection failing (suspected race condition)




Tweetdezweet
Jun 5, 2013, 02:46 AM
I'm trying to get my app to remember the last used bluetooth and use that as a default.
With the code below I have "rfcommChannelOpenComplete" returning an error (error code 11).
However it doesntt always return an error which makes me think I got some sort of race condition going on.

Any help is appreciated, if more info is needed plz dont hesitate to ask me :)

Called in "applicationDidFinishLaunching"
[self setUpBluetoothConnection];

- (void) setUpBluetoothConnection {
_btDevice = nil;
self.connectionOpened = false;

CFStringRef keyForMacAddresOfLastUsedCube = CFSTR("last_used_device");
CFStringRef macAddressOfLastUsedCube;

macAddressOfLastUsedCube = (CFStringRef)CFPreferencesCopyAppValue(keyForMacAddresOfLastUsedCube, kCFPreferencesCurrentApplication);
if(macAddressOfLastUsedCube) {
_btDevice = [IOBluetoothDevice deviceWithAddressString:(__bridge NSString *)(macAddressOfLastUsedCube)];
if(_btDevice != nil) {
[self connectToCube];
} else {
[self showAddBluetoothDeviceWindow];
}
} else {
[self showAddBluetoothDeviceWindow];
}
}


- (void) connectToCube {
if(_btDevice != nil) { //so I have something to query.
NSLog(@"I gottcha!");
IOReturn ret = [_btDevice performSDPQuery:self]; //some delegate methoed called after SDP is finished.
if (ret != kIOReturnSuccess) {
NSLog(@"something went wrong");
return;
}

BluetoothRFCOMMChannelID rfCommChan;
if([self findRfCommChannel:&rfCommChan] != kIOReturnSuccess) //check If the device have RFCOMM channel.
return;

NSLog(@"Found rfcomm channel on device.. %d",rfCommChan);
self.connectionOpened = [self openConnection:&rfCommChan];
} else {
NSLog(@"Not Found!");
}
}

-(IOReturn) findRfCommChannel:(BluetoothRFCOMMChannelID *) rfChan{
if(self.btDevice == nil)
return kIOReturnNotFound;
IOReturn ret;

NSArray* services = [_btDevice services];
BluetoothRFCOMMChannelID newChan;
for (IOBluetoothSDPServiceRecord* service in services) {
NSLog(@"Service: %@", [service getServiceName]);
ret = [service getRFCOMMChannelID:&newChan];
if (ret == kIOReturnSuccess) {
*rfChan = newChan;
NSLog(@"ChannelID FOUND %d %d", newChan, *rfChan);
return kIOReturnSuccess;
}
}

return kIOReturnNotFound;
}


-(BOOL) openConnection:(BluetoothRFCOMMChannelID *) chanId{
IOBluetoothRFCOMMChannel *channel;
if ([_btDevice openRFCOMMChannelAsync:&channel withChannelID:*chanId delegate:self] != kIOReturnSuccess) { // after connection it is established.. the delegates methoed are triggered.
NSLog(@"Couldn't open channel");
return NO;
}
[channel setSerialParameters: 9600 dataBits: 8 parity: kBluetoothRFCOMMParityTypeNoParity stopBits: 2];
[channel closeChannel];
return YES;
}

//delegate RFComm channel
- (void)rfcommChannelOpenComplete:(IOBluetoothRFCOMMChannel*)rfcommChannel
status:(IOReturn)error {
if (error != kIOReturnSuccess) {
NSLog(@"Failed to open channel, error %d", error);

return;
}

NSLog(@"channel complete");

NSLog(@"Channel MTU: %hu", [rfcommChannel getMTU]);

self.rfcommChannel = rfcommChannel;
}



Tweetdezweet
Jun 5, 2013, 04:26 AM
I did some more digging and the response code 11 (0x0B) seems to indicate the device is waiting for the pin code, not sure though