Windows 8.1 store app unable to connect to a Python pybluez Bluetooth Service

3

I am attempting to create a proof of concept app that will connect a Windows 8.1 Pro tablet to an embedded Linux device over Bluetooth but I am having trouble getting it to work. The Bluetooth service on the Linux device is written with Python using the pybluez library. The Windows 8.1 app is written using C# and the windows Bluetooth stack as described in this example.
I was wondering if anyone has had any experience in connecting a Linux device with a Windows 8.1 pro store app and could point me in the right direction. This is what I have so far:
Windows 8.1 C# Bluetooth code:

private async void runButton_Click(object sender, RoutedEventArgs e)
    {

        // Find all paired instances of the Rfcomm chat service
        serviceInfoCollection = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.FromUuid(rfcommServiceUuid)));

        if (serviceInfoCollection.Count > 0)
        {

            List<string> items = new List<string>();
            var serviceInfo = serviceInfoCollection.First();
            foreach (var chatServiceInfo in serviceInfoCollection)
            {
                items.Add(chatServiceInfo.Name);
             //   if (chatServiceInfo.Name.StartsWith("system"))
                   NotifyStatus(chatServiceInfo.Name + ":  " + chatServiceInfo.Id + "\n");
            } 

            NotifyStatus("---Found " + serviceInfo.Name + ":  " + serviceInfo.Id + "\n");
            try
            {
                service = await Windows.Devices.Bluetooth.Rfcomm.RfcommDeviceService.FromIdAsync(serviceInfo.Id);
            }
            catch (Exception ex)
            {
                NotifyStatus("Here1");
                NotifyError(ex);
                return;
            }

            if (service == null)
            {
                NotifyStatus("Error:  Access denied, application did not give permission");
                return;
            }
            var attributes = await service.GetSdpRawAttributesAsync();
            if (!attributes.ContainsKey(sdpServiceNameAttributeId))
            {
                NotifyStatus("Error:  Service is not advertising the Service Name attribute");
                return;
            }
            var attributeReader = DataReader.FromBuffer(attributes[sdpServiceNameAttributeId]);
            var attributeType = attributeReader.ReadByte();
            if (attributeType != sdpServiceNameAttributeType)
            {
                NotifyStatus("Error:  Service is using an unexpected format for the Service Name Attribute");
                return;
            }
            var serviceNameLength = attributeReader.ReadByte();
            attributeReader.UnicodeEncoding = UnicodeEncoding.Utf8;
            var serviceName = attributeReader.ReadString(serviceNameLength);
            NotifyStatus("Service Name:  " + serviceName + "\n");

                try
                {
                /*    lock (this)
                    {
                        socket = new StreamSocket();
                    } */
                    StreamSocket mySocket = new StreamSocket();
                    NotifyStatus("3 " + service.ConnectionHostName + " - " + service.ConnectionServiceName +  " - " +service.ProtectionLevel+"\n");
                    await  mySocket.ConnectAsync(service.ConnectionHostName, service.ConnectionServiceName);
                    NotifyStatus("4");
                    writer = new DataWriter(mySocket.OutputStream);
                    reader = new DataReader(mySocket.InputStream);

                }
                catch (Exception ex)
                {
                    NotifyError(ex);
                    return;
                }

            try
            {
                String sendingStr = "Hello from Windows 8.....";
                writer.WriteUInt32((uint)sendingStr.Length);
                writer.WriteString(sendingStr);
                await writer.StoreAsync();

                ReceiveDataLoop(reader);
                NotifyStatus("Going to sleep");
                await Task.Delay(TimeSpan.FromSeconds(5));
                NotifyStatus("Sending data");
                writer.WriteByte(0x41);
                writer.WriteByte(0x4b);
                NotifyStatus("Done");
            }
            catch(Exception ex)
            {
                NotifyError(ex); 
            }
        }
        else
        {
            NotifyStatus("No services found");
        }

        NotifyStatus("This is the end of the list");
    }

Here is the capabilities code for my Windows manifest file

<Capabilities>
    <Capability Name="internetClientServer" />
    <Capability Name="privateNetworkClientServer" />
    <m2:DeviceCapability Name="bluetooth.rfcomm">
      <m2:Device Id="any">
        <m2:Function Type="serviceId:34B1CF4D-1069-4AD6-89B6-E161D79BE4D8" /> 
      </m2:Device>
    </m2:DeviceCapability>
  </Capabilities>

