33

If you want to know how to use 32feet.NET library to communicate with bluetooth devices, read the solution


I am currently trying to communicate via bluetooth between a computer and a self-built .NET Gadgeteer prototype.

The Gadgeteer prototype consists of the mainboard, a power supply and a bluetooth module. The module is in discoverable mode.

On the computer a custom bluetooth program based on 32feet .NET Bluetooth is running. The program detects all bluetooth devices in range and tries to pair with them. However, this is not done automatically at the moment, I have to enter a pairing code for the device.

How can I pair devices without entering the pairing code?

Devices are found, the problem is the pairing part. I experimented a lot, but didn't find a solution...

foreach (BluetoothDeviceInfo device in this.deviceList)
{
    try
    {
        //BluetoothClient client = new BluetoothClient(this.CreateNewEndpoint(localAddress));
        //BluetoothEndPoint ep = this.CreateNewEndpoint(device.DeviceAddress);

        EventHandler<BluetoothWin32AuthenticationEventArgs> handler = new EventHandler<BluetoothWin32AuthenticationEventArgs>(HandleRequests);
        BluetoothWin32Authentication auth = new BluetoothWin32Authentication(handler);

        BluetoothSecurity.PairRequest(device.DeviceAddress, null);
    }
}

This code block initiates the pairing and it works, but Windows is asking me to enter the pairing code for the device. I read about the BluetoothWin32Authentication to prevent this case but I don't get it right.

private void HandleRequests(object that, BluetoothWin32AuthenticationEventArgs e)
{
    e.Confirm = true;
}

