On the Widcomm stack if you call connect on two (or more) BluetoothClients in close succession the the latter connect might fail with NotSupportedException(“Currently support only one concurrent Service Lookup operation.”).  This occurs because Widcomm supports only one SDP lookup at a time, which seems very restrictive.  This situation is of course much more likely to happen if the first device is not in range, in that case the Widcomm SDP lookup takes thirty seconds to timeout and return failure.  This also affects BluetoothDeviceInfo.GetServiceRecords which uses the same service lookup infrastructure.  I has some people asking how they can workaround this.

So there’s multiple ways we can think of handling this:

  1. Do nothing
    Hope that multiple connects will be rare, or the caller will have to retry a connect later if it fails due to this.
  2. Serialise the SDP lookups internally
    Rather than having the caller ensure there’s only one outstanding connect we could internally keep a queue of SDP lookup requests and carry them out as each completes.  The problem with this is that the delay for the queued items could quickly increase if one or more of the target devices are not in range, and then the developer/user will get confused as to why the connects are taking an age to complete.
  3. Find some way to detect if a device is not in range before starting the SDP query
    There are two functions available on later versions of the stack:  CBtIf::IsRemoteDeviceConnected and CBtIf::IsRemoteDevicePresent, they’re present on BTW in 5.0.1.300 and  5.0.1.1000 respectively, and on WCE on 1.7.1.2700 (both).  If they work well we could use these before calling the SDP lookup and thus allow multiple operations…
    We firstly want the results to be correct; in particular that we don’t get false negatives — that is that they don’t report the device as not in range if SDP lookup would find it in range.  Secondly we need these methods to be reasonably fast[2].  And ideally that they can be called for multiple targets at the same time!  Of the last two we need at least one to be the case; if they are quick but can’t be used concurrently we can serialise them if they can only be called for one device at a time.

The last is obviously the best solution, we could even combine it with number 2 if required if they are reasonably quick.

Unfortunately I don’t have a device that supports these functions[2].  So I need your feedback.  I’ve implemented support for these methods in the code in the repository.  They’re accessible at the top level in WidcommPlaying.FindIfPresentOrConnected.  I’ve created one test option WidcommIsPresentConnected in the ConsoleMenuTesting/DeviceMenuTesting programs to test this, which calls the above function once.  We’ll need more to test the concurrent behaviour.

____

[1] The  WCE/Windows Mobile version of the stack seems to support one SDP lookup per remote device.  That’s much more useful than the restriction on Win32.  However it doesn’t seem worth complicating the code to support the two different restrictions when its more likely that multiple connects would be used on the Win32 where they aren’t supported.

[2]I expect that IsRemoteDeviceConnected will be fast, it should only be a lookup in the stack state to see whether there’s a connection to the specified device.  I wonder how long IsRemoteDevicePresent will take to timeout if the specified device is not present however…

[3] I have an iPAQ with 1.7.1.1424 and a desktop dongle with version 3.0.1.912.  Can someone recommend me a desktop dongle that comes with a recent Widcomm version?  Or how I can find a cheap PPC with a later stack version.

FindIfPresentOrConnectedFindIfPresentOrConnected
Advertisements