I've been trying to read data from a device via Bluetooth 2.1 using an RN-42. The device pairs to an iPhone or iPad Mini, and data is streamed across briefly, but the iOS & BT module disconnect (unpair) within seconds (less than 10). The device is outputting data 5-10kB/s, so well within Bluetooth’s spec. Something that I’ve also noticed is that when I run the function NSInputStream, [NSInputStream read: maxLength:], the number of bytes returned is always 158 or less. The app and hardware don’t crash, but the Bluetooth just unpairs.
The device is still sending data to the RN42 even after the disconnect, which reduces the likelihood of a problem on the electronics side. This setup also works perfectly fine on Android devices. I can stream data without any disconnects or crashes.
Things I’ve tried...
- followed the External Accessory example, EADemo, provided by Apple.
- purely using the run-loop instead of polling.
- putting the stream on a background thread as suggested in this post.
- removing all NSLogs to help with performance.
- compiled in debug and release modes.
One thing which sort of works is slowing down the data transfer (i.e. less than 5kB/s), as that allows the iOS and BT module to stay connected and transfer data longer before disconnecting.
#define EAD_INPUT_BUFFER_SIZE 1024
/**
* Stream delegate
*/
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
switch (eventCode) {
[... other cases ...]
case NSStreamEventHasBytesAvailable:
{
uint8_t buf[EAD_INPUT_BUFFER_SIZE];
unsigned int len = 0;
len = [(NSInputStream *)aStream read:buf maxLength:EAD_INPUT_BUFFER_SIZE];
if(len) {
// Read successful, process data
} else {
// Fail
}
break;
}
default:
break;
}
}
/**
* Stream delegate with polling (for better or worse)
*/
[...]
case NSStreamEventHasBytesAvailable:
{
while ([[_session inputStream] hasBytesAvailable])
{
// Read the data
NSInteger bytesRead = [[_session inputStream] read:_buf maxLength:EAD_INPUT_BUFFER_SIZE];
if (bytesRead > 0) {
// Read successful, process data
} else if (bytesRead == 0) {
// End of buffer reached
return;
} else if (bytesRead == -1) {
// Failed to read
return;
}
}
break;
[...]