The Microsoft Bluetooth stack on Windows Vista added support for programming L2CAP and SCO connections.  Also added are a set of IOCTL codes for accessing the stack in various other ways.  Fifteen the codes are listed at http://msdn.microsoft.com/en-us/library/ff536601.aspx “Bluetooth Profile Driver I/O Function Codes” and are all supported from Vista onwards.  One more is defined at http://msdn.microsoft.com/en-us/library/ff536593.aspx “Bluetooth Vendor Commands and Events”, and is supported by “Microsoft Windows Vista SP2 and later operating system versions”

I have previously used the IOCTL_BTH_GET_LOCAL_INFO code for bug 30326 “Windows 7 BluetoothRadio HCI and LMP version numbers” which allows us to get the attached controllers HCI and LMP version numbers.

However when one looks at the Windows SDK header file (bthioctl.h) that defines these codes, we find more listed than are documented at MSDN.  The 15 above are as expected are defined for Vista (no service-pack) and later, these include IOCTL_BTH_GET_LOCAL_INFO, IOCTL_BTH_GET_DEVICE_INFO, IOCTL_BTH_SDP_CONNECT, also present are the ones for the L2CAP and SCO interfaces (e.g. IOCTL_INTERNAL_BTH_SUBMIT_BRB).  We then see the single code (IOCTL_BTH_HCI_VENDOR_COMMAND) which is included on Windows 7, and on Windows Vista with Service Pack 2 or with the Windows Vista Feature Pack for Wireless (KB942567).

Finally we see five that are defined there but not enabled in any current platform, these include IOCTL_BTH_EIR_GET_RECORDS and IOCTL_BTH_EIR_SUBMIT_RECORD.  These are disabled with the comment (sic):

#ifdef FULL_EIR_SUPPORT // in WUR this funcitonality is disabled

I’ve done some investigation to find out which codes are truly supported on which platforms.  I tested all user-level codes from 0 to 255 (i.e. 0x410300 to 0x4103FC).  On XP, as expected, all codes fail and return error 50 which is ERROR_NOT_SUPPORTED.  On Windows 7 again –we find the support matches the documentation.  All the ones disabled with that comment return that same error code, with only the sixteen documented working (all the others fail).

I guess this is not too surprising but i would have been nice to find that these extra features were present. :-,)

So to confirm on Windows 7 the supported user-level codes are:

0x410000 IOCTL_BTH_GET_LOCAL_INFO
0x410004 IOCTL_BTH_GET_RADIO_INFO
0x410008 IOCTL_BTH_GET_DEVICE_INFO
0×41000C IOCTL_BTH_DISCONNECT_DEVICE
0x410050 IOCTL_BTH_HCI_VENDOR_COMMAND
0x410200 IOCTL_BTH_SDP_CONNECT
0x410204 IOCTL_BTH_SDP_DISCONNECT
0x410208 IOCTL_BTH_SDP_SERVICE_SEARCH
0×41020C IOCTL_BTH_SDP_ATTRIBUTE_SEARCH
0x410210 IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH
0x410214 IOCTL_BTH_SDP_SUBMIT_RECORD
0x410218 IOCTL_BTH_SDP_REMOVE_RECORD
0×41021C IOCTL_BTH_SDP_SUBMIT_RECORD_WITH_INFO

Start-up, console/debug logging:

[Error 11:14:14.598] [UiaDbusBridge.RaiseAutomationEvent] Inconsistent provider -> wrapper mapping state
[Error 11:14:14.696] [UiaDbusBridge.RaiseAutomationEvent] Inconsistent provider -> wrapper mapping state
Exception creating factory 'InTheHand.Net.Bluetooth.SocketsBluetoothFactory, ex: System.DllNotFoundException: Irprops.cpl
  at (wrapper managed-to-native) InTheHand.Net.Bluetooth.Msft.NativeMethods:BluetoothFindFirstRadio (InTheHand.Net.Bluetooth.BLUETOOTH_FIND_RADIO_PARAMS&,intptr&)
  at InTheHand.Net.Bluetooth.Msft.WindowsBluetoothRadio.get_AllRadios () [0x00000] in <filename unknown>:0
  at InTheHand.Net.Bluetooth.Msft.WindowsBluetoothRadio.get_IsPlatformSupported () [0x00000] in <filename unknown>:0
  at InTheHand.Net.Bluetooth.SocketsBluetoothFactory..ctor () [0x00000] in <filename unknown>:0
  at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod*,object,object[],System.Exception&)
  at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00119] in /usr/src/packages/BUILD/mono-2.8/mcs/class/corlib/System.Reflection/MonoMethod.cs:523
