I am trying to use the 32feet.NET bluetooth library in a C# application to detect nearby devices. The purpose of my little application is to let the PC know who is in the room using the bluetooth feature of people's mobile phones.
The best way to do something like this would be to let the devices I want to "track" connect once, then continuously check if they can be detected via bluetooth.
Now my questions:
Do I need to pair or authenticate a device with my application? How to do this in C# with 32feet.NET?
How to continuously check for devices in range and compare them to the stored devices?
I know that all this is probably in the library documentation, but it is really hard to read for me and most of the examples seem to be in VB which I don't know and find hard to translate to C# (especially when it comes to AsyncCallbacks and the like).
I would be really glad if someone could give me a push in the right direction!
A couple of caveats up front, I'm presuming you're not dealing with HID devices here, they're typically handled by the OS. I've also only just started using 32feet, and I'm using it to create connections to the serial port service on bluetooth barcode scanners, so there may be better ways for your needs but this may point you in the right direction to get started.
You need to pair the device, yes. If you're using it in a WinForms app there's actually form you can display which handles scanning for devices and lets you select one, like so:
bool PairDevice()
{
using (var discoverForm = new SelectBluetoothDeviceDialog())
{
if (discoverForm.ShowDialog(this) != DialogResult.OK)
{
// no device selected
return false;
}
BluetoothDeviceInfo deviceInfo = discoverForm.SelectedDevice;
if (!deviceInfo.Authenticated) // previously paired?
{
// TODO: show a dialog with a PIN/discover the device PIN
if (!BluetoothSecurity.PairDevice(deviceInfo.DeviceAddress, myPin))
{
// not previously paired and attempt to pair failed
return false;
}
}
// device should now be paired with the OS so make a connection to it asynchronously
var client = new BluetoothClient();
client.BeginConnect(deviceInfo.DeviceAddress, BluetoothService.SerialPort, this.BluetoothClientConnectCallback, client);
return true;
}
}
void BluetoothClientConnectCallback(IAsyncResult result)
{
var client = (BluetoothClient)result.State;
client.EndConnect();
// get the client's stream and do whatever reading/writing you want to do.
// if you want to maintain the connection then calls to Read() on the client's stream should block when awaiting data from the device
// when you're done reading/writing and want to close the connection or the device servers the connection control flow will resume here and you need to tidy up
client.Close();
}
By far and away the best way, if your devices are broadcasting that they're available for a connection, is to set up a BluetoothListener
that will continuously listen for broadcasting devices and when one is found you'll get a BluetoothClient
instance that you can use the same as the first time you paired:
void SetupListener()
{
var listener = new BluetoothListener(BluetoothService.SerialPort);
listener.Start();
listener.BeginAcceptBluetoothClient(this.BluetoothListenerAcceptClientCallback, listener);
}
void BluetoothListenerAcceptClientCallback(IAsyncResult result)
{
var listener = (BluetoothListener)result.State;
// continue listening for other broadcasting devices
listener.BeginAcceptBluetoothClient(this.BluetoothListenerAcceptClientCallback, listener);
// create a connection to the device that's just been found
BluetoothClient client = listener.EndAcceptBluetoothClient();
// the method we're in is already asynchronous and it's already connected to the client (via EndAcceptBluetoothClient) so there's no need to call BeginConnect
// TODO: perform your reading/writing as you did in the first code sample
client.Close();
}
Less appealing, but useful if your device isn't broadcasting for connections, you can create a new BluetoothClient
and ask it to return all the devices it can find:
void ScanForBluetoothClients()
{
var client = new BluetoothClient();
BluetoothDeviceInfo[] availableDevices = client.DiscoverDevices(); // I've found this to be SLOW!
foreach (BluetoothDeviceInfo device in availableDevices)
{
if (!device.Authenticated)
{
continue;
}
var peerClient = new BluetoothClient();
peerClient.BeginConnect(deviceInfo.DeviceAddress, BluetoothService.SerialPort, this.BluetoothClientConnectCallback, peerClient);
}
}
This is not an answer, but I wasn't able to put this much code on comment section. Change these lines of code:
//continue listening for other broadcasting devices
listener.BeginAcceptBluetoothClient(this.BluetoothListenerAcceptClientCallback, listener);
// create a connection to the device that's just been found
BluetoothClient client = listener.EndAcceptBluetoothClient();
to
// create a connection to the device that's just been found
BluetoothClient client = listener.EndAcceptBluetoothClient();
// continue listening for other broadcasting devices
listener.BeginAcceptBluetoothClient(this.BluetoothListenerAcceptClientCallback, listener);
Basically, change the sequence of code..
As for every call to BeginXXXX method must have next EndXXXX. And all above code, you are trying to BeginAcceptBluetoothClient over already began "BeginAcceptBluetoothClient".
Hope you understand.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With