I haven't found a NuGet package that allows me to do Bluetooth RFComm in a C# program running under Linux.
In addition, I would like to provide a Stream object to the API that will use the bluetooth port.
Linux.Bluetooth (uses Tmds.DBus to access D-Bus) supports only BLE and InTheHand.Net doesn't have GNU/Linux support.
Can anyone suggest a simple strategy for implementing this feature ? To access the D-Bus, I can use Tmds.DBus, but how do I create the Stream object ?
Update : I think it's better to use a C++/Qt (or a Python) program to handle this part and use a TCP socket to communicate between the C# program and the other having access to
Update 2 : I found this article and I don't know if I can create the same type of sockets on a C# program : https://people.csail.mit.edu/albert/bluez-intro/c404.html => No, when compiling the client program, I needed to install this Ubuntu packet : libbluetooth-dev and to link the program to libbluetooth. I can try importing C libraries into the C# program...
A simple solution is to use a virtual serial device to communicate with a Bluetooth device.
I'm sharing with you a quick and dirty example of how to use the bluetooth port in a C# program running under Ubuntu.
The program must be launched with the sudo command since SerialPort is unable to open /dev/rfcomm1 (the virtual serial port created with the command rfcomm bind) without root privileges but I think there's an easy workaround to fix that.
//using InTheHand.Net;
//using InTheHand.Net.Bluetooth;
//using InTheHand.Net.Sockets;
using System;
using System.Diagnostics;
using System.IO.Ports;
using System.Net.Mail;
using System.Text;
namespace QuickBTTest
{
internal class Program
{
static void Main(string[] args)
{
byte[] outBuffer = new byte[12];
byte[] inBuffer = new byte[6];
outBuffer[0] = (byte)'$';
outBuffer[1] = (byte)'P';
outBuffer[2] = (byte)'R';
outBuffer[3] = 12;
outBuffer[4] = 0;
outBuffer[5] = 100;
outBuffer[6] = 0;
outBuffer[7] = 50;
outBuffer[8] = 0;
outBuffer[9] = 200;
ushort cs = 0;
for (int i = 1; i < 10; i++)
{
cs = (ushort)(cs + outBuffer[i]);
}
outBuffer[10] = (byte)(cs >> 8);
outBuffer[11] = (byte)cs;
string address = "88:6B:0F:84:64:1C";
string devicePath = "/dev/rfcomm0";
int port = 1;
if (!File.Exists(devicePath))
{
try
{
Process rfcommProcess = new Process();
rfcommProcess.StartInfo.FileName = "sudo";
rfcommProcess.StartInfo.Arguments = $"/usr/bin/rfcomm bind {devicePath} {address} {port}";
rfcommProcess.StartInfo.UseShellExecute = false;
rfcommProcess.StartInfo.RedirectStandardOutput = true;
rfcommProcess.StartInfo.RedirectStandardError = true;
rfcommProcess.Start();
/*string error = rfcommProcess.StandardError.ReadToEnd();
if (!string.IsNullOrWhiteSpace(error))
{
Console.WriteLine($"Bluetooth bind error : {error}");
return;
}*/
rfcommProcess.WaitForExit(3000);
}
catch (Exception e)
{
Console.WriteLine($"Bluetooth bind error : {e.Message}");
return;
}
}
if (File.Exists(devicePath))
{
SerialPort serialPort = new SerialPort();
serialPort.PortName = devicePath;
serialPort.BaudRate = 115200;
serialPort.ReadTimeout = 5000;
serialPort.Open();
if (serialPort.IsOpen)
{
serialPort.Write(outBuffer, 0, outBuffer.Length);
Console.WriteLine("Wait for response... press enter");
Console.ReadLine();
int ret = serialPort.Read(inBuffer, 0, inBuffer.Length);
if (ret > 0)
{
Console.WriteLine("Rcvd response :");
for (int i = 0; i < ret; i++)
{
Console.Write(inBuffer[i] + ", ");
}
Console.WriteLine();
}
}
serialPort.Close();
Process tCmd = new Process();
tCmd.StartInfo.FileName = "sudo";
tCmd.StartInfo.Arguments = $"/usr/bin/rfcomm release {devicePath}";
tCmd.StartInfo.UseShellExecute = false;
tCmd.StartInfo.RedirectStandardOutput = true;
tCmd.StartInfo.RedirectStandardError = true;
tCmd.Start();
string output = tCmd.StandardOutput.ReadToEnd();
string err = tCmd.StandardError.ReadToEnd();
tCmd.WaitForExit(5000);
}
}
}
}