BluezFactory platform: Unix = 0x00000004
got Manager
Dbus loop running
DefaultAdapter : ObjectPath
got Adapter
Now Registered2
InitRadios idPrimary: 0, dd: 14
Radio SUCCESS, addr: 001583B41BFA
got Manager
got Adapter
  got addrStr: 00:15:83:B4:1B:FA
got Manager
got Adapter
  got addrStr: 00:15:83:B4:1B:FA
InitRadios curDd: 15
Radio SUCCESS, addr: 001583B41BFA
got Manager
got Adapter
  got addrStr: 00:15:83:B4:1B:FA
got Manager
got Adapter
  got addrStr: 00:15:83:B4:1B:FA
Id: 0, DD: 16
Radio SUCCESS, addr: 001583B41BFA
got Manager
got Adapter
  got addrStr: 00:15:83:B4:1B:FA
got Manager
got Adapter
  got addrStr: 00:15:83:B4:1B:FA
Done BluezFactory init.

Get All Radios (one present):

---- GetAllRadios ----
1)  Radio, address: 00:15:83:B4:1B:FA
Mode: Discoverable
Name: linux-0
HCI Version: v2_0wEdr, Revision: 1958
LMP Version: v2_0wEdr, Subversion: 1958
ClassOfDevice: 4A0100, device: Computer / service: Network, Capturing, Telephony
Software: BlueZXxxx,  Hardware: CambridgeSiliconRadio, status: Running
Remote: ''

Logging:

got Manager
got Adapter
  got addrStr: 00:15:83:B4:1B:FA
got Manager
got Adapter
  got addrStr: 00:15:83:B4:1B:FA

Get DeviceInfo (i.e. new BluetoothDeviceInfo(BluetoothAddress.Parse(…)):

---- GetDeviceInfo ----
* FREDPC1w
Address: 000A3A686599
Remembered: False, Authenticated: False, Connected: False
LastSeen: 01/01/0001 00:00:00 (Unspecified), LastUsed: 01/01/0001 00:00:00 (Unspecified)
CoD: (0x000000)
 Device:  Miscellaneous (0x00) / Miscellaneous (0x0000)
 Service: None (0x00)
Rssi: failed

Logging:

got Manager
DefaultAdapter : ObjectPath
got Adapter
gonna FindDevice
GetDevice_ error: org.bluez.Error.DoesNotExist: Device does not exist
No dbus device properties.
_name is null
hci_read_remote_name ret: 0.

Get DeviceInfo to non-existent device:

---- GetDeviceInfo ----
* 00:22:33:44:55:66
Address: 002233445566
Remembered: False, Authenticated: False, Connected: False
LastSeen: 01/01/0001 00:00:00 (Unspecified), LastUsed: 01/01/0001 00:00:00 (Unspecified)
CoD: (0x000000)
 Device:  Miscellaneous (0x00) / Miscellaneous (0x0000)
 Service: None (0x00)
Rssi: failed

Logging:

got Manager
DefaultAdapter : ObjectPath
got Adapter
gonna FindDevice
GetDevice_ error: org.bluez.Error.DoesNotExist: Device does not exist
No dbus device properties.
_name is null
hci_read_remote_name ret: -1.

Set Radio Mode; Success. Logging:

got Adapter
DONE SetAdapterMode.

BDI.GetServiceRecords; Success.  Logging:

got Manager
DefaultAdapter : ObjectPath
got Adapter
gonna FindDevice
GetDevice_ error: org.bluez.Error.DoesNotExist: Device does not exist
No dbus device properties.
Gonna sdp_connect (SafeHandle)...
xAdapter_PropertyChanged name: Devices, newValue: NDesk.DBus.ObjectPath[]
rfcommOnly: False
sdp_service_search_attr_req in: -1267215624, attrid_list: -1267271928
sdp_service_search_attr_req ret: 0, result: -1267467016
attr count: 8
record count: 1
xAdapter_PropertyChanged name: Devices, newValue: NDesk.DBus.ObjectPath[]

BluetoothClient fails!

---- NewBtCli ----
Swallowed Exception: System.PlatformNotSupportedException: 32feet.NET does not support the Bluetooth stack on this device. ---> System.Net.Sockets.SocketException: An address incompatible with the requested protocol was used
  at System.Net.Sockets.Socket..ctor (AddressFamily family, SocketType type, ProtocolType proto) [0x0005e] in /usr/src/packages/BUILD/mono-2.8/mcs/class/System/System.Net.Sockets/Socket_2_1.cs:212
  at InTheHand.Net.Bluetooth.Msft.SocketBluetoothClient.CreateSocket () [0x00000] in :0
  at InTheHand.Net.Bluetooth.Msft.SocketBluetoothClient..ctor (InTheHand.Net.Bluetooth.Factory.BluetoothFactory fcty) [0x00000] in :0
  --- End of inner exception stack trace ---
  at InTheHand.Net.Bluetooth.Msft.SocketBluetoothClient..ctor (InTheHand.Net.Bluetooth.Factory.BluetoothFactory fcty) [0x00000] in :0
  at InTheHand.Net.Bluetooth.BlueZ.BluezClient..ctor (InTheHand.Net.Bluetooth.BlueZ.BluezFactory fcty) [0x00000] in :0
  at InTheHand.Net.Bluetooth.BlueZ.BluezFactory.GetBluetoothClient () [0x00000] in :0
  at InTheHand.Net.Bluetooth.Factory.BluetoothFactory.DoGetBluetoothClient () [0x00000] in :0
  at InTheHand.Net.Sockets.BluetoothClient..ctor (InTheHand.Net.Bluetooth.Factory.BluetoothFactory factory) [0x00000] in :0
  at InTheHand.Net.Sockets.BluetoothClient..ctor () [0x00000] in :0
  at ConsoleMenuTesting.BluetoothTesting.Create_BluetoothClient () [0x00000] in :0
  at ConsoleMenuTesting.BluetoothTesting.NewBtCli () [0x00000] in :0
  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod*,object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x000d0] in /usr/src/packages/BUILD/mono-2.8/mcs/class/corlib/System.Reflection/MonoMethod.cs:223

