我还没有找到一个 NuGet 包,可以让我在 Linux 下运行的 C# 程序中进行蓝牙 RFComm。
此外,我想向将使用蓝牙端口的 API 提供一个 Stream 对象。
Linux.Bluetooth(使用 Tmds.DBus 访问 D-Bus)仅支持 BLE,InTheHand.Net 不支持 GNU/Linux。
任何人都可以建议一个简单的策略来实现此功能吗?要访问 D-Bus,我可以使用 Tmds.DBus,但如何创建 Stream 对象?
更新:我认为最好使用 C++/Qt(或 Python)程序来处理这部分,并使用 TCP 套接字在 C# 程序和其他有权访问的程序之间进行通信
更新 2:我找到了这篇文章,我不知道是否可以在 C# 程序上创建相同类型的套接字:https://people.csail.mit.edu/albert/bluez-intro/c404.html => 不,在编译客户端程序时,我需要安装这个Ubuntu包:libbluetooth-dev并将程序链接到libbluetooth。我可以尝试将 C 库导入到 C# 程序中...
我分享了一个快速但肮脏的示例,以便能够在 Ubuntu 上运行的 C# 程序上使用蓝牙端口:
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;
Process rfcommProcess = null;
if (!File.Exists(devicePath))
{
try
{
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);
if (rfcommProcess != null)
{
try
{
rfcommProcess.StandardInput.Close();
rfcommProcess.Kill();
}
catch (Exception ex)
{
Console.WriteLine("Release RFComm exception : " + ex.Message);
}
}
}
}
}
}