This is the code of the event handler (http://32feet.codeplex.com/wikipage?title=BluetoothWin32Authentication)

If you simply want to allow the pairing to go ahead when to SSP devices are connecting then handling the callback and setting e.Confirm=True will be enough -- but that is a little insecure...


I am confused -.- The goal is that the application and the gadgeteer module can send data in both directions without any user interference.

Is it true that I can't pair devices automatically without user interaction?

Is it true that if two device were already paired they can exchange data without user interaction?

xmashallax
  • 1,673
  • 1
  • 17
  • 34
  • 1
    In windows 10, this does not work. The OS prompts me to "Tap to setup the device" - I never get the callback to the "HandleRequests" event handler using the code above. Any idea on how to bypass this prompt? – TheJeff Aug 28 '15 at 22:38
  • Yes, as TheJeff said, pairing does not work in Windows 10, the device gets paired but it is not visible in 'playback devices', any way to fix it? – sebastso Dec 17 '15 at 09:28
  • System requirements don't list Windows 10, only Windows 8. Maybe it's not possible at the moment. – xmashallax Dec 17 '15 at 13:47
  • I also get the "Tap to set up the device" toast notification on Windows 8.1. I'm wondering if it is related to "Alert me when a new Bluetooth device wants to connect" option in Bluetooth Settings. – Aron Curzon Jan 11 '16 at 21:57
  • were you able to resolve this? I'm also getting same TAP to setup toast notification, once I tap, it is paired properly. – sebastso Feb 12 '16 at 10:52

1 Answers1

53

I figured out how to solve my problems and my knowledge about Bluetooth connections is a bit bigger now. If someone else has problems with that, I provide my solution. The code examples represent the C# implementation of a bluetooth controller with the 32feet Bluetooth library.

Scanning

This means that devices in range are detected. My code:

// mac is mac address of local bluetooth device
BluetoothEndPoint localEndpoint = new BluetoothEndPoint(mac, BluetoothService.SerialPort);
// client is used to manage connections
BluetoothClient localClient = new BluetoothClient(localEndpoint);
// component is used to manage device discovery
BluetoothComponent localComponent = new BluetoothComponent(localClient);
// async methods, can be done synchronously too
localComponent.DiscoverDevicesAsync(255, true, true, true, true, null);
localComponent.DiscoverDevicesProgress += new EventHandler<DiscoverDevicesEventArgs>(component_DiscoverDevicesProgress);
localComponent.DiscoverDevicesComplete += new EventHandler<DiscoverDevicesEventArgs>(component_DiscoverDevicesComplete);

private void component_DiscoverDevicesProgress(object sender, DiscoverDevicesEventArgs e)
{
    // log and save all found devices
    for (int i = 0; i < e.Devices.Length; i++)
    {           
        if (e.Devices[i].Remembered)
        {
            Print(e.Devices[i].DeviceName + " (" + e.Devices[i].DeviceAddress + "): Device is known");
        }
        else
        {
            Print(e.Devices[i].DeviceName + " (" + e.Devices[i].DeviceAddress + "): Device is unknown");
        }
        this.deviceList.Add(e.Devices[i]);         
    }
}

private void component_DiscoverDevicesComplete(object sender, DiscoverDevicesEventArgs e)
{
    // log some stuff
}

Pairing

This means that devices get coupled with the local bluetooth device. This needs to be done once by entering a code of both sides. Can be done via code so that the user doesn't even notice that a device was added. My code for this purpose:

// get a list of all paired devices
BluetoothDeviceInfo[] paired = localClient.DiscoverDevices(255, false, true, false, false);
// check every discovered device if it is already paired 
foreach (BluetoothDeviceInfo device in this.deviceList)
{
    bool isPaired = false;
    for (int i = 0; i < paired.Length; i++)
    {
        if (device.Equals(paired[i]))
        {
            isPaired = true;
            break;
        }
    }

    // if the device is not paired, pair it!
    if (!isPaired)
    {
        // replace DEVICE_PIN here, synchronous method, but fast
        isPaired = BluetoothSecurity.PairRequest(device.DeviceAddress, DEVICE_PIN);
        if (isPaired)
        {
            // now it is paired
        }
        else
        {
            // pairing failed
        }
    }
}

Connecting

This means establishing a connection and exchanging of data. Again some code:

// check if device is paired
if (device.Authenticated)
{
    // set pin of device to connect with
    localClient.SetPin(DEVICE_PIN);
    // async connection method
    localClient.BeginConnect(device.DeviceAddress, BluetoothService.SerialPort, new AsyncCallback(Connect), device);
}

// callback
private void Connect(IAsyncResult result)
{
    if (result.IsCompleted)
    {
        // client is connected now :)
    }
}

If you keep the order scan, pair, connect, everything should work fine. To send or receive data, use the GetStream() method of the BluetoothClient. It provides a network stream that can be manipulated.

Receiving a connection

If you want another device to connect with your device you need to listen to incoming connection requests. This only works if the device have already been paired before. My code:

BluetoothListener l = new BluetoothListener(LOCAL_MAC, BluetoothService.SerialPort);
l.Start(10);
l.BeginAcceptBluetoothClient(new AsyncCallback(AcceptConnection), l);

void AcceptConnection(IAsyncResult result){
    if (result.IsCompleted){
        BluetoothClient remoteDevice = ((BluetoothListener)result.AsyncState).EndAcceptBluetoothClient(result);    
    }    
}

Replace LOCAL_MAC with a valid BluetoothAddress (e.g. by using BluetoothAddress.Parse();). After the devices are connected they can exchange messages via the underlying stream. If the connection does not work there might be authentication issues, so try setting the local device pin in the listener (l.SetPin(LOCAL_MAC, MY_PASSWORD);

xmashallax
  • 1,673
  • 1
  • 17
  • 34
  • Do you need your own code to run on the remote device as well? – Uri Abramson Apr 25 '14 at 10:04
  • 2
    @xmarshallax Socket is not connecting by BeginConnect method.Socket.connected status is false thats why Getstream() method will not work to send or receive data. – Harsh Jun 24 '14 at 10:58
  • Is that a question or a statement? The code above works for me – xmashallax Oct 13 '14 at 18:22
  • @xmashallax I need help . I am making a WP8 app.My requirement is to scan devices(RFID scanners that have bluetooth module) , connect to one of it , send commnands to do specific work and get the response ! any help ? – Apoorv May 26 '15 at 05:59
  • 2
    Shouldn't the `Progress` and `Complete` event handlers be registered before the `DiscoverDevicesAsync` method is called? – Edgar Aug 27 '15 at 10:07
  • In general yes but the async method takes some time (some seconds) so usually a device won't be discovered before the handlers are registered. – xmashallax Aug 27 '15 at 13:56
  • 3
    For those looking for how to find the bluetooth MacAddress "mac": http://stackoverflow.com/questions/1819971/how-to-get-bluetooth-mac-address-from-local-pc – CodyF May 12 '16 at 12:49
  • I want to know How to send data to particular device ? – Bhavin Jun 14 '16 at 05:33
  • Is this 32feet library supports connection with Bluetooth low energy devices as well? Like iOS? – Bit_Pulse Feb 15 '17 at 08:26
  • Does anyone know how to connect to a blutooth device without a pin? – noone392 May 16 '17 at 15:48
  • I'm pretty sure every device has a pre-set pin by default. Check the manual or the internet or try 1234 or 0000. Good luck! – xmashallax May 17 '17 at 09:03
  • @Harsh I replaced that BeginConnect method with localClient.Connect(device.DeviceAddress, BluetoothService.Handsfree); (I knew my device was handsfree) – StinkyCat Jul 04 '19 at 10:00
  • In the connect, what value is device PIN? To the best of my knowledge, my smart phone and laptop connect because I provide authorization, if it's requested. Is that the PIN, or is it something else? I'm confused. – octopusgrabbus Feb 27 '20 at 13:47
  • @xmashallax: Don't get me wrong buddy; I appreciate the effort but the post has both really bad English and missing information. You throw code that is expected to be inside methods; there is no object declaration... It feels like Magic Code. People look at it believing there is something; there there is not. Should we just guess? =) Anyways: please improve your thread. –  Mar 31 '21 at 14:37
  • I am sorry but this thread is 8 years old. I don't use the tools anymore. If you provide better code, I will update the answer and mention you :) – xmashallax Aug 05 '21 at 10:21
  • @xmashallax this seems really helpful. but following the same I am facing with an error. While executing BluetoothClient.Connect() it throws error stating "The requested address is not valid in its context". But this happened only when I'm connecting to android smart phone. Working with bluetooth dongle. Share me your email want to share my code. – meekash55 Nov 10 '22 at 17:46
  • As I said I don't have the tools anymore, I can't provide any help here. – xmashallax Nov 13 '22 at 17:51