Search code examples
c#bluetoothwin-universal-appspp

Universal Application + Bluetooth + SPP


I am currently trying to build a library for using the Serial Port Profile (SPP) on an Universal App.

As far as I have discovered, SPP runs on top of RFCOMM. The basics for RFCOMM are outlined in the MSDN which is fine. I was also able to "find" my device and "connect" to it. I was also able to create a StreamReader and StreamWriter for the RFCOMM.

Now the troubles arise. I understand that RFCOMM provides some kind of channels for various features/tasks, one of them being probably SPP (I know the device features SPP and it even works when done via a "normal" serial connection).

I would like to know if there was an example which bytes I have to send through that channel to get a single byte output on the other side. Is there some kind of connection setup required (bi-directional exchange)? Are there examples for these data packets, what are their names and is there a specific specification for it. I think I would be happy even with some of the correct terms to search for.


Solution

  • Alright, what I assumed was basically wrong. Here is the minimalistic code for a very simple (no error handling, no tasks, ...) communication.

    This goes into the Package.appxmanifest:

    <Capabilities>
      <m2:DeviceCapability Name="bluetooth.rfcomm">
        <m2:Device Id="any">
          <m2:Function Type="name:serialPort" />
        </m2:Device>
      </m2:DeviceCapability>
    </Capabilities>
    

    And this to a method of your choice (make sure your Bluetooth device has been paired, my device has the name "HC-06").

    // Find the device
    var bluetoothDevicesSpp = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));
    var bluetoothDeviceHc06 = bluetoothDevicesSpp.SingleOrDefault(d => d.Name == "HC-06");
    var serviceRfcomm = await RfcommDeviceService.FromIdAsync(bluetoothDeviceHc06.Id);
    StreamSocket socket = new StreamSocket();
    await socket.ConnectAsync(serviceRfcomm.ConnectionHostName, serviceRfcomm.ConnectionServiceName, SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication);
    DataWriter writer = new DataWriter(socket.OutputStream);
    DataReader reader = new DataReader(socket.InputStream);
    

    To read, use this:

    await reader.LoadAsync(1);
    byte b = reader.ReadByte();
    Debug.WriteLine((char)b);
    

    To write, use this:

    writer.WriteString("MaM\r\n");
    writer.StoreAsync();
    

    The bytes will be transferred as they are, no additional protocol or similar is necessary. Enjoy.