And finally the code for my Python Service:

from bluetooth import *

server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(2)

port = server_sock.getsockname()[1]

uuid = "34B1CF4D-1069-4AD6-89B6-E161D79BE4D8"

advertise_service( server_sock, "SampleServer",
                   service_id = uuid,
                   service_classes = [ uuid, SERIAL_PORT_CLASS ],
                   profiles = [ SERIAL_PORT_PROFILE ]
                    )

print("Waiting for connection on RFCOMM channel %d" % port)

client_sock, client_info = server_sock.accept()
print("Accepted connection from ", client_info)

try:
    while True:
        data = client_sock.recv(1024)
        if len(data) == 0: break
        print("received [%s]" % data)
except IOError:
    pass

print("disconnected")

client_sock.close()
server_sock.close()
print("all done")

When I run all these together, the windows client successfully finds the service but when it tries to open the socket it throws the following error:

System.Exception:  Element not found. (Exceptiion from HRESULT: 0x80070490
  At System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
  At System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  At System.Runtime.CompilerServices.TaskAwaiter.GetResult()
  At TestBluetoothRFCOMMClient.MainPage.<runButton_click>d__0.MoveNext()

I did install python and pybluez on the tablet as well and was able to successfully connect to the Python service using the following python client:

from bluetooth import *
import sys

if sys.version < '3':
    input = raw_input

addr = None

if len(sys.argv) < 2:
    print("no device specified.  Searching all nearby bluetooth devices for")
    print("the SampleServer service")
else:
    addr = sys.argv[1]
    print("Searching for SampleServer on %s" % addr)

# search for the SampleServer service
uuid = "34B1CF4D-1069-4AD6-89B6-E161D79BE4D8"
service_matches = find_service( uuid = uuid, address = addr )

if len(service_matches) == 0:
    print("couldn't find the SampleServer service =(")
    sys.exit(0)

first_match = service_matches[0]
port = first_match["port"]
name = first_match["name"]
host = first_match["host"]

print("connecting to \"%s\" on %s" % (name, host))

# Create the client socket
sock=BluetoothSocket( RFCOMM )
sock.connect((host, port))

print("connected.  type stuff")
while True:
    data = input()
    if len(data) == 0: break
    sock.send(data)

sock.close()

However I am unable to get the Windows 8.1 store app written in C# to connect. Any help or advice would be greatly appreciated. Thanks

EDIT: The code below fixes the errors that I found in the code that Nate link too if anyone needs it or if I made a mistake in the code, please let me know:

// This App requires a connection that is encrypted but does not care about
// whether its authenticated.
bool SupportsProtection(RfcommDeviceService service)
{
    switch (service.ProtectionLevel)
    {
    case SocketProtectionLevel.PlainSocket:
        if ((service.MaxProtectionLevel == SocketProtectionLevel.BluetoothEncryptionWithAuthentication)
            || (service.MaxProtectionLevel == SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication))
        {
            // The connection can be upgraded when opening the socket so the
            // App may offer UI here to notify the user that Windows may
            // prompt for a PIN exchange.
            return true;
        }
        else
        {
            // The connection cannot be upgraded so an App may offer UI here
            // to explain why a connection won’t be made.
            return false;
        }
    case SocketProtectionLevel.BluetoothEncryptionWithAuthentication:
        return true;
    case SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication:
        return true;
    }
    return false;
}


async Task<bool> IsCompatibleVersion(RfcommDeviceService service)
{
    var attributes = await service.GetSdpRawAttributesAsync(
        BluetoothCacheMode.Uncached);
    var attribute = attributes[sdpServiceNameAttributeId];
    var reader = DataReader.FromBuffer(attribute);

    // The first byte contains the attribute's type
    byte attributeType = reader.ReadByte();
    if (attributeType == sdpServiceNameAttributeType)
    {
        // The remainder is the data
        uint version = reader.ReadUInt32();
        return version >=200;
    }
    return false;
}
c#
python
bluetooth
windows-store-apps
asked on Stack Overflow May 13, 2014 by Jon H • edited May 14, 2014 by Jon H

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0