ubuntu 在Linux上运行的C#程序上的蓝牙RFComm

hrysbysz  于 2023-10-17  发布在  Linux
关注(0)|答案(1)|浏览(107)

我还没有找到一个NuGet包,可以让我在Linux下运行的C#程序中执行蓝牙RFComm。
此外,我想向将使用蓝牙端口的API提供一个Stream对象。
Linux。蓝牙(使用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#程序中。

3phpmpom

3phpmpom1#

一个简单的解决方案是使用虚拟串行设备与蓝牙设备进行通信。
我与你分享一个快速和肮脏的例子,如何在Ubuntu下运行的C#程序中使用蓝牙端口。
该程序必须使用sudo命令启动,因为SerialPort无法在没有root权限的情况下打开/dev/rfcomm 1(使用命令rfcommbind创建的虚拟串行端口),但我认为有一个简单的解决方案可以解决这个问题。

//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);
            }
        }
    }
}

相关问题