Re: Momentary out of range problems
Re: Momentary out of range problems
- Subject: Re: Momentary out of range problems
- From: Peter Sichel <email@hidden>
- Date: Tue, 13 Apr 2010 09:31:55 -0400
On Apr 13, 2010, at 12:39 AM, Chuck Carlson wrote:
> Hello,
>
> I've got a data-logger type bluetooth system, data is mostly streaming to the Mac/PC. On the PC, if I momentarily go out of range, then back in,the data flow resumes quickly. On the Mac, a few seconds after the loss, even when I'm well back in range, I get disconnected, then I have to go through the reconnection process.
>
> Any strategies, settings to avoid this?
Are you in control of the Bluetooth client software on the Mac?
In my own experience developing Phone Amego, the details of maintaining a Bluetooth connection took some study and testing to resolve. Here's how I do it:
(1) When the user first selects a paired Bluetooth device, I record the corresponding IOBluetoothServiceRecord and use this to open an RFCOMM channel to corresponding channel ID.
(2) A short time after the device (Bluetooth cell phone) moves out of range, the RFCOMM channel delegate is notified the connection has closed.
(3) I set the RFCOMM channel delegate to nil, release the previous RFCOMM channel object, and then try to open a new RFCOMM channel (this often works fairly quickly).
(4) If that fails, I close the device connection and try again.
(5) If that fails I mark the device as out-of-range and attempt a remoteNameRequest every 30 seconds to detect when the device comes back into range.
(6) When the device is detected to be back in range (remoteNameRequestComplete: status:kIOReturnSuccess), I do an sdpQuery. The documentation is a little vague here saying you should do an SDP query to determine if the desired channel still exists since the channel assignments could change (and to work around a bug in early Leopard systems). I don't actually re-retrieve the device service records (yet :-)
(7) If the sdpQuery completes successfully (sdpQueryComplete: status:kIOReturnSuccess), I try again to open an RFCOMM channel to the requested channelID based on the previously saved IOBluetoothServiceRecord.
(8) When an RFCOMM channel opens successfully, I request and save the "ObjectID" of the open channel. This is significant because if your program is unable to close the channel normally for any reason, you will need this information.
(9) If opening an RFCOMM channel fails with error kIOReturnExclusiveAccess (exclusive access and device already open), I use the previously saved ObjectID to recover the RFCOMM channel object and close it.
Prior to Mac OS X 10.6, the Bluetooth stack would retain and release your RFCOMM channel delegate, and under certain rare scenarios could double release it causing the stack to abort. I developed two work arounds: a singleton RFCommEventDelegate that cannot be deallocated; and (b) having a built-in crash reporter to detect the abort signal and automatically relaunch the application after 30 seconds.
There is no Apple supplied sample code that covers all of these steps, and I may well be missing something. Embarrassing myself in public has been a good way to learn :-)
- Peter Sichel
Sustainable Softworks
FYI: Phone Amego is designed to maintain a Bluetooth connection with upto two Bluetooth phones simultaneously, so it needs to track two RFCOMM channels as described above.
http://www.sustworks.com/site/prod_phoneAmego_help/PhoneAmegoHelp.html
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Bluetooth-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden