在BT设备的树莓派上获得蓝牙信号强度而不需要配对

我喜欢为我现有的家庭自动化系统创build一种室内跟踪系统。 我想过使用BLE。 我已经成功地在我的Raspberry Pi上设置了hcitool ,并且可以连接到我的iPhone,没有任何问题。 但是如何在没有连接的情况下获得我的Raspberry Pi和iPhone之间的信号强度。 我已经尝试使用sudo hcitool cc [BTADDRESS]连接到我的iPhone而不进行身份validation,但它看起来像iPhone不允许这些连接保持打开状态。 我认为这是获得信号强度而不连接两个设备的一种方法。 我想用它来确定从我的树莓派到我的iPhone的距离。 我可以计算从我需要发现我的iPhone的时间的距离?

有两种方法可行,到目前为止,我只能在Android设备上可靠地工作。

  1. 利用智能手机的蓝牙友好名称,并将可发现性设置为无限 。 我已经写了一个简单的应用程序。 在后台工作,此后应用程序已被杀死,因为发现设置被保留。 据我所知,这在iOS中是不可能的。
  2. 在手机的BLE数据包中公布UUID。 这可以通过Android和iOS设备来完成。 但是,在后台,iPhone会将广告切换到收缩模式,使得数据包无法识别。 在后台识别广告iOS设备的问题仍然是开放的 。

在树莓上,我使用PyBluez进行扫描并寻找运行(1)或(2)的智能手机。 我报告一个代码示例:

 import bluetooth import bluetooth._bluetooth as bluez import struct, socket, sys, select def hci_enable_le_scan(sock): hci_toggle_le_scan(sock, 0x01) #Discover name and RSS of enabled BLE devices class MyDiscoverer(bluetooth.DeviceDiscoverer): def pre_inquiry(self): self.done = False def device_discovered(self, address, device_class, rssi, name): discovery_logger.info("Discovered %s" % (address, )) if name == "YOUR-DEVICE-FRIENDLY_NAME": #Use the RSS for your detection / localization system def inquiry_complete(self): self.done = True #Performs inquiry for name request def async_inquiry(): d = MyDiscoverer() while True: d.find_devices(lookup_names = True) readfiles = [ d, ] while True: rfds = select.select( readfiles, [], [] )[0] if d in rfds: d.process_event() if d.done: break time.sleep(DISCOVERY_INTERVAL) #Parse received advertising packets def parse_events(sock): # save current filter old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) flt = bluez.hci_filter_new() bluez.hci_filter_all_events(flt) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt ) while True: pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == LE_META_EVENT: subevent, = struct.unpack("B", pkt[3]) pkt = pkt[4:] if subevent == EVT_LE_CONN_COMPLETE: le_handle_connection_complete(pkt) elif subevent == EVT_LE_ADVERTISING_REPORT: #Check if the advertisement is the one we are searching for if getASCII(pkt[start:end]) == "YOUR-UUID" report_pkt_offset = 0 report_data_length, = struct.unpack("B", pkt[report_pkt_offset + 9]) # each report is 2 (event type, bdaddr type) + 6 (the address) # + 1 (data length field) + report_data length + 1 (rssi) report_pkt_offset = report_pkt_offset + 10 + report_data_length + 1 rssi, = struct.unpack("b", pkt[report_pkt_offset -1]) #Now you have the RSS indicator, use it for monitoring / localization sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) dev_id = 0 try: sock = bluez.hci_open_dev(dev_id) except: print "error accessing bluetooth device..." sys.exit(1) p = threading.Thread(group=None, target=parse_events, name='parsing', args=(sock, )) d = threading.Thread(group=None, target=async_inquiry, name='async_inquiry', args=()) try: p.start() except: print "Error: unable to start parsing thread" try: d.start() except: print "Error: unable to start asynchronousous discovery thread"