Uncategorized
June 14, 2011
March 8, 2011
A page from the BlueCove Java Bluetooth library documentation showing how to identify which Bluetooth stack is installed http://www.bluecove.org/bluecove-examples/bluetooth-stack.html It shows screenshots of the device driver info on Windows XP for the Microsoft, Widcomm, and BlueSoleil stacks.
February 22, 2011
Support for Widcomm COM port creation
Posted by alanjmcf under Uncategorized, WidcommLeave a Comment
I’ve just checked in support for Widcomm’s COM Port creation classes. Access WidcommSerialPort.CreateClient and store the result and once you’ve finished with the COM port Dispose it, it’ll be Finalized if not referenced. I’ll look at integrating the functionality into the BluetoothSerialPort class sometime.
I’ve tested it on my Asus WM Classic device and it work fine there. The Widcomm documentation implies that it should work on Win32 too but it doesn’t work on my WinXP Widcomm v3 installation.
Download the library code (revision 85315 or later) from http://32feet.codeplex.com/SourceControl/list/changesets and compile the CF2 project to get the library code to use in your project. You’ll also need the new native Widcomm mapping DLL, get it from http://32feet.codeplex.com/releases/view/61443
Testing shows that if the connected devices go out of range then the connection is lost however (we see DISCONNECT event in the code, and the remote socket server sees close). Presumably we need to implement code to repeatedly retry to reconnect?
I’ve done about a day’s work on that. I’d be glad of a wee ‘reward’ for adding this new feature, particularly if it saves you time on your projects. 🙂 I’ve Amazon wishlist or paypal for instance.
February 3, 2011
Mostly as an aid memoire to myself, to help me remember how to find the version of radio (“controller” in official terminology IIRC) in the various Bluetooth stacks.
Microsoft on Windows XP, Windows 7 etc