xx

See http://32feet.codeplex.com/releases/view/67702 🙂

Summary

One of the things on my to-do list for our Widcomm support is that on some of the device platforms once the device has gone through a power-down-up change the stack needs to be restarted. On my Asus device in this case we find that some operations fail. Once we re-create the Widcomm objects they works again.

What fails when

On my older iPAQ with Widcomm version 1.7.1.1424 after a power-down-up, there is no problem: things works ok.

On my Asus with Widcomm version “1.8.0 build 4800”, the stack needs to be reset. If we don’t restart the stack then Device Discovery (CBtIf::StartInquiry) and Service Discovery (StartDiscovery) fail for instance (and the latter affects BtCli.Connect).

What we tried

So the obvious thing to do in this case is to close the existing Widcomm C++ objects and initialise new ones. So I implemented that: when the Stack-Down event has been seen, the next time we do an operation we dispose our instance of the CBtIf object and ‘new’ a new instance.

What works and doesn’t

On the Asus that works fine, StartInquiry etc work successfully after the dispose/re-create.

On the iPAQ that’s the case also, but only if we leave some time after the restart before using the stack again. Instead if we access the new instance too soon after the restart we get a crash. Well it looks like a crash in that the application just disappears, but it doesn’t look like a crash in that we get no crash dialog nor apparently any crash dump. Why not?? And we can inspect it with the debugger as we can’t have a debugger stay attached over the power-down-up and it takes too long for ActiveSync and/or a debugger to re-attach to be able to catch the crash.

Any suggestions about investigating this crash are welcomed…

Other thoughts

The other thought was to check the IsStackServerUp and IsDeviceReady methods provided by the Widcomm CBtIf class. We would check these and delay things until the stack was in a safe state. However these methods were added in a version after that that the problematic device has, they were added in 1.7.1.2700 but the iPAQ has 1.7.1.1424.  So they’re not available on the very platform that we need them on.

I had hoped anyway that closing the instance and creating a new one would make everything right — internally it would do a wait if necessary.  What we see of course that the new instance is returned, but then something unknown fails…

Events

One begins to consider whether we need to add some some of version check hack: if (version < 1.8.0.xxxx) then delay-new-instance-creation.  Or something like that…

Or, looking at the logs maybe we can maybe use the different events produced to fingerprint the version.

