【问题标题】:Looking to write Bluetooth 'hcitool' equivelant in Windows希望在 Windows 中编写等效的蓝牙“hcitool”
【发布时间】:2013-02-08 18:57:44
【问题描述】:

我在 Linux 中使用了 Bluez 蓝牙堆栈,它带有一个方便的实用程序“hcitool”。希望在 Windows 中构建具有相同或等效功能的类似功能。具体来说,'hcitool name ',显示指定设备是否在范围内。 任何指导将不胜感激。

我有 Windows SDK v7 和 Visual Studio 2010,使用 C/C++

谢谢。

【问题讨论】:

    标签: windows bluetooth bluez


    【解决方案1】:

    使用我的32feet.NET 库,如下所示。

    编辑 3 月 3 日:我现在添加了代码以直接通过地址而不是使用设备发现来查找设备;所以这是一个简单的 'new BluetoothDeviceInfo(...)'。

    看看是否能找到你想要的设备。这要求远程设备仅处于“可连接”模式,而前者要求它处于“可发现”模式。 (顺便说一句,我已经保留了发现代码。)

    编辑 3 月 8 日:现在进行连接(使用 SDP API)以检查设备是否在范围内(并且处于可连接模式)。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using InTheHand.Net.Bluetooth;
    using InTheHand.Net;
    using InTheHand.Net.Sockets;
    using System.Diagnostics;
    using System.Net.Sockets;
    
    namespace hcitool
    {
        partial class Program
        {
            static bool infoRatherThanName;
            static BluetoothAddress _searchAddress;
    
            static int Main(string[] args)
            {
                if (args.Length < 1) {
                    Console.WriteLine("Please specify command.");
                    return 2;
                }
                var cmd = args[0];
                switch (cmd) {
                    case "name":
                        infoRatherThanName = false;
                        break;
                    case "info":
                        infoRatherThanName = true;
                        break;
                    //-
                    case "dev":
                        return ShowRadios();
                    //case "auth":
                    //    return CauseAuth(GETADDRESS());
                    default:
                        throw new NotImplementedException("Command: '" + cmd + "'");
                }
                if (args.Length < 2) {
                    Console.WriteLine("Please specify device address.");
                    return 2;
                }
                var addrS = args[1];
                _searchAddress = BluetoothAddress.Parse(addrS);
                //
                var dev = new BluetoothDeviceInfo(_searchAddress);
                bool isInRange = GetCanConnectTo(dev);
                if (isInRange) {
                    PrintDevice(dev);
                } else {
                    Console.WriteLine("Can't see that device.");
                }
                //
                Console.WriteLine("simple");
                return Simple();
                //return Fancier();
            }
    
            //----
            private static int ShowRadios()
            {
                BluetoothRadio[] list;
                try {
                    list = BluetoothRadio.AllRadios;
                } catch (Exception) {
                    return 1;
                }
                Debug.Assert(list.Length != 0, "Expect zero radios case to raise an error.");
                foreach (var curR in list) {
                    Console.WriteLine("* {0} '{1}'", curR.LocalAddress, curR.Name);
                    Console.WriteLine("{0}", curR.SoftwareManufacturer);
                    Console.WriteLine("{0}", curR.Manufacturer);
                    Console.WriteLine("{0}", curR.Mode);
                }//for
                return 0;
            }
    
            private static int CauseAuth(BluetoothAddress addr)
            {
                BluetoothSecurity.PairRequest(addr, null);
                return 0;
            }
    
            //----
            static int Simple()
            {
                BluetoothDeviceInfo[] devices;
                BluetoothDeviceInfo foundDev = null;
                var cli = new BluetoothClient();
                // Fast: Remembered/Authenticated
                devices = cli.DiscoverDevices(255, true, true, false, false);
                SimpleCheckDevice(devices, ref foundDev);
                if (foundDev == null) {
                    // Slow: Inquiry
                    cli.DiscoverDevices(255, false, false, true, false);
                    SimpleCheckDevice(devices, ref foundDev);
                }
                //
                if (foundDev != null) {
                    return 0;
                } else {
                    return 1;
                }
            }
    
            private static void SimpleCheckDevice(IEnumerable<BluetoothDeviceInfo> devices,
                ref BluetoothDeviceInfo foundDev)
            {
                foreach (var cur in devices) {
                    if (cur.DeviceAddress == _searchAddress) {
                        foundDev = cur;
                        PrintDevice(cur);
                    }
                }//for
            }
    
            private static void PrintDevice(BluetoothDeviceInfo cur)
            {
                Console.WriteLine("* Found device: '{0}' ", cur.DeviceName);
                if (infoRatherThanName) {
                    try {
                        var vs = cur.GetVersions();
                        Console.WriteLine(vs.Manufacturer);
                        Console.WriteLine(vs.LmpVersion);
                        Console.WriteLine(vs.LmpSubversion);
                        Console.WriteLine(vs.LmpSupportedFeatures);
                    } catch (Exception ex) {
                        Console.WriteLine("Failed to get remote device versions info: "
                            + ex.Message);
                    }
                }
            }
    
            //----
            private static bool GetCanConnectTo(BluetoothDeviceInfo device)
            {
                bool inRange;
                Guid fakeUuid = new Guid("{F13F471D-47CB-41d6-9609-BAD0690BF891}");
                try {
                    ServiceRecord[] records = device.GetServiceRecords(fakeUuid);
                    Debug.Assert(records.Length == 0, "Why are we getting any records?? len: " + records.Length);
                    inRange = true;
                } catch (SocketException) {
                    inRange = false;
                }
                return inRange;
            }
    
        }
    }
    

    【讨论】:

    • 谢谢。让我试一试。我之前确实下载了这个库,但是对 c# 毫无头绪,我无法取得任何进展。
    • 我设法构建并运行了这个应用程序(通过修改“Chat2Desk”示例)。但是它只返回配对的设备。 (与 Windows BT SDK 类似的结果)。与 Linux 的“hcitool”不同,它也可以查询未配对的设备。我的研究表明,我需要在无线电级别查询低级别的驱动程序层。但我可能错了。有什么进一步的建议吗? (再次感谢您的快速应用!)。
    • 无法编译这个:error CS0117: 'InTheHand.Net.Bluetooth.BluetoothRadio' does not contain a definition for 'GetAllRadioserror CS1061: 'InTheHand.Net.Bluetooth.BluetoothRadio' does not contain a definition for 'Modes' and no extension method 'Modes'
    • 好的。也设法建立了这个(经过一些调整)。它确实显示了一个设备(我的 ipod)的名称,而无需配对。但是,即使我禁用 ipod 上的 BT,它也会继续这样做。所以它正在从一些缓存中读取,因为 ipod 之前是由 PC 发现的。对于全新的设备,结果与未找到设备相同(即未打印名称)。另一方面,Linux 工具仅在设备已打开 BT 并且在范围内时才会显示输出。不需要处于可发现模式。 ShowRadios() 会在本地电台上打印正确的信息。 Simple() 似乎什么也没做。
    • 嗯,好的。我应该在一开始就问 hcitool 的行为如何。 :-,) 所以 hcitool——正如它的名字——显然是在使用蓝牙 HCI 命令,在这种情况下显然是 CreateConnection 和 RemoteNameRequest。大多数堆栈将用户从名称查找过程中隐藏起来并自动进行。所以我认为我们将不得不作弊,查看更新的代码,通过尝试连接(使用 SDP API)检查范围。我还删除了对新库版本函数的引用。
    猜你喜欢
    • 2014-11-11
    • 2016-06-22
    • 1970-01-01
    • 1970-01-01
    • 2021-03-26
    • 2012-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多