Page 1 of 1

Dual MS & Widcomm Bluetooth support

PostPosted: Mar 27, 2007 @ 1:06am
by Dan East

PostPosted: Mar 27, 2007 @ 11:34pm
by Kzinti

PostPosted: Mar 29, 2007 @ 10:08pm
by David Horn
I'm working on a project involving Pocket PCs and bluetooth, and made the decision to go with the 32feet library.

At worst I lose compatibility with some pre-WM5 devices, and at best 32feet will update the library to natively support Widcomm and the MS stack.

PostPosted: Mar 30, 2007 @ 12:59am
by Dan East
As long as your devices have the MS stack and not Widcomm you'll be okay with that library. :) Unfortunately, Widcomm is much more prevalent. Out of the 3 bluetooth PPCs I have (Asus a716, Axim x50v, Treo 700w) 2 use Widcomm and the Treo uses MS.

Dan East

PostPosted: Apr 3, 2007 @ 10:34am
by drgoldie
Actually I don't really see the problem with that class based design of Widcomm. At some point you will have to abstract the two different APIs anyhow in your application. So the only difference is that you put each implementation (or at least the Widcomm one) into a DLL and try to load it...

Daniel

PostPosted: Apr 3, 2007 @ 11:55am
by Dan East

PostPosted: Apr 3, 2007 @ 12:01pm
by drgoldie

PostPosted: May 18, 2007 @ 1:29am
by Dan East
Here is a quick, dirty and superficial description of how things work in the MS an Widcomm stacks.

With Widcomm you have to define classes derived from various Widcomm base classes. These have virtual members that are called when certain things happen.

So for example, to find bluetooth devices, you derive a class from CBtIf, and call the StartInquiry member. Each time a bluetooth device is encountered your overloaded OnDeviceResponded member is called, and you must store the device address away somewhere. When all devices have been iterated (meaning some timeout threshold has been reached) your OnInquiryComplete member is called.

Then you call StartDiscovery for each device that was found, passing the device address and the service GUID you're looking for. When the stack is done talking to the device (or times out) your OnDiscoveryComplete member is called. You then call ReadDiscoveryRecords, the return code of which will let you know if it discovered the service. If it did, you call FindRFCommScn which provides the 64 bit ID of the service (port) that you will connect to.

Now, once you've found something to connect to, the process is similar for actual data transfer, but worse. It is worse because with discovery you can pretty much just block (using events) until you've found something or given up. With data transfer you derive from CRfCommPort, and your overloaded OnDataReceived will be hammered, from some other thread, as data packets flow. So you'll need to setup some thread safe method of storing away that received data, and add in flow control to stop the data flow whenever your cache grows too big. I use a linked list with a node per packet, while keeping track of how much I've allocated and calling SetFlowEnabled if I've exceeded my cache size. My app's thread is grabbing data out as it needs it, again, in a thread-safe fashion (Critical Sections), and enables flow when enough of the cache has been consumed.

That's all Widcomm specific. With MS stack some parts are saner, like iterating devices and the actual IO. However finding the specific service on a device and connecting to it is far more complex.

To find devices it is all iterative, using WSALookupServiceBegin and WSALookupServiceNext. A few lines of code is all that is required to simply see what devices are out there. Finding a service is a royal pain in the butt, and requires some really low level crap with BT. It involves COM (as in Component Object Model) interfaces, that have to be invoked to parse a bunch of junk, to first find your desired service GUID, and second, extract the port that service is bound to. Once you have that, you simply connect to it as you would any old socket, and the rest is typical socks stuff.

A portion of the original code I hacked up to find a specific service on a device is here:
http://www.developer.com/ws/other/print ... _3640576_3

Anyway, the whole BT experience was an ordeal with both stacks. At least the Widcomm stack was bread and butter stuff for me - thread safety being the most complex part, and having to wrap it in a separate DLL because you can't dynamically link to their DLL (unless you don't care that your app can't execute on non-widcomm devices). So basically it was just a bit of tedium doing extra work because they like C++ classes and multithreading so much. With MS I felt like I was delving too far into the deep, dark chasms of the bloated, consortium-defined Bluetooth specifications for my liking. It was too much out of my control, and dependent on traversing complex data structures that are proprietary to bluetooth.

Dan East