def set_bt_name(name, src_hci, src, dst): """ Sets the name of the local bluetooth device to 'name'. Params: - 'name' - The new name of the device - 'src_hci' - Name of the bluetooth device to change the name of - 'src' - The bluetooth address of the local device - 'dst' - Bluetooth address of a remote device to temporarily connect with (sets the REMOTE_NAME in 'dst') """ # Create raw HCI sock to set our BT name raw_sock = bt.hci_open_dev(bt.hci_devid(src_hci)) flt = bt.hci_filter_new() bt.hci_filter_all_ptypes(flt) bt.hci_filter_all_events(flt) raw_sock.setsockopt(bt.SOL_HCI, bt.HCI_FILTER, flt) # Send raw HCI command to controller (first 3 bytes are padding for alignment) raw_sock.sendall( binascii.unhexlify('01130cf8cccccc') + name.ljust(MAX_BT_NAME, b'\x00')) raw_sock.close() time.sleep(0.1) # Connect to BNEP to "refresh" the name bnep = bluetooth.BluetoothSocket(bluetooth.L2CAP) bnep.bind((src, 0)) bnep.connect((dst, BNEP_PSM)) bnep.close() # Close ACL connection again util.exec_command_block(["hcitool", "dc", dst])
def find_devices (s, lookup_names=True, duration=8, flush_cache=True): if s.is_inquiring: raise BluetoothError ("Already inquiring!") s.lookup_names = lookup_names s.sock = _gethcisock () flt = _bt.hci_filter_new () _bt.hci_filter_all_events (flt) _bt.hci_filter_set_ptype (flt, _bt.HCI_EVENT_PKT) try: s.sock.setsockopt (_bt.SOL_HCI, _bt.HCI_FILTER, flt) except: raise BluetoothError ("problem with local bluetooth device.") # send the inquiry command max_responses = 255 cmd_pkt = struct.pack ("BBBBB", 0x33, 0x8b, 0x9e, \ duration, max_responses) s.pre_inquiry () try: _bt.hci_send_cmd (s.sock, _bt.OGF_LINK_CTL, \ _bt.OCF_INQUIRY, cmd_pkt) except: raise BluetoothError ("problem with local bluetooth device.") s.is_inquiring = True s.names_to_find = {}
def ScanBeacons(sock, loop_count): 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 ) results = [] for i in range(0, loop_count): packet = sock.recv(255) ptype, event, plen = struct.unpack("BBB", packet[:3]) if(plen == 42): if event == 0x3e: subevent = ToChar(packet[3]) packet = packet[4:] if(BDAddrToString(packet[3:9]) == "43:45:c0:00:1f:ac"): if subevent == 0x01: le_handle_connection_complete(packet) elif subevent == 0x02: num_reports = ToChar(packet[0]) for i in range(0, num_reports): b = Beacon() b.minor = "%i" % NumberPacket(packet[-4:-2]) b.mac = BDAddrToString(packet[3:9]) b.rssi = "%i" % ToChar(packet[-1], signed=True) if b not in results: results.append(b) return results
def parse_events(sock, target_uuid, loop_count=100): """Parses the events that the bluetooth socket recieves""" 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) result = None for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == LE_META_EVENT: subevent = pkt[3] pkt = pkt[4:] if subevent == EVT_LE_ADVERTISING_REPORT: num_reports = pkt[0] report_pkt_offset = 0 for i in range(0, num_reports): uuid = returnstringpacket(pkt[report_pkt_offset - 22:report_pkt_offset - 6]) rssi = struct.unpack("b", pkt[report_pkt_offset - 1:])[0] if uuid == target_uuid: result = FindResult(uuid, rssi) break else: continue break sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return result
def fetch_rssi(socket, bdaddr): flt = bluez.hci_filter_new() bluez.hci_filter_all_events(flt) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) socket.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt ) cmd_pkt = struct.pack("????") bluez.hci_send_cmd(socket, bluez.OGF_LINK_CTL, bluez.OCF_READ_RSSI, cmd_pkt) pkt = socket.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: pkt = pkt[3:] nrsp = bluetooth.get_byte(pkt[0]) for i in range(nrsp): addr = bluez.ba2str( pkt[1+6*i:1+6*i+6] ) rssi = bluetooth.byte_to_signed_int( bluetooth.get_byte(pkt[1+13*nrsp+i])) results.append( ( addr, rssi ) ) print("[%s] RSSI: [%d]" % (addr, rssi)) elif event == bluez.EVT_CMD_STATUS: status, ncmd, opcode = struct.unpack("BBH", pkt[3:7]) if status != 0: print("uh oh...") done = True elif event == bluez.EVT_INQUIRY_RESULT: pkt = pkt[3:] nrsp = bluetooth.get_byte(pkt[0]) for i in range(nrsp): addr = bluez.ba2str( pkt[1+6*i:1+6*i+6] ) results.append( ( addr, -1 ) ) print("[%s] (no RRSI)" % addr) else: print("unrecognized packet type 0x%02x" % ptype) print("event ", event)
def device_inquiry_with_with_rssi(sock): # save current filter old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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) duration = 4 max_responses = 255 cmd_pkt = struct.pack("BBBBB", 0x33, 0x8b, 0x9e, duration, max_responses) bluez.hci_send_cmd(sock, bluez.OGF_LINK_CTL, bluez.OCF_INQUIRY, cmd_pkt) results = [] while True: pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) print("Event: {}".format(event)) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: pkt = pkt[3:] nrsp = bluetooth.get_byte(pkt[0]) for i in range(nrsp): addr = bluez.ba2str(pkt[1 + 6 * i:1 + 6 * i + 6]) rssi = bluetooth.byte_to_signed_int( bluetooth.get_byte(pkt[1 + 13 * nrsp + i])) results.append((addr, rssi)) print("[{}] RSSI: {}".format(addr, rssi)) rssi = (pkt[-1]) print(addr, rssi) elif event == bluez.EVT_INQUIRY_COMPLETE: break elif event == bluez.EVT_CMD_STATUS: status, ncmd, opcode = struct.unpack("BBH", pkt[3:7]) if status: print("Uh oh...") printpacket(pkt[3:7]) break elif event == bluez.EVT_INQUIRY_RESULT: pkt = pkt[3:] nrsp = bluetooth.get_byte(pkt[0]) for i in range(nrsp): addr = bluez.ba2str(pkt[1 + 6 * i:1 + 6 * i + 6]) results.append((addr, -1)) print("[{}] (no RRSI)".format(addr)) rssi = (pkt[-1]) print(addr, rssi) else: print("Unrecognized packet type 0x{:02x}.".format(ptype)) # restore old filter sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return results
def run(self): self._sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) cmd_pkt = struct.pack("<BB", 0x01, 0x00) bluez.hci_send_cmd(self._sock, OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE, cmd_pkt) while True: old_filter = self._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) self._sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, flt) pkt = self._sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == LE_META_EVENT: sub_event, = struct.unpack("B", pkt[3]) pkt = pkt[4:] if sub_event == EVT_LE_CONN_COMPLETE: le_handle_connection_complete(pkt) elif sub_event == EVT_LE_ADVERTISING_REPORT: mac = self._packed_bdaddr_to_string(pkt[3:9]) rssi = struct.unpack("b", pkt[-1])[0] data_frame = pkt[14:-1] payload = struct.unpack("B" * len(data_frame), data_frame) self._lock.acquire() self._messages.append((mac, rssi, payload)) self._lock.release() self._sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter)
def _hci_set_le_scan_params(self): # set scan parameter self._old_filter = self._dev_sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) new_filter = bluez.hci_filter_new() bluez.hci_filter_all_events(new_filter) bluez.hci_filter_set_ptype(new_filter, bluez.HCI_EVENT_PKT) self._dev_sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, new_filter)
def parse_events(self, restore_filter=False): """Method used to parse an event, save it just if matching our filter. """ if restore_filter: old_filter = self.hci_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) self.hci_sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, flt) filtered_reports = [] pkt = self.hci_sock.recv(255) # Analyze what is received and parse usefull data parsed_packet = self.hci_le_parse_event(pkt) if ("bluetooth_le_subevent_name" in parsed_packet) and ( parsed_packet["bluetooth_le_subevent_name"] == 'EVT_LE_ADVERTISING_REPORT'): for report in parsed_packet["advertising_reports"]: # self.print_report(report, pkt) # If match our format we should save them if self.verify_beacon_packet(report): filtered_reports.append(report) if restore_filter: self.hci_sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return filtered_reports
def parse_events(sock, loop_count=100): old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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) done = False results = [] myFullList = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) # print "--------------" if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i = 0 elif event == bluez.EVT_NUM_COMP_PKTS: i = 0 elif event == bluez.EVT_DISCONN_COMPLETE: i = 0 elif event == LE_META_EVENT: subevent, = struct.unpack("B", pkt[3]) pkt = pkt[4:] if subevent == EVT_LE_CONN_COMPLETE: le_handle_connection_complete(pkt) done = True sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return myFullList
def parse_packets(self): old_filter = self.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) self.sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, flt) pkt = self.sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i = 0 elif event == bluez.EVT_NUM_COMP_PKTS: i = 0 elif event == bluez.EVT_DISCONN_COMPLETE: i = 0 elif event == LE_META_EVENT: subevent, = struct.unpack("B", pkt[3]) pkt = pkt[4:] if subevent == EVT_LE_CONN_COMPLETE: self.le_handle_connection_complete(pkt) elif subevent == EVT_LE_ADVERTISING_REPORT: num_reports = struct.unpack("B", pkt[0])[0] for i in range(0, num_reports): macAddressSeen = self.packed_bdaddr_to_string(pkt[3:9]) rssi = ''.join(c for c in str(struct.unpack("b", pkt[-1])) if c in '-0123456789') self.filter(macAddressSeen, rssi) if (len(self.beacon_list) > 0 and self.beacon_list_age < time.time() - self.config['update_frequency']): # self.log.debug('Flushing list to the stream... Age: %d, Size: %i' % (time.time() - self.beacon_list_age, len(self.beacon_list))) self.flush_list() self.beacon_list_age = time.time() self.sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter)
def update(self): """Get the latest data from the scale.""" import bluetooth._bluetooth as bluez # low level bluetooth wrappers. old_filter = self._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) self._sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, flt) for i in range(100): pkt = self._sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) subevent, = struct.unpack("B", pkt[3:4]) pkt = pkt[4:] if event == 0x3e and subevent == 0x02: mac = ':'.join( '%02x' % i for i in struct.unpack("<BBBBBB", pkt[3:9][::-1])) print(i, mac) if mac.lower() == self._mac: uuid = ''.join( '%02x' % i for i in struct.unpack("B" * 16, pkt[-22:-6])) print(mac, uuid, ptype) if self._validate_data(uuid): break self._sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter)
def Catch_and_Store_advertisement_meassages(sock): global tags_list global semaphore global CHANGES_TO_DATABASE #Setup filter to receive only the events what we need flt = bluez.hci_filter_new() bluez.hci_filter_all_events(flt) # Enable all events, then mask it with HCI_EVENT_PKT = 0x04 check bluez source/lib/hci.h bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) #HCI Packet types: Bluetooth specification (4.2) page 2406, Vol 4, Part A, Section: 2 - Protocol sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt ) #(socket level)SOL_HCI = 0 check bluez source/lib/bluetooth.h while(True): if(BLOCK_THREADS == False): try: packet = sock.recv(46) if packet: entry = process_BLE_packet(packet) if entry: tags_list.append(entry) if (len(tags_list)>20): semaphore.acquire() status = update_detected_tags(tags_list) tags_list =[] CHANGES_TO_DATABASE = 1 semaphore.release() except Exception,e: error_reporting(("ERROR - Catch_and_Store_advertisement_meassages..." + str(e))) else: print "close ble thread..." break
def parse_events(sock, loop_count=100): 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 ) myFullList = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i = 0 elif event == bluez.EVT_NUM_COMP_PKTS: i = 0 elif event == bluez.EVT_DISCONN_COMPLETE: i = 0 elif event == LE_META_EVENT: subevent, = struct.unpack("B", pkt[3:4]) pkt = pkt[4:] if subevent == EVT_LE_CONN_COMPLETE: le_handle_connection_complete(pkt) elif subevent == EVT_LE_ADVERTISING_REPORT: num_reports = struct.unpack("B", pkt[0:1])[0] report_pkt_offset = 0 for i in range(0, num_reports): # build the return string Adstring = returnstringpacket(pkt[report_pkt_offset - 22: report_pkt_offset - 6]) Adstring += ',' Adstring += "%i" % struct.unpack("b", pkt[report_pkt_offset - 2: report_pkt_offset - 1]) Adstring += ',' Adstring += "%i" % struct.unpack("b", pkt[report_pkt_offset - 1:]) #Prevent duplicates in results if Adstring not in myFullList: myFullList.append(Adstring) sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return myFullList
def device_inquiry_with_with_rssi(sock): global FOUND # save current filter old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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 ) duration = 4 max_responses = 255 cmd_pkt = struct.pack("BBBBB", 0x33, 0x8b, 0x9e, duration, max_responses) bluez.hci_send_cmd(sock, bluez.OGF_LINK_CTL, bluez.OCF_INQUIRY, cmd_pkt) results = [] done = False while not done: pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: pkt = pkt[3:] nrsp = struct.unpack("B", pkt[0])[0] for i in range(nrsp): addr = bluez.ba2str( pkt[1+6*i:1+6*i+6] ) rssi = struct.unpack("b", pkt[1+13*nrsp+i])[0] results.append( ( addr, rssi ) ) print("[%s] RSSI: [%d]" % (addr, rssi)) if addr == ADDR: FOUND = True return elif event == bluez.EVT_INQUIRY_COMPLETE: done = True elif event == bluez.EVT_CMD_STATUS: status, ncmd, opcode = struct.unpack("BBH", pkt[3:7]) if status != 0: print("uh oh...") printpacket(pkt[3:7]) done = True elif event == bluez.EVT_INQUIRY_RESULT: pkt = pkt[3:] nrsp = struct.unpack("B", pkt[0])[0] for i in range(nrsp): addr = bluez.ba2str( pkt[1+6*i:1+6*i+6] ) results.append( ( addr, -1 ) ) print("[%s] (no RRSI)" % addr) else: print("unrecognized packet type 0x%02x" % ptype) print("event ", event) # restore old filter sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return results
def parse_events(sock, loop_count=100): old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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) beacons = [] for i in range(0, loop_count): 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: num_reports = struct.unpack('B', pkt[0])[0] report_pkt_offset = 0 for i in range(0, num_reports): beacons.append({ 'uuid': returnstringpacket(pkt[report_pkt_offset - 22: report_pkt_offset - 6]), 'minor': returnnumberpacket(pkt[report_pkt_offset - 4: report_pkt_offset - 2]), 'major': returnnumberpacket(pkt[report_pkt_offset - 6: report_pkt_offset - 4]) }) done = True sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return beacons
def parse_events(sock, loop_count=100): 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 ) done = False results = [] myFullList = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) #print "--------------" if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i =0 elif event == bluez.EVT_NUM_COMP_PKTS: i =0 elif event == bluez.EVT_DISCONN_COMPLETE: i =0 elif 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: #print "advertising report" num_reports = struct.unpack("B", pkt[0])[0] report_pkt_offset = 0 for i in range(0, num_reports): if (DEBUG == True): print "-------------" print "\tfullpacket: ", printpacket(pkt) print "\tUDID: ", printpacket(pkt[report_pkt_offset -22: report_pkt_offset - 6]) print "\tMAJOR: ", printpacket(pkt[report_pkt_offset -6: report_pkt_offset - 4]) print "\tMINOR: ", printpacket(pkt[report_pkt_offset -4: report_pkt_offset - 2]) print "\tMAC address: ", packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) txpower, = struct.unpack("b", pkt[report_pkt_offset -2]) rssi, = struct.unpack("b", pkt[report_pkt_offset -1]) print "\tRSSI:", rssi #return string Adstring = packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) Adstring += "," Adstring += returnstringpacket(pkt[report_pkt_offset -22: report_pkt_offset - 6]) Adstring += "," Adstring += "%i" % returnnumberpacket(pkt[report_pkt_offset -6: report_pkt_offset - 4]) Adstring += "," Adstring += "%i" % returnnumberpacket(pkt[report_pkt_offset -4: report_pkt_offset - 2]) Adstring += "," Adstring += "%i" % struct.unpack("b", pkt[report_pkt_offset -2]) Adstring += "," Adstring += "%i" % struct.unpack("b", pkt[report_pkt_offset -1]) print "\tfullpacket: ", printpacket(pkt) myFullList.append(Adstring) done = True return myFullList
def parse_events(sock, loop_count=100): old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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 ) done = False results = [] myFullList = [] myDataList = [] data = { 'uuid': '', 'major': '', 'minor': '' } for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) #print "--------------" if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i =0 elif event == bluez.EVT_NUM_COMP_PKTS: i =0 elif event == bluez.EVT_DISCONN_COMPLETE: i =0 elif 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: #print "advertising report" num_reports = struct.unpack("B", pkt[0])[0] report_pkt_offset = 0 for i in range(0, num_reports): if (DEBUG == True): print "-------------" #print "\tfullpacket: ", printpacket(pkt) print "\tUDID: ", printpacket(pkt[report_pkt_offset -22: report_pkt_offset - 6]) print "\tMAJOR: ", printpacket(pkt[report_pkt_offset -6: report_pkt_offset - 4]) print "\tMINOR: ", printpacket(pkt[report_pkt_offset -4: report_pkt_offset - 2]) print "\tMAC address: ", packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) # commented out - don't know what this byte is. It's NOT TXPower txpower, = struct.unpack("b", pkt[report_pkt_offset -2]) print "\t(Unknown):", txpower rssi, = struct.unpack("b", pkt[report_pkt_offset -1]) print "\tRSSI:", rssi # build the list of beacon data myDataList.append(BeaconData(returnstringpacket(pkt[report_pkt_offset -22: report_pkt_offset - 6]), returnnumberpacket(pkt[report_pkt_offset -6: report_pkt_offset - 4]), returnnumberpacket(pkt[report_pkt_offset -4: report_pkt_offset - 2]), struct.unpack("b", pkt[report_pkt_offset -1]),int(time.time()), scanutil.display_mac_addr())) done = True sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return myDataList
def _hci_set_le_scan_params(self): # set scan parameter self._old_filter = self._dev_sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) new_filter = bluez.hci_filter_new() bluez.hci_filter_all_events(new_filter) bluez.hci_filter_set_ptype(new_filter, bluez.HCI_EVENT_PKT) self._dev_sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, new_filter)
def __init__(self): self.sock = bluez.hci_open_dev(0) # Filter socket for HCI_EVENT_PKT fltr = bluez.hci_filter_new() bluez.hci_filter_all_events(fltr) bluez.hci_filter_set_ptype(fltr, bluez.HCI_EVENT_PKT) self.sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, fltr) self.db = redis.Redis(host="raspberry.local", port=6379, db=0)
def find_devices (self, lookup_names=True, duration=8, flush_cache=True): """ find_devices (lookup_names=True, service_name=None, duration=8, flush_cache=True) Call this method to initiate the device discovery process lookup_names - set to True if you want to lookup the user-friendly names for each device found. service_name - set to the name of a service you're looking for. only devices with a service of this name will be returned in device_discovered () NOT YET IMPLEMENTED ADVANCED PARAMETERS: (don't change these unless you know what you're doing) duration - the number of 1.2 second units to spend searching for bluetooth devices. If lookup_names is True, then the inquiry process can take a lot longer. flush_cache - return devices discovered in previous inquiries """ if self.is_inquiring: raise BluetoothError (EBUSY, "Already inquiring!") self.lookup_names = lookup_names self.sock = _gethcisock (self.device_id) flt = _bt.hci_filter_new () _bt.hci_filter_all_events (flt) _bt.hci_filter_set_ptype (flt, _bt.HCI_EVENT_PKT) try: self.sock.setsockopt (_bt.SOL_HCI, _bt.HCI_FILTER, flt) except _bt.error as e: raise BluetoothError (*e.args) # send the inquiry command max_responses = 255 cmd_pkt = struct.pack ("BBBBB", 0x33, 0x8b, 0x9e, \ duration, max_responses) self.pre_inquiry () try: _bt.hci_send_cmd (self.sock, _bt.OGF_LINK_CTL, \ _bt.OCF_INQUIRY, cmd_pkt) except _bt.error as e: raise BluetoothError (*e.args) self.is_inquiring = True self.names_to_find = {} self.names_found = {}
def _device_inquiry_with_with_rssi(self, sock): """inquiry blutooth devices with rssi""" # save current filter old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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) duration = 4 max_responses = 255 cmd_pkt = struct.pack("BBBBB", 0x33, 0x8b, 0x9e, duration, max_responses) bluez.hci_send_cmd(sock, bluez.OGF_LINK_CTL, bluez.OCF_INQUIRY, cmd_pkt) results = [] done = False while not done: pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: pkt = pkt[3:] nrsp = bluetooth.get_byte(pkt[0]) for i in range(nrsp): addr = bluez.ba2str(pkt[1 + 6 * i:1 + 6 * i + 6]) rssi = bluetooth.byte_to_signed_int( bluetooth.get_byte(pkt[1 + 13 * nrsp + i])) results.append( (addr, rssi, str(datetime.datetime.utcnow()))) elif event == bluez.EVT_INQUIRY_COMPLETE: done = True elif event == bluez.EVT_CMD_STATUS: status, ncmd, opcode = struct.unpack("BBH", pkt[3:7]) if status != 0: print("uh oh...") self._print_packet(pkt[3:7]) done = True elif event == bluez.EVT_INQUIRY_RESULT: pkt = pkt[3:] nrsp = bluetooth.get_byte(pkt[0]) for i in range(nrsp): addr = bluez.ba2str(pkt[1 + 6 * i:1 + 6 * i + 6]) results.append((addr, -1, str(datetime.datetime.utcnow()))) else: print("unrecognized packet type 0x%02x" % ptype) # restore old filter sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return results
def parse_events(sock, loop_count=100): old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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) done = False results = [] myFullList = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack('BBB', pkt[:3]) #print '--------------' if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i = 0 elif event == bluez.EVT_NUM_COMP_PKTS: i = 0 elif event == bluez.EVT_DISCONN_COMPLETE: i = 0 elif 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: #print 'advertising report' num_reports = struct.unpack('B', pkt[0])[0] report_pkt_offset = 0 for i in range(0, num_reports): #print '\tfullpacket: ', printpacket(pkt) device = bledevice() device.udid = returnstringpacket( pkt[report_pkt_offset - 22:report_pkt_offset - 6]) device.major = returnnumberpacket( pkt[report_pkt_offset - 6:report_pkt_offset - 4]) device.minor = returnnumberpacket( pkt[report_pkt_offset - 4:report_pkt_offset - 2]) device.macaddress = packed_bdaddr_to_string( pkt[report_pkt_offset + 3:report_pkt_offset + 9]) device.txpower = struct.unpack('b', pkt[report_pkt_offset - 2]) device.rssi = struct.unpack('b', pkt[report_pkt_offset - 1]) #print returnstringpacket(pkt[report_pkt_offset -22: report_pkt_offset - 6]) #print returnnumberpacket(pkt[report_pkt_offset -6: report_pkt_offset - 4]) #print returnnumberpacket(pkt[report_pkt_offset -4: report_pkt_offset - 2]) #print packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) #print struct.unpack('b', pkt[report_pkt_offset -2]) #print struct.unpack('b', pkt[report_pkt_offset -1]) myFullList.append(device) done = True sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return myFullList
def Listen(self): try: old_filter = self.sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on blue tooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices flt = bluez.hci_filter_new() bluez.hci_filter_all_events(flt) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) self.sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, flt) while True: pkt = self.sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i = 0 elif event == bluez.EVT_NUM_COMP_PKTS: i = 0 elif event == bluez.EVT_DISCONN_COMPLETE: i = 0 elif 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: # print "advertising report" num_reports = struct.unpack("B", pkt[0])[0] report_pkt_offset = 0 for i in range(0, num_reports): if DEBUG == True: print "-------------" print "\t", "full packet: ", self.printpacket(pkt) print "\t", "MAC address: ", self.packed_bdaddr_to_string( pkt[report_pkt_offset + 3 : report_pkt_offset + 9] ) # build the return string id = pkt[report_pkt_offset + 12 : report_pkt_offset + 26] if DEBUG == True: print "\t", "id: ", id if id == "MSOT_BLE_Demo:": # MAC address macAddress = self.packed_bdaddr_to_string( pkt[report_pkt_offset + 3 : report_pkt_offset + 9] ) # string representation of Water Volume Content (unit-less) floating point value value = pkt[report_pkt_offset + 26 : report_pkt_offset + 36] if DEBUG == True: print "\t", "address=", macAddress, " value=", value if self.callback != None: print "calling event handler" self.callback(macAddress, value) except: self.sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) print "error in BLE Listen loop" sys.exit(1)
def device_inquiry_with_with_rssi(sock): # save current filter old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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 ) duration = 4 max_responses = 255 cmd_pkt = struct.pack("BBBBB", 0x33, 0x8b, 0x9e, duration, max_responses) bluez.hci_send_cmd(sock, bluez.OGF_LINK_CTL, bluez.OCF_INQUIRY, cmd_pkt) results = [] done = False while not done: pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: pkt = pkt[3:] print("test", pkt, type(pkt[0])) nrsp = struct.unpack(b"B", bytes(pkt[0]))[0] print(nrsp, type(nrsp)) for i in range(nrsp): addr = bluez.ba2str( pkt[1+6*i:1+6*i+6] ) rssi = struct.unpack("b", pkt[1+13*nrsp+i])[0] print("addr", addr, type(addr)) results.append( ( addr, rssi ) ) print ("[%s] RSSI: [%d]" % (addr, rssi)) elif event == bluez.EVT_INQUIRY_COMPLETE: done = True elif event == bluez.EVT_CMD_STATUS: status, ncmd, opcode = struct.unpack("BBH", pkt[3:7]) if status != 0: print ("uh oh...") printpacket(pkt[3:7]) done = True elif event == bluez.EVT_INQUIRY_RESULT: pkt = pkt[3:] nrsp = struct.unpack("B", pkt[0])[0] for i in range(nrsp): addr = bluez.ba2str( pkt[1+6*i:1+6*i+6] ) results.append( ( addr, -1 ) ) print ("[%s] (no RRSI)" % addr) else: print ("unrecognized packet type 0x%02x" % ptype) print ("event ", event) # restore old filter sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return results
def parse_events(sock, loop_count=100): old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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) done = False results = [] myFullList = [] beacons = {} for i in range(0, loop_count): sock.settimeout(10) try: pkt = sock.recv(255) except (socket.timeout, socket.error, bluez.timeout) as e: print "Connection error: {}".format(e) return {} ptype, event, plen = struct.unpack("BBB", pkt[:3]) #print "--------------" if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i = 0 elif event == bluez.EVT_NUM_COMP_PKTS: i = 0 elif event == bluez.EVT_DISCONN_COMPLETE: i = 0 elif 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: #print "advertising report" num_reports = struct.unpack("B", pkt[0])[0] report_pkt_offset = 0 for i in range(0, num_reports): beacon_data = {} beacon_data['udid'] = returnstringpacket( pkt[report_pkt_offset - 22:report_pkt_offset - 6]) beacon_data['major'] = returnstringpacket( pkt[report_pkt_offset - 6:report_pkt_offset - 4]) beacon_data['minor'] = returnstringpacket( pkt[report_pkt_offset - 4:report_pkt_offset - 2]) mac_addr = packed_bdaddr_to_string( pkt[report_pkt_offset + 3:report_pkt_offset + 9]) beacon_data['txpower'] = struct.unpack( "b", pkt[report_pkt_offset - 2]) beacon_data['rssi'] = struct.unpack( "b", pkt[report_pkt_offset - 1]) beacons[mac_addr] = beacon_data done = True sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return beacons
def clearDiscoveredDevices(sock): # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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)
def parse_events(sock, loop_count=100): old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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) myFullList = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i = 0 elif event == bluez.EVT_NUM_COMP_PKTS: i = 0 elif event == bluez.EVT_DISCONN_COMPLETE: i = 0 elif event == LE_META_EVENT: subevent, = struct.unpack("B", pkt[3:4]) pkt = pkt[4:] if subevent == EVT_LE_CONN_COMPLETE: le_handle_connection_complete(pkt) elif subevent == EVT_LE_ADVERTISING_REPORT: num_reports = struct.unpack("B", pkt[0:1])[0] report_pkt_offset = 0 for i in range(0, num_reports): # build the return string Adstring = packed_bdaddr_to_string( pkt[report_pkt_offset + 3:report_pkt_offset + 9]) Adstring += ',' Adstring += returnstringpacket( pkt[report_pkt_offset - 22:report_pkt_offset - 6]) Adstring += ',' Adstring += "{:d}".format( returnnumberpacket(pkt[report_pkt_offset - 6:report_pkt_offset - 4])) Adstring += ',' Adstring += "{:d}".format( returnnumberpacket(pkt[report_pkt_offset - 4:report_pkt_offset - 2])) try: #Adstring += ',' + "%i" % struct.unpack("b", pkt[report_pkt_offset -2:report_pkt_offset -1]) Adstring += ',' + returnstringpacket( pkt[report_pkt_offset - 2:report_pkt_offset - 1]) #The last byte is always 00; we don't really need it #Adstring += ',' + "%i" % struct.unpack("b", pkt[report_pkt_offset -1:report_pkt_offset]) #Adstring += ',' + returnstringpacket(pkt[report_pkt_offset -1:report_pkt_offset]) except: 1 #Prevent duplicates in results if Adstring not in myFullList: myFullList.append(Adstring) sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return myFullList
def save_filter(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) return old_filter
def save_filter(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 ) return old_filter
def handle_events(self, callback=None): if callback is None: callback = self.print_detect self.old_filter = self.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) self.sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt ) while True: pkt = self.sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if DEBUG: print "-------------- ptype: 0x%02x event: 0x%02x plen: 0x%02x" % (ptype, event, plen) if event != LE_META_EVENT: continue subevent, = struct.unpack("B", pkt[3]) pkt = pkt[4:] if DEBUG: print "LE META EVENT subevent: 0x%02x" %(subevent,) if subevent != EVT_LE_ADVERTISING_REPORT: continue if DEBUG: print "advertising report" num_reports, = struct.unpack("B", pkt[0]) report_pkt_offset = 0 if DEBUG: print "Number of reports in the report: 0x%02x" % num_reports for i in range(0, num_reports): if DEBUG: print "report", i report_event_type = struct.unpack("B", pkt[report_pkt_offset + 1])[0] bdaddr_type = struct.unpack("B", pkt[report_pkt_offset + 2])[0] if DEBUG: print "\tadvertising report event type: 0x%02x" % report_event_type if DEBUG: print "\tbdaddr type: 0x%02x" % (bdaddr_type,) bdaddr = packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) if DEBUG: print "\tdevice address: ", bdaddr report_data_length, = struct.unpack("B", pkt[report_pkt_offset + 9]) if DEBUG: print "\tadvertising packet metadata length: ", report_data_length report_event_type_human = ADV_TYPES.get(report_event_type, 'Unknown(%s)' % report_event_type) if DEBUG: print "\ttype: ", report_event_type_human name = None if report_event_type == ADV_SCAN_RSP: local_name_len, = struct.unpack("B", pkt[report_pkt_offset + 11]) # TODO: the line below is probably bugged name = pkt[report_pkt_offset + 12:report_pkt_offset + 12+local_name_len].split('\x00')[0] if DEBUG: print "\tname:", name # each report is 2 (event type, bdaddr type) + 6 (the address) # + 1 (data length field) + data length + 1 (rssi) report_pkt_offset = report_pkt_offset + 10 + report_data_length + 1 rssi, = struct.unpack("b", pkt[report_pkt_offset -1]) if DEBUG: print "\tRSSI:", rssi callback(bdaddr, rssi, report_event_type_human, name)
def parse_events(self,sock, loop_count=100): old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should lush its cache of # previously discovered devices 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 ) done = False results = [] myFullList = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) #print "--------------" if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i =0 elif event == bluez.EVT_NUM_COMP_PKTS: i =0 elif event == bluez.EVT_DISCONN_COMPLETE: i =0 elif event == BtleCollectionPoint.LE_META_EVENT: subevent, = struct.unpack("B", pkt[3]) pkt = pkt[4:] if subevent == BtleCollectionPoint.EVT_LE_CONN_COMPLETE: self.le_handle_connection_complete(pkt) elif subevent == BtleCollectionPoint.EVT_LE_ADVERTISING_REPORT: num_reports = struct.unpack("B", pkt[0])[0] report_pkt_offset = 0 for i in range(0, num_reports): udid=self.returnstringpacket(pkt[report_pkt_offset -22: report_pkt_offset - 6]) beaconMac=self.packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) majorNumber=self.returnnumberpacket(pkt[report_pkt_offset -6: report_pkt_offset - 4]) minorNumber=self.returnnumberpacket(pkt[report_pkt_offset -4: report_pkt_offset - 2]) rawTx="%i" %struct.unpack("b", pkt[report_pkt_offset -2]) tx = int(rawTx) rawRssi="%i" %struct.unpack("b", pkt[report_pkt_offset -1]) rssi = int(rawRssi) #check tx and make sure its a negative. some devices report in positive if tx > 0: tx = -tx #check to see if the detected advertiser is in our major / minor range if majorNumber == self.btleConfig['major'] and minorNumber == self.btleConfig['minor']: detectedClient = DetectedClient('btle',udid=udid,beaconMac=beaconMac,majorNumber=majorNumber,minorNumber=minorNumber,tx=tx,rssi=rssi) myFullList.append(detectedClient) done = True sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return myFullList
def open_dev(bt_device_id): """Open hci device socket.""" socket = bluez.hci_open_dev(bt_device_id) filtr = bluez.hci_filter_new() bluez.hci_filter_all_events(filtr) bluez.hci_filter_set_ptype(filtr, bluez.HCI_EVENT_PKT) socket.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, filtr) return socket
def parse_events(sock, loop_count=100): 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) done = False results = [] myFullList = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) #print "--------------" if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i = 0 elif event == bluez.EVT_NUM_COMP_PKTS: i = 0 elif event == bluez.EVT_DISCONN_COMPLETE: i = 0 elif event == LE_META_EVENT: subevent = pkt[3] pkt = pkt[4:] if subevent == EVT_LE_CONN_COMPLETE: le_handle_connection_complete(pkt) elif subevent == EVT_LE_ADVERTISING_REPORT: num_reports = pkt[0] report_pkt_offset = 0 for i in range(0, num_reports): item = { "UUID": returnstringpacket(pkt[report_pkt_offset - 22:report_pkt_offset - 6]), "MAC": packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]), "MAJOR": "%i" % returnnumberpacket( pkt[report_pkt_offset - 6:report_pkt_offset - 4]), "MINOR": returnnumberpacket(pkt[report_pkt_offset - 4:report_pkt_offset - 2]), "TxPower": int.from_bytes(bytes([pkt[report_pkt_offset - 2]]), byteorder='big', signed=True), "RSSI": int.from_bytes(bytes([pkt[report_pkt_offset - 1]]), byteorder='big', signed=True) } myFullList.append(item) done = True sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return myFullList
def parse_events(sock, loop_count=100): 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) myFullList = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i = 0 elif event == bluez.EVT_NUM_COMP_PKTS: i = 0 elif event == bluez.EVT_DISCONN_COMPLETE: i = 0 elif event == LE_META_EVENT: subevent, = struct.unpack("B", pkt[3:4]) pkt = pkt[4:] if subevent == EVT_LE_CONN_COMPLETE: le_handle_connection_complete(pkt) elif subevent == EVT_LE_ADVERTISING_REPORT: num_reports = struct.unpack("B", pkt[0:1])[0] report_pkt_offset = 0 for i in range(0, num_reports): # build the return string Adstring = packed_bdaddr_to_string( pkt[report_pkt_offset + 3:report_pkt_offset + 9]) rssi, = struct.unpack("b", pkt[-1:]) Adstring += "," + str(rssi) + "," Adstring += str(int(time.time())) #Prevent duplicates in results if Adstring not in myFullList: myFullList.append(Adstring) sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return myFullList #if __name__ == '__main__': # dev_id = 0 # try: # sock = bluez.hci_open_dev(dev_id) # print("ble thread started") # except: # print("error accessing bluetooth device...") # sys.exit(1) # # hci_le_set_scan_parameters(sock) # hci_enable_le_scan(sock) # # while True: # returnedList = parse_events(sock, 10) # print("----------") # for beacon in returnedList: # print(beacon)
def device_inquiry_with_with_rssi(sock, wanted_addr): global results # save current filter old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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 ) duration = 4 max_responses = 255 # 0x9e8b33 is the reserved code for general inquiry of Bluetooth devices cmd_pkt = struct.pack("BBBBB", 0x33, 0x8b, 0x9e, duration, max_responses) bluez.hci_send_cmd(sock, bluez.OGF_LINK_CTL, bluez.OCF_INQUIRY, cmd_pkt) done = False while not done: pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: pkt = pkt[3:] nrsp = struct.unpack("B", pkt[0])[0] for i in range(nrsp): addr = bluez.ba2str( pkt[1+6*i:1+6*i+6] ) rssi = struct.unpack("b", pkt[1+13*nrsp+i])[0] if addr == wanted_addr: results.append( rssi ) # print "*** ", # print "[%s] RSSI: [%d]" % (addr, rssi) elif event == bluez.EVT_INQUIRY_COMPLETE: done = True elif event == bluez.EVT_CMD_STATUS: status, ncmd, opcode = struct.unpack("BBH", pkt[3:7]) if status != 0: print "uh oh..." done = True else: # print "unrecognized packet type 0x%02x" % ptype continue # restore old filter sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) if len(results) > 10: results = results[-10:] return results
def parse_events(sock, loop_count=100): old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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) results = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i = 0 elif event == bluez.EVT_NUM_COMP_PKTS: i = 0 elif event == bluez.EVT_DISCONN_COMPLETE: i = 0 if event == LE_META_EVENT: subevent = to_char(pkt[3]) pkt = pkt[4:] if subevent == EVT_LE_CONN_COMPLETE: le_handle_connection_complete(pkt) elif subevent == EVT_LE_ADVERTISING_REPORT: num_reports = to_char(pkt[0]) report_pkt_offset = 0 for i in range(0, num_reports): b = Beacon() uuid = returnstringpacket( pkt[report_pkt_offset - 22:report_pkt_offset - 6]).upper() b.uuid = '{}-{}-{}-{}-{}'.format(uuid[:8], uuid[8:12], uuid[12:16], uuid[16:20], uuid[20:]) b.major = "%i" % returnnumberpacket( pkt[report_pkt_offset - 6:report_pkt_offset - 4]) b.minor = "%i" % returnnumberpacket( pkt[report_pkt_offset - 4:report_pkt_offset - 2]) b.mac = packed_bdaddr_to_string( pkt[report_pkt_offset + 3:report_pkt_offset + 9]) b.unknown = "%i" % to_char(pkt[report_pkt_offset - 2], signed=True) b.rssi = "%i" % to_char(pkt[report_pkt_offset - 1], signed=True) if b in results: ob = results[results.index(b)] ob.unknown = b.unknown ob.rssi = b.rssi else: results.append(b) sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return results
def Listen(self): try: old_filter = self.sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on blue tooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices flt = bluez.hci_filter_new() bluez.hci_filter_all_events(flt) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) self.sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt ) while True: pkt = self.sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i =0 elif event == bluez.EVT_NUM_COMP_PKTS: i =0 elif event == bluez.EVT_DISCONN_COMPLETE: i =0 elif 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: #print "advertising report" num_reports = struct.unpack("B", pkt[0])[0] report_pkt_offset = 0 for i in range(0, num_reports): if (DEBUG == True): print "-------------" print "\t", "full packet: ", self.printpacket(pkt) print "\t", "MAC address: ", self.packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) # build the return string id = pkt[report_pkt_offset +12: report_pkt_offset +26] if (DEBUG == True): print "\t", "id: ", id if (id == 'MSOT_BLE_Demo:'): # MAC address macAddress = self.packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) # string representation of Water Volume Content (unit-less) floating point value value = pkt[report_pkt_offset + 26: report_pkt_offset + 36] if (DEBUG == True): print "\t", "address=", macAddress, " value=", value if( self.callback != None ): print "calling event handler" self.callback( macAddress, value ) except: self.sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) print "error in BLE Listen loop" sys.exit(1)
def parse_events(sock, loop_count): old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) iBeaconIdString = (255, 76, 0, 2, 21) # Type - xFF (255) # MFGID - x4C x00 (76 0) # Type - Proximity / iBeacon - x02 (2) # Length - x15 (21) custBeaconIdString = (255, 00, 128, 1) # Type - xFF (255) # MFGID - x00 x80 (0 128) # Type - x01 Bio telemetry (1) beaconType = 0x01 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) results = [] myFullList = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if (DEBUG == True): print("------ptype, event, plen--------", ptype, event, plen) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i = 0 elif event == bluez.EVT_NUM_COMP_PKTS: i = 0 elif event == bluez.EVT_DISCONN_COMPLETE: i = 0 elif event == LE_META_EVENT: subevent = pkt[3] pkt = pkt[4:] if len(pkt) < 20: continue parser = nullParser if pkt[11] == beaconType and pkt[14:19]: if struct.unpack("BBBBB", pkt[14:19]) == iBeaconIdString: parser = iBeaconParser elif struct.unpack("BBBB", pkt[14:18]) == custBeaconIdString: parser = custBeaconParser if subevent == EVT_LE_CONN_COMPLETE: le_handle_connection_complete(pkt) elif subevent == EVT_LE_ADVERTISING_REPORT: myFullList.append(parser(pkt)) sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return myFullList
def parse_events(sock, loop_count=100): old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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 ) done = False results = [] myFullList = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack('BBB', pkt[:3]) #print '--------------' if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i =0 elif event == bluez.EVT_NUM_COMP_PKTS: i =0 elif event == bluez.EVT_DISCONN_COMPLETE: i =0 elif 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: #print 'advertising report' num_reports = struct.unpack('B', pkt[0])[0] report_pkt_offset = 0 for i in range(0, num_reports): #print '\tfullpacket: ', printpacket(pkt) device = bledevice() device.udid = returnstringpacket(pkt[report_pkt_offset -22: report_pkt_offset - 6]) device.major = returnnumberpacket(pkt[report_pkt_offset -6: report_pkt_offset - 4]) device.minor = returnnumberpacket(pkt[report_pkt_offset -4: report_pkt_offset - 2]) device.macaddress = packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) device.txpower = struct.unpack('b', pkt[report_pkt_offset -2]) device.rssi = struct.unpack('b', pkt[report_pkt_offset -1]) #print returnstringpacket(pkt[report_pkt_offset -22: report_pkt_offset - 6]) #print returnnumberpacket(pkt[report_pkt_offset -6: report_pkt_offset - 4]) #print returnnumberpacket(pkt[report_pkt_offset -4: report_pkt_offset - 2]) #print packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) #print struct.unpack('b', pkt[report_pkt_offset -2]) #print struct.unpack('b', pkt[report_pkt_offset -1]) myFullList.append(device) done = True sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return myFullList
def parse_events(sock, loop_count=100): old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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 ) done = False results = [] myFullList = [] beacons = {} for i in range(0, loop_count): sock.settimeout(10) try: pkt = sock.recv(255) except (socket.timeout, socket.error, bluez.timeout) as e: print "Connection error: {}".format(e) return {} ptype, event, plen = struct.unpack("BBB", pkt[:3]) #print "--------------" if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i =0 elif event == bluez.EVT_NUM_COMP_PKTS: i =0 elif event == bluez.EVT_DISCONN_COMPLETE: i =0 elif 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: #print "advertising report" num_reports = struct.unpack("B", pkt[0])[0] report_pkt_offset = 0 for i in range(0, num_reports): beacon_data = {} beacon_data['udid'] = returnstringpacket(pkt[report_pkt_offset -22: report_pkt_offset - 6]) beacon_data['major'] = returnstringpacket(pkt[report_pkt_offset -6: report_pkt_offset - 4]) beacon_data['minor'] = returnstringpacket(pkt[report_pkt_offset -4: report_pkt_offset - 2]) mac_addr = packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) beacon_data['txpower'] = struct.unpack("b", pkt[report_pkt_offset -2]) beacon_data['rssi'] = struct.unpack("b", pkt[report_pkt_offset -1]) beacons[mac_addr] = beacon_data done = True sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return beacons
def parse_events(sock, loop_count=100): old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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) message = dict() for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) #print "--------------" if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i = 0 elif event == bluez.EVT_NUM_COMP_PKTS: i = 0 elif event == bluez.EVT_DISCONN_COMPLETE: i = 0 elif 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: #print "advertising report" num_reports = struct.unpack("B", pkt[0])[0] report_pkt_offset = 0 mac = packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) for i in range(0, num_reports): if mac not in message: message[mac] = {'uuid': returnstringpacket(pkt[report_pkt_offset - 22:report_pkt_offset - 6]), 'majorid': returnnumberpacket(pkt[report_pkt_offset - 22:report_pkt_offset - 6]), 'minorid': returnnumberpacket(pkt[report_pkt_offset - 4:report_pkt_offset - 2]), 'calibratedtx': struct.unpack("b", pkt[report_pkt_offset - 2])[0], 'rssi': struct.unpack("b", pkt[report_pkt_offset - 1])[0] } if DEBUG: print "\n-------------" print "\tUDID: ", printpacket(pkt[report_pkt_offset - 22:report_pkt_offset - 6]) print "\tMAJOR: ", printpacket(pkt[report_pkt_offset - 6:report_pkt_offset - 4]) print "\tMINOR: ", printpacket(pkt[report_pkt_offset - 4:report_pkt_offset - 2]) print "\tMAC address: ", packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) # commented out - don't know what this byte is. It's NOT TXPower LOOK AT BLE Specification print "\t(Unknown):", struct.unpack("b", pkt[report_pkt_offset - 2]) print "\tRSSI:", struct.unpack("b", pkt[report_pkt_offset - 1]) sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return message
def device_inquiry_with_with_rssi(sock): # save current filter old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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 ) duration = 4 max_responses = 255 cmd_pkt = struct.pack("BBBBB", 0x33, 0x8b, 0x9e, duration, max_responses) bluez.hci_send_cmd(sock, bluez.OGF_LINK_CTL, bluez.OCF_INQUIRY, cmd_pkt) results = [] done = False while not done: pkt = sock.recv(255) __, event, __ = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: pkt = pkt[3:] nrsp = bluetooth.get_byte(pkt[0]) for i in range(nrsp): addr = bluez.ba2str( pkt[1+6*i:1+6*i+6] ) rssi = bluetooth.byte_to_signed_int( bluetooth.get_byte(pkt[1+13*nrsp+i])) results.append( ( addr, rssi ) ) elif event == bluez.EVT_INQUIRY_COMPLETE: done = True elif event == bluez.EVT_CMD_STATUS: status, __, __ = struct.unpack("BBH", pkt[3:7]) if status != 0: done = True elif event == bluez.EVT_INQUIRY_RESULT: pkt = pkt[3:] nrsp = bluetooth.get_byte(pkt[0]) for i in range(nrsp): addr = bluez.ba2str( pkt[1+6*i:1+6*i+6] ) results.append( ( addr, -1 ) ) # restore old filter sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return results
def parse_le_events(socket): old_filter = socket.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) nfilter = bluez.hci_filter_new() bluez.hci_filter_all_events(nfilter) # HCI_EVENT_PKT = 0x04 bluez.hci_filter_set_ptype(nfilter, bluez.HCI_EVENT_PKT) # socket.setsockopt(level, optname, value) socket.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, nfilter) bluez.hci_send_cmd(socket, bluez.OGF_HOST_CTL, bluez.OCF_READ_INQUIRY_MODE ) #while(true): for i in range(0, 5000): pkt = socket.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) # BLE EVENTS if event == LE_META_EVENT: subevent, = struct.unpack("B", pkt[3]) pkt = pkt[4:] if subevent == EVT_LE_ADVERTISING_REPORT: num_reports = struct.unpack("B", pkt[0])[0] report_pkt_offset = 0 for i in range(0, num_reports): report_event_type = struct.unpack("B", pkt[report_pkt_offset + 1])[0] bdaddr_type = struct.unpack("B", pkt[report_pkt_offset + 2])[0] report_data_length, = struct.unpack("B", pkt[report_pkt_offset + 9]) payload = "{" payload += "\"addr\": \"%s\"" % packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) report_pkt_offset = report_pkt_offset + 10 + report_data_length + 1 rssi, = struct.unpack("b", pkt[report_pkt_offset -1]) payload += ", \"rssi\": %s " % rssi payload += ", \"source\": \"%s\" " % adress payload += ", \"captured\": \"%s\"" % datetime.datetime.now().isoformat() payload += "}" print payload requests.post(url, data=payload, headers=headers) #requests.post(url, data=json.dumps(payload), headers=headers) sleep(1.00) socket.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter )
def process_ble_advertisements(sock, loop_count=100): def packet2string(pkt): return ''.join(map(lambda x: "%02x" % struct.unpack("B", x)[0], pkt)) def packed_bdaddr_to_string(bdaddr_packed): return ':'.join('%02x'%i for i in struct.unpack("<BBBBBB", bdaddr_packed[::-1])) def fmt_major_minor(value): return sum(map(lambda c: struct.unpack("B", c)[0], value[1:]), struct.unpack("B", value[0])[0] * 256.0) old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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 ) reports = {} for i in range(0, loop_count): 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_ADVERTISING_REPORT: num_reports = struct.unpack("B", pkt[0])[0] report_pkt_offset = 0 if not isBean.match(packet2string(pkt[report_pkt_offset-22: report_pkt_offset-6])): continue for i in range(0, num_reports): report = { "udid": packet2string(pkt[report_pkt_offset - 22: report_pkt_offset - 6]), "temp": fmt_major_minor(pkt[report_pkt_offset - 6: report_pkt_offset - 4]), "sg": fmt_major_minor(pkt[report_pkt_offset - 4: report_pkt_offset - 2]) / 1000.0, "addr": packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) } reports[report["addr"]] = report sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return reports
def parse_events(sock, loop_count=100): 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) for i in range(loop_count): pkt = sock.recv(255) parsed_packet = ble.hci_le_parse_response_packet(pkt) if ( "bluetooth_le_subevent_name" in parsed_packet and parsed_packet["bluetooth_le_subevent_name"] == "EVT_LE_ADVERTISING_REPORT" ): for report in parsed_packet["advertising_reports"]: print "Found BLE device:", report["peer_bluetooth_address"] for k, v in report.items(): print "\t%s: %s" % (k, v)
def parse_events(sock, loop_count, source, influx, coll, lastDoc): 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 ) points = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) now = datetime.datetime.now(tzlocal()) nowMs = int(time.time() * 1000) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: print "EVT_INQUIRY_RESULT_WITH_RSSI" elif event == bluez.EVT_NUM_COMP_PKTS: print "EVT_NUM_COMP_PKTS" elif event == bluez.EVT_DISCONN_COMPLETE: print "EVT_DISCONN_COMPLETE" elif event == LE_META_EVENT: subevent, = struct.unpack("B", pkt[3:4]) pkt = pkt[4:] if subevent == EVT_LE_CONN_COMPLETE: pass elif subevent == EVT_LE_ADVERTISING_REPORT: rows = list(evt_le_advertising_report_dump(pkt)) for row in sorted(rows): rssi = row.pop('rssi') if row['addr_type'] == 'Public': # or, someday, if it's a device we know points.append(dict( measurement='rssi', tags={'from': source, 'toAddr': row['addr']}, fields={'value': rssi}, time=nowMs, )) key = (row['addr'], row['evt_type']) if lastDoc.get(key) != row: # should check mongodb here- maybe another # node already wrote this row lastDoc.put(key, row) row = row.copy() row['t'] = now coll.insert(row) influx.write_points(points, time_precision='ms') sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter )
def createSocket(port_id): try: sock = bluez.hci_open_dev(port_id) print "ble thread started on ", port_id blescan.hci_le_set_scan_parameters(sock) blescan.hci_enable_le_scan(sock) 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 ) test.append(sock) except: print "error accessing bluetooth device on ", port_id
def create_socket(self): try: self.socket = bluez.hci_open_dev(self.dev_id) except: raise BluetoothError.BluetoothError("Error al acceder al dispositivo") return # Establece el filtro para recibir todos los eventos flt = bluez.hci_filter_new() bluez.hci_filter_all_events(flt) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) try: # Establece opciones: nivel nombre opciĆ³n valor self.socket.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, flt) except: raise BluetoothError.BluetoothError("Problema al establecer filtro de eventos.") return
def parse_events(sock, loop_count=100): 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) results = {} for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i = 0 elif event == bluez.EVT_NUM_COMP_PKTS: i = 0 elif event == bluez.EVT_DISCONN_COMPLETE: i = 0 elif 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: num_reports = struct.unpack("B", pkt[0])[0] report_pkt_offset = 0 for x in range(0, num_reports): txpower, = struct.unpack("b", pkt[report_pkt_offset - 2]) rssi, = struct.unpack("b", pkt[report_pkt_offset - 1]) results[ ( packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]), returnstringpacket(pkt[report_pkt_offset - 22: report_pkt_offset - 6]), returnnumberpacket(pkt[report_pkt_offset - 6: report_pkt_offset - 4]), returnnumberpacket(pkt[report_pkt_offset - 4: report_pkt_offset - 2]) ) ] = { 'udid': returnstringpacket(pkt[report_pkt_offset - 22: report_pkt_offset - 6]), 'mac': packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]), 'major': returnnumberpacket(pkt[report_pkt_offset - 6: report_pkt_offset - 4]), 'minor': returnnumberpacket(pkt[report_pkt_offset - 4: report_pkt_offset - 2]), 'rssi': rssi, 'txpower': txpower } sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return results
def getBeacons(sock, loop_count=10): old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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 ) done = False results = [] beaconsList = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) #print "--------------" if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i =0 elif event == bluez.EVT_NUM_COMP_PKTS: i =0 elif event == bluez.EVT_DISCONN_COMPLETE: i =0 elif 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: #print "advertising report" num_reports = struct.unpack("B", pkt[0])[0] report_pkt_offset = 0 for i in range(0, num_reports): pass beacon = {'uuid': 'none', 'rssi': 0} beacon['uuid'] = returnstringpacket(pkt[report_pkt_offset -22: report_pkt_offset - 6]) beacon['rssi'] = struct.unpack("b", pkt[report_pkt_offset -1]) beaconsList.append(beacon) done = True sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return beaconsList
def hci_le_set_scan_parameters(sock): SCAN_TYPE = 0x01 INTERVAL = 0x10 WINDOW = 0x10 OWN_TYPE = 0x00 FILTER = 0x00 # all advertisements, not just whitelisted devices cmd_pkt = struct.pack("<BBBBBBB", SCAN_TYPE, 0x0, INTERVAL, 0x0, WINDOW, OWN_TYPE, FILTER) bluez.hci_send_cmd(sock, OGF_LE_CTL, OCF_LE_SET_SCAN_PARAMETERS, cmd_pkt) old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) filtr = bluez.hci_filter_new() bluez.hci_filter_all_events(filtr) bluez.hci_filter_set_ptype(filtr, bluez.HCI_EVENT_PKT) bluez.hci_filter_set_event(filtr, LE_META_EVENT) sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, filtr)
def parse_events(sock, loop_count=100): 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 ) myFullList = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i = 0 elif event == bluez.EVT_NUM_COMP_PKTS: i = 0 elif event == bluez.EVT_DISCONN_COMPLETE: i = 0 elif event == LE_META_EVENT: subevent, = struct.unpack("B", pkt[3:4]) pkt = pkt[4:] if subevent == EVT_LE_CONN_COMPLETE: le_handle_connection_complete(pkt) elif subevent == EVT_LE_ADVERTISING_REPORT: num_reports = struct.unpack("B", pkt[0:1])[0] report_pkt_offset = 0 for i in range(0, num_reports): # build the return string Adstring = packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) Adstring += ',' + returnstringpacket(pkt[report_pkt_offset -22: report_pkt_offset - 6]) #Adstring += ',' + "%i" % returnnumberpacket(pkt[report_pkt_offset -6: report_pkt_offset - 4]) Adstring += ',' + returnstringpacket(pkt[report_pkt_offset -6: report_pkt_offset - 4]) #Adstring += ',' + "%i" % returnnumberpacket(pkt[report_pkt_offset -4: report_pkt_offset - 2]) Adstring += ',' + returnstringpacket(pkt[report_pkt_offset -4: report_pkt_offset - 2]) try: #Adstring += ',' + "%i" % struct.unpack("b", pkt[report_pkt_offset -2:report_pkt_offset -1]) Adstring += ',' + returnstringpacket(pkt[report_pkt_offset -2:report_pkt_offset -1]) #The last byte is always 00; we don't really need it #Adstring += ',' + "%i" % struct.unpack("b", pkt[report_pkt_offset -1:report_pkt_offset]) #Adstring += ',' + returnstringpacket(pkt[report_pkt_offset -1:report_pkt_offset]) except: 1 #Prevent duplicates in results if Adstring not in myFullList: myFullList.append(Adstring) sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return myFullList
def __init__(self, callback=None): try: self.sock = sock = bluez.hci_open_dev() except: raise OSError("error accessing bluetooth device...") self.callback = callback or self._print_data # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices self.flt = bluez.hci_filter_new() bluez.hci_filter_all_events(self.flt) bluez.hci_filter_set_ptype(self.flt, bluez.HCI_EVENT_PKT) sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, self.flt) self.parser_thread = Thread(target=self.parse_events) self.parser_thread.daemon = True self.parser_thread.start()
def parse_events(sock, loop_count=100): 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 ) done = False results = [] myFullList = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i =0 elif event == bluez.EVT_NUM_COMP_PKTS: i =0 elif event == bluez.EVT_DISCONN_COMPLETE: i =0 elif 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: #print "advertising report" num_reports = struct.unpack("B", pkt[0])[0] report_pkt_offset = 0 for i in range(0, num_reports): # build the return list Advalues = [] Advalues.append(packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9])) Advalues.append(returnstringpacket(pkt[report_pkt_offset -22: report_pkt_offset - 6])) Advalues.append(returnnumberpacket(pkt[report_pkt_offset -6: report_pkt_offset - 4])) Advalues.append(returnnumberpacket(pkt[report_pkt_offset -4: report_pkt_offset - 2])) Advalues.append(struct.unpack("b", pkt[report_pkt_offset -2])) Advalues.append(struct.unpack("b", pkt[report_pkt_offset -1])) myFullList.append(Advalues) done = True sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return myFullList
def set_bt_name(payload, src_hci, src, dst): # Create raw HCI sock to set our BT name raw_sock = bt.hci_open_dev(bt.hci_devid(src_hci)) flt = bt.hci_filter_new() bt.hci_filter_all_ptypes(flt) bt.hci_filter_all_events(flt) raw_sock.setsockopt(bt.SOL_HCI, bt.HCI_FILTER, flt) # Send raw HCI command to our controller to change the BT name (first 3 bytes are padding for alignment) raw_sock.sendall(binascii.unhexlify('01130cf8cccccc') + payload.ljust(MAX_BT_NAME, b'\x00')) raw_sock.close() #time.sleep(1) time.sleep(0.1) # Connect to BNEP to "refresh" the name (does auth) bnep = bluetooth.BluetoothSocket(bluetooth.L2CAP) bnep.bind((src, 0)) bnep.connect((dst, BNEP_PSM)) bnep.close() # Close ACL connection os.system('hcitool dc %s' % (dst,))
def parse_events(sock, loop_count=100): 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) results = [] for i in range(0, loop_count): pkt = sock.recv(255) event, subevent, something = struct.unpack ("BBB", pkt[1:4]) if subevent != 42: continue for p in split_packets (pkt): results.append (extract (p)) sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return results
def parse_events(sock, loop_count=100): old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices 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 ) results = [] myFullList = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) #print "--------------" if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i =0 elif event == bluez.EVT_NUM_COMP_PKTS: i =0 elif event == bluez.EVT_DISCONN_COMPLETE: i =0 elif 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: num_reports = struct.unpack("B", pkt[0])[0] report_pkt_offset = 0 for i in range(0, num_reports): mac_address = packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) rssi = int("%i" % struct.unpack("b", pkt[report_pkt_offset -1])) myFullList.append(mac_address +"|" +str(rssi)) done = True sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return myFullList
def createSocket(port_id): try: sock = bluez.hci_open_dev(port_id) print "ble thread started on ", port_id blescan.hci_le_set_scan_parameters(sock) blescan.hci_enable_le_scan(sock) old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # print "Bluez hci filter:", bluez.HCI_FILTER # print "Old filter", old_filter, "end" flt = bluez.hci_filter_new() # print "New filter", flt, "end" # bluez.hci_filter_set_event(bluez.SCAN_RSP) bluez.hci_filter_all_events(flt) # print "All events", flt, "end" # printpacket(flt) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt ) socketList.append(sock) except: print "error accessing bluetooth device on ", port_id
def get_BT_addr_around(sock, loop_count=100): old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices new_filter = bluez.hci_filter_new() bluez.hci_filter_all_events(new_filter) bluez.hci_filter_set_ptype(new_filter, bluez.HCI_EVENT_PKT) sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, new_filter ) done = False results = [] BLE_addr_List = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i =0 elif event == bluez.EVT_NUM_COMP_PKTS: i =0 elif event == bluez.EVT_DISCONN_COMPLETE: i =0 elif 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: num_reports = struct.unpack("B", pkt[0])[0] report_pkt_offset = 0 for i in range(0, num_reports): BLE_addr = packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) if BLE_addr not in BLE_addr_List: BLE_addr_List.append(BLE_addr) done = True sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return BLE_addr_List