RFCOMM Scenario: Receive File as a Server (HTML)

Another common RFCOMM App scenario is to host a service on the PC and expose it for other devices. In this scenario, the App developer first creates a RfcommServiceProvider to advertise the desired service. The developer then sets the SDP attributes as needed (using established data helpers to generate the attribute’s Data) and starts advertising the SDP records for other devices to retrieve. To connect to a client device, the App developer creates a socket listener to start listening for incoming connection requests. When a connection is received, the developer can store the connected socket for later processing. When it’s time to receive the file, the App developer can follow established data stream patterns to read chunks of data from the socket’s InputStream and save it to a file.

var _provider;   // Windows.Devices.Bluetooth.RfcommServiceProvider

function Initialize()
{
    // Initialize the provider for the hosted RFCOMM service
    Windows.Devices.Bluetooth.RfcommServiceProvider.createAsync(
        RfcommServiceId.obexObjectPush)
    .done(function(provider) {
        _provider = provider;

        // Create a listener for this service and start listening
        var listener = new StreamSocketListener();
        listener.addEventListener(
            “connectionreceived”, OnConnectionReceived);
        return listener.bindServiceNameAsync(
            _provider.serviceId.asString(),
            SocketProtectionLevel
                .bluetoothEncryptionAllowNullAuthentication);
    }).done(function() {
        // Set the SDP attributes and start advertising
        InitializeServiceSdpAttributes(_provider);
        _provider.startAdvertising();
    )};
}

var SERVICE_VERSION_ATTRIBUTE_ID = 0x0300;
var SERVICE_VERSION_ATTRIBUTE_TYPE = 0x0A;   // UINT32
var SERVICE_VERSION = 200;
function InitializeServiceSdpAttributes(RfcommServiceProvider provider)
{
    var writer = new Windows.Storage.Streams.DataWriter();

    // First write the attribute type
    writer.writeByte(SERVICE_VERSION_ATTRIBUTE_TYPE)
    // Then write the data
    writer.writeUint32(SERVICE_VERSION);
    
    var data = writer.detachBuffer();
    provider.sdpRawAttributes.add(SERVICE_VERSION_ATTRIBUTE_ID, data);
}

void OnConnectionReceived(listener, args)
{
    // Stop advertising/listening so that we’re only serving one client
    _provider.stopAdvertising();
    listener.close()
    .done(function() {
        _socket = args.socket;

        // The client socket is connected. At this point the App can wait for
        // the user to take some action, e.g. click a button to receive a
        // file from the device, which could invoke the Picker and then save
        // the received file to the picked location. The transfer itself
        // would use the Sockets API and not the Rfcomm API, and so is
        // omitted here for brevity.
    });
}