iPAQ log
At 15:50:20: StackStatusChange: Unloaded
At 15:50:27: StackStatusChange: Reloaded

Asus log
At 15:52:44: StackStatusChange: Down
At 15:53:11: StackStatusChange: Unloaded

Note the difference: iPAQ: Unloaded+Reloaded, Asus: Down+Unloaded with no Reloaded.

Out of interest: Firstly, why no Reloaded in the latter case?  Because the stack is detached on that platform??  Secondly the Widcomm docs say: “DEVST_DOWN indicates that the Bluetooth stack server has been shut down and is not expected to be restarted.”, but that’s not the case here.  Hmm, they seem a bit confused… 🙂

I think we’ll have a think about using the Down+Unloaded case to find that the platform needs reset and don’t do the reset in the other cases.  I’ll try and test this on other devices and see what I find.

Other thoughts welcome…

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.

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.

 I’ve added support for Secure Simple Pairing (SSP) for Windows 7 and Vista SP2 using the Microsoft stack.  When a Windows 7/etc PC has a Bluetooth version 2.1 dongle (radio/controller) attached and a version 2.1 device is to be atempts to authenticate then one of the new SSP authentication methods will be used.  Previously we had support only for the original Bluetooth PIN authentication method and thus BluetoothWin32Authentication would ignore SSP authentication attempts.  It aims to supports all the authentication methods, although I’ve managed to test only the NumericalComparison/JustWorks methods, and not Passkey, PasskeyNotification and OutOfBand methods.

From the BluetoothWin32Authentication class documentation:

[…] the callback includes a parameter of type BluetoothWin32AuthenticationEventArgs. Various authentication methods are available in Bluetooth version 2.1 and later. Which one is being used is indicated by the AuthenticationMethod property. If it is Legacy then the callback method should set the Pin property.

For the other authentication methods e.g. NumericComparison or OutOfBand the callback method should use one or more of the other properties and methods e.g. NumberOrPasskeyAsString, NumberOrPasskey, Confirm, ResponseNumberOrPasskey, ConfirmOob etc.

For more information see the class documentation and the user guide (http://32feet.codeplex.com/wikipage?title=BluetoothWin32Authentication)

Let me have your feedback.

No changes to BluetoothSecurity.PairRequest nor BluetoothWin32Authentication.New(BluetoothAddress,String).  Those will be considered in the future based on your feedback.  This also affects BluetoothClient.SetPin etc.



UPDATED: Renamed to NumberOrPasskey from  NumberOrPasscode etc

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

Windows 7 Advanced tab of the Bluetooth Control Panel

Admin view of Windows XP Advanced tab of the Bluetooth Control Panel No version on Windows XP's non-admin view...

No version on Windows XP's non-admin view...

Widcomm/Broadcom

Widcomm (Windows XP at least) shows the version on the Hardware tab of its Control Panel.

BlueSoleil

BlueSoleil (Windows 7 at least) shows the version on the Hardware tab of its Control Panel.

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)

We have new L2CAP support in the code repository for L2CAP, currently only for the Broadcom/Widcomm stack. This can be used for your custom application that uses L2CAP, and for some Bluetooth Profiles, for instance HDP (Health Devices) etc.

For the HID Profile most Bluetooth stacks have built-in ‘host’ support for HID and thus connect directly with the HID device and pass the data directly to Windows’ HID support.  However some devices have incomplete HID support and thus the protocol stack can’t connect to them, so this L2CAP support can be used to connect directly.  It also could be used if one wants to create a HID Device.  Depending on the stack, there might be conflicts between the built-int HID services and your implementation however.

API

The API to this is currently two new classes: L2CapClient and L2CapListener which each have a subset of the member on the exixting BluetoothClient and BluetoothListener classes — they remain for RFCOMM.  However the data stream returned by L2CapClient is subclass of System.IO.Stream rather than a subclass of NetworkStream.  This is because whereas RFCOMM presents a stream of data instead L2CAP transfers packets so should use socket type SOCK_SEQPACKET rather that SOCK_STREAM, and NetworkStream does not support SOCK_SEQPACKET.  See more on data transfer below.

At the moment both client and listener are lacking SDP support.  Client given only a Service Class Id will not lookup a port (L2CAP PSM — Protocol Service Multiplexer), and Listener will not add a SDP record.  We should be able to add support for both in the next week or two.

