July 2009


Since starting on the Widcomm support its always been hoped that we could allow applications to use both the Microsoft and Widcomm stack at the same time (or any combinations of stacks supported on the machine).  Then an application could connect to more devices than it could when just using one stack alone.  This is partly necessary because those two stacks each only support one connected radio (Bluetooth Controller) — unlike BlueZ on Linux for instance which supports more than one.

I’ve added support for loading two or more stack types at a time in the library in preparation for this (it’s disabled in the 2.4 release however).  However, although I’ve not had a lot of time to play with this, I haven’t managed to get the two stacks to work at the same time.  It appears that even if the MSFT stack support isn’t loaded but I have my MSFT-stack dongle connected then the Widcomm API doesn’t work…  Has anyone else seen this?  Maybe it’s Widcomm version dependent?  I’m using 3.0.1.912 (via Belkin).

Has anyone else tried this scenario?

 

There are various ways to disable loading the MSFT stack.  Either run in the debugger and set a breakpoint in InTheHand.Net.Bluetooth.BluetoothFactory.GetStacks_inLock, and don’t allow the loop to load the MSFT stack factory.  Or, the correct way is to use configuration settings.  After 2.4 I’ve added this support.  Add a configuration file like the following to disable the MSFT stack.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="InTheHand.Net.Personal">
      <section name="BluetoothFactory"
           type="InTheHand.Net.Bluetooth.BluetoothFactorySection, InTheHand.Net.Personal"
           requirePermission="false" />
    </sectionGroup>
  </configSections>
  <!-- -->
  <InTheHand.Net.Personal>
    <BluetoothFactory>
      <stackList>
        <remove name="InTheHand.Net.Bluetooth.SocketsBluetoothFactory" />
      </stackList>
    </BluetoothFactory>
  </InTheHand.Net.Personal>
</configuration>

And in passing, to enable multi-stack support in the library (with all errors reported) use a configuration file with the following element. 🙂

...
<BluetoothFactory reportErrors="true"
    oneStackOnly="false" >
</BluetoothFactory>
...

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

This seems to have been a generally useful and successful release.  (Let me know if you feel otherwise ;-))  However I did get some interesting feedback which made me rethink some features in the Widcomm support.  Firstly I’ll include a quick overview of the features which were supported on Widcomm, then I’ll briefly discuss the feedback and on each I’ll write a new post.  For full info in what was supported in the release see the “32feet and Widcomm-Broadcom.doc” document in the release.

On the client-side support is good, client connections should work well, the only caveat with data transfer being that Widcomm discards any data received just before the sender closes the connection.  Device discovery works well and checking whether a device is remembered/paired/RSSI also.  Getting a device’s SDP record is also supported but we don’t attempt to read all the attributes in the record (the Widcomm API doesn’t supply the whole raw record for parsing, but we could read simple attributes if required).

Server-side support is less mature, only a little time having been spent on creating BluetoothListener for Widcomm.  In particular, as discussed in the forums just before the release, a connection is only accepted if the consumer application has called Accept/BeginAccept before the connection is received.  I’ve code ready for testing for listener which provides full support and thus fixes this bug.  I’ll post on that soon.

The first piece of feedback, though only from one correspondent, was regarding connecting to multiple devices at the same time, and to devices that might not be in range. The Widcomm API does not make this easy as certain operations can only be called one at a time but we hopefully can improve things a little there.  I’ll also post on that soon.

Secondly was help with Widcomm set-up on desktop Windows.  In the pre-release phase most users were on Windows Mobile so I didn’t spend much time making diagnostics available to help troubleshoot set-up on desktop Windows.  Various dependencies are required there (a Widcomm DLL, and VC++ runtime DLLs).  I’ve done some work on improving that, more information to follow. 

Finally a correspondent noted a bug in OBEX which would occur when connecting to the OBEX Folder-Browsing service (“OBEX FTP” in Bluetooth terms).  I’ve generally left OBEX issues to other’s, but I’ll take more interest now.  Four issues were fixed — though of them two would occur for FTP connections only, its likely that only OBEX Inbox/Push connections worked previously, and the other two would only rarely occur.

This is a blog for discussion of development on the 32feet.NET library, which provides Bluetooth, IrDA, and OBEX support for .NET. The library is available from http://inthehand.com/content/32feet.aspx and http://www.codeplex.com/32feet/. I am Alan McFarlane, the maintainer of the library and am based in Scotland. 🙂

The main recent work has been on adding Widcomm/Broadcom support to the library, and I’ve been working on that for around seven months. The code repository (at CodePlex) contains a document on that project (32feet and Widcomm.doc), it is kept up-to-date with the status of the support, but there has been interest from many parties in learning more about the current and future development work, and also the best way to contribute.

So I hope to write here on those subjects, discussing what features I’m working on and what help would be useful. Often I have implemented support for a feature but it needs testing before I want it to hit the trunk repository. I could post that code here and if feedback says that it works well and doesn’t break anything then it would allow me to commit the new feature quicker.

Alan