Admin view of Windows XP Advanced tab of the Bluetooth Control Panel No version on Windows XP's non-admin view...
Widcomm/Broadcom
BlueSoleil
BlueZ on Linux
Not from hcitool:
alan@foobar:~/> hcitool dev Devices: hci0 00:15:83:B4:1B:FA hci1 00:80:98:24:4C:A4 alan@foobar:~/>
Yes from root hciconfig:
foobar:/home/alan # hciconfig hci0 version hci0: Type: BR/EDR Bus: USB BD Address: 00:15:83:B4:1B:FA ACL MTU: 384:8 SCO MTU: 64:8 HCI Version: 2.0 (0x3) Revision: 0x7a6 LMP Version: 2.0 (0x3) Subversion: 0x7a6 Manufacturer: Cambridge Silicon Radio (10) foobar:/home/alan # hciconfig hci1 version hci1: Type: BR/EDR Bus: USB BD Address: 00:80:98:24:4C:A4 ACL MTU: 192:8 SCO MTU: 64:8 HCI Version: 1.1 (0x1) Revision: 0x20c LMP Version: 1.1 (0x1) Subversion: 0x20c Manufacturer: Cambridge Silicon Radio (10) foobar:/home/alan # hciconfig -a hci0: Type: BR/EDR Bus: USB BD Address: 00:15:83:B4:1B:FA ACL MTU: 384:8 SCO MTU: 64:8 UP RUNNING PSCAN RX bytes:1677 acl:0 sco:0 events:41 errors:0 TX bytes:498 acl:0 sco:0 commands:41 errors:0 Features: 0xff 0xff 0x8f 0xfe 0x9b 0xf9 0x00 0x80 Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3 Link policy: RSWITCH HOLD SNIFF PARK Link mode: SLAVE ACCEPT Name: 'linux-0' Class: 0x4a0100 Service Classes: Networking, Capturing, Telephony Device Class: Computer, Uncategorized HCI Version: 2.0 (0x3) Revision: 0x7a6 LMP Version: 2.0 (0x3) Subversion: 0x7a6 Manufacturer: Cambridge Silicon Radio (10) hci1: Type: BR/EDR Bus: USB BD Address: 00:80:98:24:4C:A4 ACL MTU: 192:8 SCO MTU: 64:8 UP RUNNING PSCAN RX bytes:689 acl:0 sco:0 events:22 errors:0 TX bytes:86 acl:0 sco:0 commands:22 errors:0 Features: 0xff 0xff 0x0f 0x00 0x00 0x00 0x00 0x00 Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3 Link policy: Link mode: SLAVE ACCEPT Name: 'ALANPC1a' Class: 0x4a0000 Service Classes: Networking, Capturing, Telephony Device Class: Miscellaneous, HCI Version: 1.1 (0x1) Revision: 0x20c LMP Version: 1.1 (0x1) Subversion: 0x20c Manufacturer: Cambridge Silicon Radio (10) foobar:/home/alan #
Version Numbers
The X.X e.g 1.1, 3.0, version numbers are actually represented by a simple integer, HCI and LMP strictly don’t use the same definitions but the two use the same numbering system currently and likely will do forever. The current definitions are:
| 0 | Bluetooth Core Specification 1.0b |
| 1 | Bluetooth Core Specification 1.1 |
| 2 | Bluetooth Core Specification 1.2 |
| 3 | Bluetooth Core Specification 2.0 + EDR |
| 4 | Bluetooth Core Specification 2.1 + EDR |
| 5 | Bluetooth Core Specification 3.0 + HS |
| 6 | Bluetooth Core Specification 4.0 |
| 7 – 255 | Reserved |
The definitions are available at https://www.bluetooth.org/Technical/AssignedNumbers/hci.htm and https://www.bluetooth.org/Technical/AssignedNumbers/link_manager.htm The Bluetooth specification documents have moved, unfortunately there’s a fault on the HCI document which requires Bluetooth log-in to access. (http://bluetooth.com/Specification%20Documents/AssignedNumbersHostControllerInterface1.pdf and http://bluetooth.com/Specification%20Documents/AssignedNumbersLinkManager1.pdf)
October 12, 2010
Release Notes
The main features and bug fixes in this release are as follows. For Bluetooth:
• FIX BluetoothRadio.LocalAddress is all zeros in v2.5 on WM+MSFT (bug 26123) — as broken at version 2.5
• Live discovery — prototype for Widcomm and WM+MSFT (bug 28491) — see the User Guide for more information
• Support setting BluetoothRadio.Name on Win32+MSFT (bug 26149)
• SDP support for 64-bit integers and parsing 128-bit integers (bug 26118, 26119, 28884)
For Bluetooth on Widcomm:
• Support BtRadio.set_Mode (can CE/WM only) (bug 26239)
• BtRadio.Mode reports wrong values when radio has been turned off (bug 26240) — this requires a recent versions of the Widcomm stack
• Fully Widcomm threading compatible including on CE/WM — this is for instance visible to the developer in that Connect can now be called from EndDiscoverDevices etc (bug 26186, 26194, 26195, 26868)
• Close connections on app crash etc (bug 28628)
• Use OnStackStatusChange to close connections when radio turned off (bug 28623)
There are no OBEX or IrDA changes in this release.
For Widcomm, various users have reported that there are problems on desktop Windows with newer versions of the Widcomm stack, with for instance BluetoothClient.Connect failing with a SocketException with it message including the code “PortLookup_NoneRfcomm”. We now supply two versions of 32feetWidcomm.dll for Win32 for this reason. Unfortunately when to use them is complex— I wish Widcomm had been a bit cleverer about how they provided their Vista support. 😦 (Note that Bluecove on Java also has to supply two versions of the DLL presumably for similar reasons ).
- Normal 32feetWidcomm.dll version: Works even when the Microsoft Bluetooth stack is also active, and so allows multi-stack support. But might not work on newer version installations of the Widcomm stack.
- “SDK6” version: May be required on newer version installations of the Widcomm stack, but will not work when the Microsoft Bluetooth stack is active.
We also now include copies of the 32feetWidcomm.dll for x64, let me know if it works for you, it is untested by us.
July 27, 2010
—- Preliminary, needs tidying —-
Users coming to .NET from other platforms are often surprised that they have to do blocking reads on a Stream or Socket to read data from the network. And when they asks how to stop blocking the UI, the normal answer is to tell the them either to move the stream/socket reading onto a background thread, or to use the APM (asynchronous programming model) with the BeginRead/EndRead methods…
Which is ok until the programmer soon asks what “cross-thread” exceptions are. Since both of those schemes have the data-arrival code run on a different thread than the UI we then have to explain all the complexity of cross-thread marshalling, whether using Control.BeginInvoke on WinForms, or the more general SyncronizationContext use.
So why don’t we just have the data arrival signalled by event, that’s how VB did it, and automatically ensure that the event runs on the UI thread. So the user simply signs-up for the respective events and all his/her problems are solved: no blocking, and no cross-thread marshalling required.
Until such a class is provided in the FCL (framework class library) the following will have to do. 🙂
Add this into a new file in your project (converting to C# if necessary). Then subscribe to the events, set it running on the connection and all should be good.
'
' Copyright (c) 2009 Alan J. McFarlane
' Free for any use. No rights reserved.
'
Option Explicit On
Option Strict On
Imports System
Imports System.IO
Imports System.Threading
''' <summary>
''' Raises events when data is received on a <see cref="T:System.IO.Stream" />
''' </summary>
''' <remarks>
''' <para>Raises three events <see cref="E:DataReceived" />, <see cref="E:ConnectionClosed" />,
''' and <see cref="E:ErrorOccurred" />.
''' </para>
''' <para>The events are called on the correct synchronization context, e.g. on
''' the UI thread in a WinForms app.
''' </para>
''' </remarks>
''' -
''' <example>
''' <code>
''' ...
''' Dim strm As Stream = cli.GetStream() ' etc...
''' Dim efs As New EventFromStream() ' We pick-up the UI thread when initialised
''' AddHandler efs.DataReceived, AddressOf HandleDataReceived
''' AddHandler efs.ErrorOccurred, AddressOf HandleErrorOccurred
''' AddHandler efs.ConnectionClosed, AddressOf HandleConnectionClosed
''' efs.Run(strm)
''' ...
''' End Sub
'''
''' Sub HandleDataReceived(ByVal sender As Object, ByVal e as DataReceivedEventArgs)
''' Dim data() As Byte = e.Data
''' ...
''' End Sub
''' ...
''' </code>
''' </example>
Class EventFromStream : Inherits System.ComponentModel.Component
Private m_strm As Stream
Private m_syncCtx As SynchronizationContext
Private m_disposed As Integer
Private m_disposedEvent As New ManualResetEvent(False)
'----
Friend Sub New()
m_syncCtx = SynchronizationContext.Current
End Sub
Overloads Sub Dispose(ByVal disposing As Boolean)
Try
Thread.VolatileWrite(m_disposed, 1)
m_disposedEvent.Set()
' Should we close the Stream? It makes life much easier for us if
' we do but
Finally
MyBase.Dispose(disposing)
End Try
End Sub
Private ReadOnly Property IsDisposed() As Boolean
Get
Dim v As Integer = Thread.VolatileRead(m_disposed)
Dim disposed As Boolean = v <> 0
Return disposed
End Get
End Property
'----
Public Event DataReceived As EventHandler(Of DataReceivedEventArgs)
Public Event ConnectionClosed As EventHandler(Of EventArgs)
Public Event ErrorOccurred As EventHandler(Of ErrorEventArgs)
'----
Public Sub Run(ByVal strm As Stream)
If m_strm IsNot Nothing Then Throw New ArgumentException("Supports one stream at the moment")
m_strm = strm
ThreadPool.QueueUserWorkItem(AddressOf Runner)
End Sub
Private Sub Runner(ByVal state As Object)
Dim buf(1024 - 1) As Byte
While True
Dim readLen As Integer
Try
#If False Then
readLen = m_strm.Read(buf, 0, buf.Length)
#Else
' Use the async version so we can exit when disposed
Dim ar As IAsyncResult = m_strm.BeginRead(buf, 0, buf.Length, Nothing, Nothing)
Dim ah() As WaitHandle = {ar.AsyncWaitHandle, m_disposedEvent}
Dim signalled As Integer = WaitHandle.WaitAny(ah, -1)
If signalled = 0 Then
readLen = m_strm.EndRead(ar)
Else
' We leave that BeginReceive hanging in this case. :-( There's
' not much we can do about that (well we could start a thread
' sitting on EndRead...).
' It would be much nicer if we closed the stream when we were
' disposed...
Exit While
End If
#End If
Catch ex As Exception
' Probably due to the stream closing, so ignore.
If IsDisposed Then Exit While
DoError(ex)
Exit While
End Try
If readLen = 0 Then
DoConnectionClosed()
Exit While
End If
DoDataReceived(Clone(buf, 0, readLen))
End While
End Sub
'--
Private Sub DoError(ByVal ex As Exception)
m_syncCtx.Send(AddressOf DoErrorS, ex)
End Sub
Private Sub DoErrorS(ByVal state As Object)
Dim ex As Exception = CType(state, Exception)
RaiseEvent ErrorOccurred(Me, New ErrorEventArgs(ex))
End Sub
'--
Private Sub DoConnectionClosed()
m_syncCtx.Send(AddressOf DoConnectionClosedS, Nothing)
End Sub
Private Sub DoConnectionClosedS(ByVal state As Object)
RaiseEvent ConnectionClosed(Me, New EventArgs)
End Sub
'--
Private Sub DoDataReceived(ByVal data() As Byte)
m_syncCtx.Send(AddressOf DoDataReceivedS, data)
End Sub
Private Sub DoDataReceivedS(ByVal state As Object)
Dim data() As Byte = CType(state, Byte())
RaiseEvent DataReceived(Me, New DataReceivedEventArgs(data))
End Sub
'----
Private Function Clone(ByVal buf As Byte(), ByVal offset As Integer, ByVal length As Integer) As Byte()
' Create a new array of the correct size
Dim buf2() As Byte = CType(Array.CreateInstance(GetType(Byte), length), Byte())
Array.Copy(buf, offset, buf2, 0, length)
Return buf2
End Function
End Class
Class DataReceivedEventArgs : Inherits EventArgs
Private m_data() As Byte
Friend Sub New(ByVal data() As Byte)
m_data = data
End Sub
Public ReadOnly Property Data() As Byte()
Get
Return m_data
End Get
End Property
End Class
November 11, 2009
Currently the codeplex repository has the namespace folders arranged in a hierarchical fashion, i.e. Net/*.cs, Net/Bluetooth/*.cs, Net/Bluetooth/Sdp2/*.cs etc. This is rather unwieldy to work with, for instance if one wants to see files in Net/Bluetooth/Sdp2/ one has to have both it and the two parent folder open which takes up lots of space with the files from all three. I intend to change this to be a simple list of folders at the top level: Net/, Net/Bluetooth/, Net/Bluetooth/Sdp2, … , Net/Socket/ etc.
This might affect people who use a source control client to keep in sync with the code (e.g. the VS Team System client (is this the correct name?), or an SVN client for instance). People who do a complete download using the ZIP file download shouldn’t be affected. Hopefully the source-code-control clients recognise a “folder rename” operation and just move the files in the folder locally instead of having to re-download them. Also things might behave worse if there’s a local edit to a file the moves folder. So I’ll hold off from making any major changes until Friday at the earliest.
I’ve made two changes already to test how things behave. I moved Net/IrDA/ and Net/Mime/. In the latter test I made a local edit in one (team-system) repository and carried out the folder renaming in another repo. Then on updating the first repository the following sequence of operations occurred:
- A dialog box reporting ‘ could not delete non-empty folder “Mime”‘ or words to that effect. I just clicked the OK button.
- The conflicts dialog was then displayed and I clicked “Resolve all automatically”. I was then prompted about the ‘moved and edited’ file to which I asked it to merge the local changes. It then asked whether to keep the local name or the server name, I chose the latter.
- After all that everything looked ok. The file was in the correct folder and with my local change present. (The old Net/Mime/ folder was still present as implied by #1, but it was of course empty and I deleted it manually for tidyness.
It wasn’t clear in these cases whether the moved files were re-downloaded or just shifted locally.
Let me know if this will cause any great difficulties.
July 13, 2009
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.
July 12, 2009
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



