Widcomm on 32feet.NET tests

Alan McFarlane
January 2010

Widcomm no Radio present

bug 23222.   On Win32 (XP) test of Widcomm radio dongle unplugged.

  1. With Radio dongle attached, all should work: PrimaryRadio/AllRadios should include the Widcomm radio (if no MSFT present, or multi-radio enabled).
  2. Unplug the radio.  Now PrimaryRadio should return null, etc.

The failing behaviour is for a empty radio instance to be returned, like:

        option>10
        BtIf_Create
        BtIf_GetLocalDeviceVersionInfo
                [Assertion Failed: GetLocalDeviceVersionInfo failed]
        BtIf_GetLocalDeviceName
                [Assertion Failed: GetLocalDeviceName failed]
        BtIf_GetLocalDeviceInfoBdAddr
                [Assertion Failed: GetLocalDeviceInfoBdAddr failed]
        BtIf_IsDeviceConnectableDiscoverable
        Radio, address: 00:00:00:00:00:00
        Mode: Discoverable
        Name: , LmpSubversion: 0
        ClassOfDevice: 0, device: Miscellaneous / service: None
        Software: Broadcom,  Hardware: Ericsson, status: Running
        Remote: ''

WidcommDeviceInfo GetServiceRecords

Device-/ConsoleMenuTesting menu option “ServiceDiscovery” etc.   Against any device, at least one record should be listed, the SDP server record itself.  The device may have other records.

Note that we cannot dump the whole record as Widcomm does not provide access to the raw record bytes. Check the documentation for the Attributes we lookup (currently only the Service Class, and Name, and RFCOMM Channel Number).

Also need to do a specific class query to check we filter correctly.  Widcomm returns *all* the records read in the current session, so we have to filter the matching ones in GetServiceRecords.

  1. Do a query for a specific class id e.g. OPP.
  2. Then query for all (L2CAP).
  3. Then do a query for the first class again. You should see only the record(s) listed originally, and not those listed in the ‘all’ step.
    (Originally we behaved as: see correct result for the original query, but all records are listed after the ‘all’ query).

Widcomm BluetoothListener

See the general BluetoothListener test also.

Widcomm BluetoothListener Authenticate and Encrypt properties

Connecting from a device that isn't trusted by the Widcomm-stack machine the DUT.

In each case, on the DUT, start BluetoothListener apply the respective settings and then connect from the peer machine. Check that the peer machine succeeds/fails to connect as expected.

Recommend specifying the Service Class UUID each time, and with a different value each time, e.g. 0x00010001, then 0x00010002, etc. May also be wise to manually specify the port at well, using 11, 12, etc in correspondence with the UUID.

1. Yes Auth, No Encrypt
Expect to see Widcomm authentication prompt pop-up on the DUT. Ignore it, or open and hit Cancel button. (Then will see authentication failed pop-up). Expect no incoming connection on DUT. Expect fail. (MSFT: EHOSTDOWN) Cancel listener (or exit test app if necessary) on DUT.
2. No Auth, No Encrypt
Expect success.
3. Yes Auth, No Encrypt
Expect fail as #1.
4. No Auth, Yes Encrypt
Expect fail as #1. Note this does not check that the data is being sent encrypted. Presumably only sniffing the traffic would ensure that?
5. Yes Auth, No Encrypt
Expect fail as #1.
6. No Auth, No Encrypt
Just to verify that the two devices can still connect, i.e. no hardware fault or etc has occurred. Expect success as #2.

WidcommDeviceInfo get_Remembered versus get_Authenticated

We want to check that we see devices of the two types: {Remembered=true, Authenticated=false} and {Remembered=true, Authenticated=true}. This requires that we have at least one device in Widcomm's “Trusted Devices” set.

Run discovery with at least remembered=authentication=true, discoverableOnly must be false, unknown is better set to false also.

In Widcomm a device is ‘remembered’ whenever the stack sees it — unlike MSFT where manual request is required. One may need to force a device to be trusted — either by calling BluetoothSecurity.PairRequest, or by making a connection with it to a service requiring authentication.

