xcode Mac 上的蓝牙 RSSI/查询扫描 - 无需连接即可检测到 iPhone?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7998335/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bluetooth RSSI/Inquiry scan on Mac - proximity detection to iPhone without connecting?
提问by Benjie
I have to dash away from the computer frequently, and I want to trigger some commands to run when my iPhone is close enough/far enough from my iMac (next to it vs. 2-3 metres away/other side of a wall). A couple of minutes latency is fine.
我必须经常远离计算机,并且我想在我的 iPhone 离 iMac 足够近/足够远时触发一些命令来运行(在它旁边与 2-3 米远/墙的另一侧)。几分钟的延迟没问题。
Partial solution: proximity
部分解决方案:接近
I've downloaded reduxcomputing-proximityand it works, but this only triggers when the device goes in to/out of range of bluetooth, but my desired range is much smaller.
我已经下载了reduxcomputing-proximity并且它可以工作,但这仅在设备进入/超出蓝牙范围时触发,但我想要的范围要小得多。
(Proximity polls [IOBluetoothDevice -remoteNameRequest]
to see if the device is in bluetooth range or not.)
(接近轮询[IOBluetoothDevice -remoteNameRequest]
以查看设备是否在蓝牙范围内。)
Enhancement: rawRSSI
增强:rawRSSI
I've used [IOBluetoothDevice -rawRSSI]
to get the RSSI when I am connected to the iPhone (when disconnected this just returns +127
), but in order to save the battery life of my iPhone I'd rather avoid establishing a full bluetooth connection.
我曾经[IOBluetoothDevice -rawRSSI]
在连接到 iPhone 时获取 RSSI(断开连接时它会返回+127
),但为了节省 iPhone 的电池寿命,我宁愿避免建立完整的蓝牙连接。
Am I correct in thinking that maintaining a connection will consume more battery life than just polling every couple of minutes?
我认为保持连接比每隔几分钟轮询一次会消耗更多的电池寿命是正确的吗?
I've overridden the isInRange
method of proximity
here to give me a working solution that's probably relatively battery intensive compared to the previous remoteNameRequest:
method:
我已经覆盖了这里的isInRange
方法,proximity
为我提供了一个可行的解决方案,与之前的remoteNameRequest:
方法相比,该解决方案可能相对耗电:
- (BOOL)isInRange {
BluetoothHCIRSSIValue RSSI = 127; /* Valid Range: -127 to +20 */
if (device) {
if (![device isConnected]) {
[device openConnection];
}
if ([device isConnected]) {
RSSI = [device rawRSSI];
[device closeConnection];
}
}
return (RSSI >= -60 && RSSI <= 20);
}
(Proximity uses synchronous calls - if and when I fit it to my needs I will edit it to be asynchronous but for now that's not important.)
(Proximity 使用同步调用——如果当我满足我的需要时,我会将它编辑为异步,但现在这并不重要。)
Under Linux: l2ping - inquiry scan?
Linux下:l2ping - 查询扫描?
This SO postreferences getting an RSSI during an 'inquiry scan' which sounds like what I want, but it talks about using the Linux Bluez library, whilst I am on a Mac - I'd rather do it without having to stray too far if possible! (I have considered using a VM with USB pass-thru to hook up a second bluetooth device... But a simpler solution would be preferable!)
这篇 SO 帖子引用了在“查询扫描”期间获取 RSSI,这听起来像我想要的,但它谈到使用 Linux Bluez 库,而我在 Mac 上 - 我宁愿这样做而不必走得太远,如果可能的!(我曾考虑使用带有 USB 直通功能的 VM 来连接第二个蓝牙设备......但更简单的解决方案会更可取!)
I see there is a IOBluetoothDeviceInquiry
class, but I am not sure if this is useful to me. I don't intend to learn bluetooth protocol just for this simple problem!
我看到有一个IOBluetoothDeviceInquiry
课程,但我不确定这对我是否有用。我不打算为了这个简单的问题去学习蓝牙协议!
The commands
命令
For interest, and not particularly relevant to the solution, here are the Apple Scripts I currently trigger when
出于兴趣,但与解决方案并不是特别相关,以下是我当前触发的 Apple 脚本
in range:
在范围内:
tell application "Skype"
send command "SET USERSTATUS ONLINE" script name "X"
do shell script "afplay '/System/Library/Sounds/Blow.aiff'"
end tell
out of range:
超出范围:
tell application "Skype"
send command "SET USERSTATUS AWAY" script name "X"
do shell script "afplay '/System/Library/Sounds/Basso.aiff'"
end tell
Though these are likely to get longer!
虽然这些可能会变得更长!
采纳答案by Dennis Mathews
In terms of tradeoffs for your use case doing a continuous or periodic inquiry will consume same or even a bit more energy as doing a periodic connect / read RSSI and disconnect. Depending on the use case it sometimes may be more efficient to maintain the connection in a low power mode (sniff with 2.56 sec interval) and remain connected if the device is in range. And use RSSI to monitor proximity (although it is not accurate as interference due to objects change rssi drastically even though the device might be in proximity)
就您的用例的权衡而言,执行连续或定期查询将消耗与执行定期连接/读取 RSSI 和断开连接相同甚至更多的能量。根据用例,有时在低功耗模式下(以 2.56 秒间隔嗅探)保持连接并在设备在范围内时保持连接可能更有效。并使用 RSSI 来监控接近度(尽管它不准确,因为即使设备可能接近,由于物体引起的干扰也会急剧改变 RSSI)
回答by TJD
You are correct that making a connection will cost more energy. However, I'm not aware of APIs on mac OS that will give you access to the RSSI from inquiry scan packets. You could get access to the raw packets from your BT adapter using Mac OS PacketLogger. See this post Bluetooth sniffer - preferably mac osx
你是对的,建立连接会花费更多的能量。但是,我不知道 Mac OS 上的 API 可以让您从查询扫描数据包中访问 RSSI。您可以使用 Mac OS PacketLogger 从 BT 适配器访问原始数据包。请参阅这篇文章蓝牙嗅探器 - 最好是 mac osx
You could programmaticly put your device in discovery every couple of minutes, capture the inquiry scan packets with the packetlogger, and parse out the RSSI. You can use WireShark to help you understand how to decode the packets and find RSSI.
您可以每隔几分钟以编程方式将设备置于发现状态,使用数据包记录器捕获查询扫描数据包,并解析出 RSSI。您可以使用 WireShark 来帮助您了解如何解码数据包并找到 RSSI。
Your simplest option is probably to just periodically create a connection, measure RSSI, and then tear down the connection.
您最简单的选择可能是定期创建一个连接,测量 RSSI,然后断开连接。