jjzjj

windows - 希望在 Windows 中编写等效的蓝牙 'hcitool'

coder 2023-11-12 原文

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

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

谢谢。

最佳答案

使用我的 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;
        }

    }
}

关于windows - 希望在 Windows 中编写等效的蓝牙 'hcitool',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15036364/

有关windows - 希望在 Windows 中编写等效的蓝牙 'hcitool'的更多相关文章

  1. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  2. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  3. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  4. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  5. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  6. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  7. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  8. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  9. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  10. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

随机推荐