I ran into this alongside the findAllAsync trouble I was having in the previous post. To be more specific, I've been converting a small sample that's in the ZIP file for //build 2013 session 3-026 (http://channel9.msdn.com/Events/Build/2013/3-026, the ZIP is http://files.channel9.msdn.com/thumbnail/f9025b07-120c-4320-8de6-a5de2d255b7c.zip) . This is a C# sample to talk to a Sphero device using the Windows 8.1 Bluetooth.Rfcomm API.

The problem I was having was that write.storeAsync (write is a Windows.Storage.Streams.DataWriter object) was throwing an exception, hence my try/catch block:

function changeColor() {
    output.innerText = "";

    if (writer == null) {
        return;
    }

    var packet = generateRandomColorPacket();
    writer.writeBytes(packet);

    try { 
        writer.storeAsync().done(function () {
        }, function (e) {
            output.innerText = "Failed to write packet; " + e;
        });
    } catch (e) {
        output.innerText = "DataWriter.storeAsync failed (exception); " + e;
    }
}

The exception message wasn't at all helpful: it just said: "The operation identifier is not valid." Huh?

With the help of some colleagues in the Bluetooth team who looked this over, we found a small glitch in the code below that opens the socket to the device. Do you see the error?

function openSocket() {
    output.innerText = "";

    if (device == null) {
        return;
    }

    // Create a socket and connect to the target
    var sockNS = Windows.Networking.Sockets;
    socket = new sockNS.StreamSocket();
    socket.connectAsync(device.connectionHostName, device.connectionServiceName,
        sockNS.SocketProtectionLevel.bluetoothEncryptionAllowNullAuthentication)
        .done(function () {
            writer = new Windows.Storage.Streams.DataWriter(socket.OutputStream);
        }, function (e) {
            output.innerText = "Failed to open socket; " + e;
        });
}

Don't feel bad if you missed it, because I did. It's this line here, which I'd brought over from the C# code. Now do you see the problem?

writer = new Windows.Storage.Streams.DataWriter(socket.OutputStream);

It's hard to see: socket.OutputStream should be socket.outputStream! In other words, I was creating a DataWriter with undefined rather than the real stream. DataWriter didn't complain, though, until it tried to access the backing stream via storeAsync.

Changing that one character solved the problem.


While working on the Devices and Printing chapter of the second edition of Programming Windows Store Apps with HTML, CSS, and JavaScript, I’ve been bitten several times by a subtly confusing feature of the device enumeration API and it’s projection into JavaScript.

Device enumeration happens in a few different ways, but a common method is to ask a device object like HidDevice or Bluetooth.RfcommDeviceService (both under the Windows.Devices namespace) for a “selector” string through a static method called getDeviceSelector. You then pass this to the Windows.Devices.Enumeration.DeviceInformation.findAllAsync.

The gotcha is that findAllAsync has two overloads that take one argument: one that takes a selector string, and one that takes a DeviceClass object. Only one of these, however, is projected into JavaScript and it’s the DeviceClass variant. Unfortunately, if you happen to pass a selector string to this method, you’ll get no complaint anywhere along the way: the API will accept the string, see that it’s an invalid DeviceClass, and then ignore it.

As a result, this variant of findAllAsync just assumes then that you didn’t need the argument and does the equivalent of findAllAsync() with no arguments, which enumerates every device on your system (all 300+ of them, typically!). This is, like I said, very confusing if you were only expecting to see a single result.

When using a selector to enumerate devices in JavaScript, then, be sure to call the findAllAsync(<selector>, <properties>) variant, passing null for <properties>. This ensures that you use the findAllAsync that expects a selector string, and thus you’ll get the results you’re looking for.

 

 


One of the most significant additions to the WinRT API in Windows 8.1 Preview is found in the Windows.Devices namespace, showing that Windows 8.1 is opening the floodgates for apps that can make sure of a wide range of peripheral hardware.

The self-explanatory API areas are listed below, along with links to //build 2013 sessions that talked about them. Note that a number of the sessions were pre-recorded–we did this because there were more specific topics than we could accommodate in the live venue.

Personally, I’m looking forward to working on devices chapter in the second edition of my book (first preview here), as it will give me an excuse to buy some fun toys to play with like a Sphero and LEGO Mindstorm! My nearly 7-year-old son will enjoy that too.