A nice test to is to have a trusted device and then make it untrusted (either BluetoothSecurity.RemoveDevice, or use the Widcomm UI e.g. on WM do {Wireless XX -> Manage -> Advanced menu -> Trusted Devices -> Remove} and on two discovery process see it R+A and then R-A.

BluetoothSecurity (PairRequest, RemoveDevice)

In a similar area to the above, here testing whether we can add and remove devices from the trusted list. Choose a peer device that is in range and you can bond with. Run discovery(auth+rmbd) and/or use the Widcomm UI to view trusted device and see the device removed from the trusted list with RemoveDevice and added with PairRequest.

Widcomm UI

Paired Device dialog box on iPAQ Windows MobileIn iPAQ: StartMenu → iPAQWireless → Manager → Menu → PairedDevices

WidcommBluetoothClient

In BluetoothClient we have to do a manual SDP lookup (unless the port is set in the specified BluetoothEndPoint), thus there's some complexity around that.  There's the test below 'BluetoothClient' which does SvcA->SvcB->SvcA.  The SDP Lookup takes 12 seconds to time-out when the target device is not found.

Connect works

Connect to a remote service, e.g. OBEX or SerialPort on most device types, or 1113 to another instance on ConsoleMenuTesting.

If the port (RFCOMM SCN) is specified in the endpoint then the process is less complex (no SDP lookup) though not worth testing that in most cases.

Connect (SDP) take a while to time-out

Start a Connect to a non-existent device, it will take a while (12secs) for the SDP lookup to fail.  See that that delay (only) occurs.

We would like to report a useful Winsock Error code but Widcomm doesn't tell us if the failure was not-present, security, or something else.  So ignore the exception error code.

Restricted to one Connect (SDP) at a time

Use ConsoleMenuTesting option: "ConnectMultiple".

Connect can be cancelled

Start a Connect to a non-existent device, it will take a while (12secs) for the SDP lookup to fail.  In that time call BluetoothClient.Close and the sync/async Connect will fail with a ObjDispEx (we only test the async case from the same thread here).  Later the SDP lookup will complete, and it will NOT crash!

Cancelled Connect doesn't allow the next immediately

Here we can see that we aren't able to do another connect immediately when we cancel a previous connect.  We have to wait for the SDP to complete first.  The current script in ConsoleMenuTesting is as following.  It runs two Connect, the first as async=Y, cancel=Y; and we expect to see the second fail with "one at a time" InvOpEx.

13
002233445566






y
y
y
13
0022446688aa






y

Connections close at switch Radio Off

bug 28623.   [widcomm] Use OnStackStatusChange to close connections when radio turned off

On PDAs when the radio is turned off when there is an current RFCOMM connection, no connection loss event is received, so the program there thinks the connection is still open, and will hang on a Read for instance (the remote end sees the connection close due to 20s timeout).  So we need to listen for the radio-off event and manually close any connections then.  Note that on my iPAQ hx2710 with Widcomm 1.7.1.1424 when the radio is switched off a CONN_ERR event is recevied, this is not the case on my Asus device nor a newer iPAQ I've tested on.

This functionality is not implemented on the desktop PC platform, we saw wierd/bad things happening when implemented.  The radio-off situation is less likely to happen then, e.g. less need for saving power, so its not important to implement it there, we'll look at it again based on demand.  (The wierd/bad thing was that after the native code called up into the managed code to report the OnStackStatusChange event things went all wrong).

We need to test the connection(s) are closed.  We should also test that the infrastructure is working correctly, that the list of open connections is maintained correctly, being added to at both client and server connect, and the connection is removed from the list when it closes.

Test using DeviceMenuTesting

1. Make a client connection to a remote machine and close the connection.  Run a server on the PDA and connect to it from a remote machine, and close the connection.

2. Run a server on the PDA and connect to it from a remote machine, and start a Read on the connection.

3. In Wireless Manager or similar turn off the radio.

4. Re-enable the radio, restart DeviceMenuTesting (if required – or use HackShutdown), make a client connection to a remote machine.  Turn off the radio, and start a Read on the connection.


General test

BluetoothClient

This checks a possible failure case on Widcomm pre 2.4.

Connect three times: to SvcA, SvcB, then SvcA again. For instance on another machine run two copies of ConsoleMenuTesting and use the ListenMultiple option with a different UUID in each instance.

Ensure that third connect does not connect to SvcB, but correctly to SvcA.

GetServiceRecords

This checks a possible failure case on Widcomm pre 2.4.

Query for OPP, then for all, the for OPP again.

Ensure that the third query doesn't return 'all', but the same result as the first query.

BluetoothListener (SDP and accepts)

  1. View test machine's SDP database, start BluetoothListener, view SDP contents again and check correct record has been added -- has Service Class List with selected Class Id, and has a valid RFCOMM ProtocolDescriptorList.
  2. Make a connection to the server, and transfer some data.
  3. Stop the listener (lsnr.Stop()) and check that the record has gone.
  4. Start a BluetoothListener setting also the ServiceName property, check that the added SDP record includes the given name, and the record has a correct corresponding LanguageBaseIdList.
  5. Close the app by TaskManager / taskkill.exe, and check that the record has gone.
  6. Start a BluetoothListener giving a custom SDP record (as a ServiceRecord instance), check that the record is added -- and no default record is added too.

SetPin on BluetoothClient / BluetoothListener

Stack support

Microsoft stack on Windows CE / Windows Mobile
A socket option is available which sets the PIN to use for all purposes on that socket. A device address can optionally be provided to specify that the pin is only for that device.
Microsoft stack on desktop Windows
No socket option is available. The only feature is an event raised for all requests for a PIN. In the library this is provided by class BluetoothWin32Authentication. It can be used in two forms, firstly in an automatic mode where the caller specifies a device address and the pin and it should use to authenticate to that address. In the second mode the caller supplies a callback method which can respond to the PIN requests.
Broadcom/Widcomm stack on both platforms
No ‘socket’ option is available. No event for PIN requests is provided either. The only PIN related method is CBtIf::Bond which actively bonds using the given PIN.

Functional spec

Default method should be for the user to call SetPin(String pin) before connect, which specifies that that pin is to be used this connection, or at least that the PIN should be used for the device that this instance is connecting to.  There will also be a SetPin(BluetoothAddress device,String pin) method, but I'm not sure of its use.

The use of these after a connection is made is not obvious to me.  By then the PIN is not required since the connection has been successful without one!

Implementation

Tests

1. With BluetoothClient, Connect to a service on an unbonded device, where the service or device requires authentication.
Expect failure
2. Do again, this time first calling SetPin(pin) on the BluetoothClient.
Expect success: the PIN is used automatically, the devices bond, and the connection succeeds.
3. Do again, this time first calling SetPin(address,pin) on the BluetoothClient.
First delete the bonding on the peer device and re-test #1.
Expect success: the PIN is used automatically, the devices bond, and the connection succeeds.
4. Do again, this time first calling SetPin(wrongAddress,pin) on the BluetoothClient.
First delete the bonding on the peer device and re-test #1.
Expect failure.

Bluetooth stack loading error reporting and options

Can be configured whether to attempt to initialise more that one stack (i.e. MSFT and Widcomm together), also need to configure where we report errors in all case.  For instance if configured to load more that one stack but the first stack fails to init, should the error be reported.  Answer: probably not, one stack may be enough for the use case.

So the following configurations exist and the number of errors that should be reported are listed.  The cells with underscores have been tested.

OneStack=Y, RAE=N
Widcomm
Y N
MSFT Y 0 0_
N 0_ 2_
OneStack=Y, RAE=Y
Widcomm
Y N
MSFT Y 0 0
N 1_ 2_
OneStack=N, RAE=N
Widcomm
Y N
MSFT Y 0 0_
N 0 2
OneStack=N, RAE=Y
Widcomm
Y N
MSFT Y 0 1_
N 1 2_

Check also when on a suitable machine that one stack is loaded when “OneStack” is true, and two are loaded when it is false.