Unfortunately, being Widcomm, updates to the C++ mapping layer are required for this new functionality.  These have been added to the 32feetWidcomm.dll source in the repository and the respective DLL need to be recompiled.  I can provide access to a built copy based on demand.

Update: I hadn’t checked in one change for Listener so it wasn’t working until today (January 2nd).  Client SDP is working now too.

Update: Listener SDP is working now too, repository revision 82726.

Example

Listener

---- L2CapListen ---- local PSM (optional)>
BluetoothEndPoint..cctor _isBlueZ: False
L2CapIf_AssignPsmValue ret: True <- psm: 0=0x0
L2CapIf_GetPsm PSM: 22271=0x56FF
L2CapIf_Register ret :True
Server GetScn returned port: 22271 True; False,False-> NONE
Listening on 000000000000:22271
WidcommRfcommPort.Create'd: 12E5988
WidcommL2CapClient.NativeMethods.L2CapConn_OpenServer ret: SUCCESS=0x00000000
OpenServer ret: SUCCESS=0x00000000
StartOneNewListenerPort 12E5988. Started 1 new port(s).
Listening on PSM: 22271 = 0x56FF
BeginAccept Enqueued
00:39:46.5000000 HandleEvent: CONNECTED=0x00000200=CONNECTED
12E5988: CONNECTED (New) port: InTheHand.Net.Bluetooth.Widcomm.L2CapPort CONNECTED 12E5988; m_state: New; m_arConnect (set), IsCompleted: False. PortAccepted Dequeued a caller WidcommRfcommPort.Create'd: 12E59E8 WidcommL2CapClient.NativeMethods.L2CapConn_OpenServer ret: SUCCESS=0x00000000 OpenServer ret: SUCCESS=0x00000000
StartOneNewListenerPort 12E59E8. Started 1 new port(s).
Accepted! :-)
---- CLEAN EXIT ----

Client

---- L2CapConnect ----
remote address>00:1A:92:AB:47:F5
remote PSM>22261
WidcommRfcommPort.Create'd: 12E5A48
BeginFillInPortState
BeginFillInPort, has port -> Completed Syncronously
L2CapIf_AssignPsmValue ret: True <- psm: 22261=0x56F5
L2CapIf_GetPsm PSM: 22261=0x56F5
L2CapIf_Register ret :True
WidcommL2CapClient.NativeMethods.L2CapConn_OpenClient ret: SUCCESS=0x00000000
OpenClient ret: SUCCESS=0x00000000
Connect called
---- CLEAN EXIT ----

Data access

As a SOCK_SEQPACKET the packet boundaries from the L2CAP protocol should be maintained when reading from the socket/stream, we do that currently, so one Read will not return data from more than one packet, it will return when the end of a packet is reached (or it has filled the caller buffer).  However the semantics of SEQPACKET with simple recv are also that if a portion of a packet is read then the rest of the data from that packet should be discarded.  We do not do that currently, remaining parts of a packet will be returned in the subsequent reads.  We will look at changing that sometime.



We’ve implemented support to use BlueZ’s D-Bus ‘newly discovered device’ signal for our ‘live’ discovery feature. Use BluetoothComponent.DiscoverDevicesAsync as always.   It appears that a signal is only raised if the device wasn’t seen the last time discovery was run — I haven’t found whether this is per application or is controllable through their “session” features.  Maybe we need to store the old set each time, adding when we see the DeviceFound signal and removing from it when we see the DeviceDisappeared signal.

Radio.set_Mode is also now supported.  Note that once a radio is ‘PoweredOff’ I can’t find a way through the BlueZ control panels to re-enable it, we don’t load it either so I had to use a custome application to re-enable it.

Finally we’ve also had some feedback from the Mono team that they don’t want to support Bluetooth sockets specifically and have to pull in their header file, so we suggested having their socket layer stop blocking unknown address families and sockaddr types but instead pass them through. We submitted a new patch to them for this[1] and have updated out BluetoothEndPoint class to match[2].

[1] https://bugzilla.novell.com/show_bug.cgi?id=655153#c6

[2] http://32feet.codeplex.com/SourceControl/changeset/changes/82268

(Further to: https://32feetnetdev.wordpress.com/2010/12/05/further-support-for-bluez/ and https://32feetnetdev.wordpress.com/2010/11/24/bluez-support/)