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 _check_command_support(self, octet, mask): """ Checks if a certain command is supported by the Bluetooth sensor. @param octet The octet of the command. @param mask The bitmask of the command. Both as defined in the Bluetooth specification v4.0 pp. 447 (pdf 693). """ # save current filter old_filter = self.sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) # Setup socket filter to receive only events related to the # read_inquiry_mode command flt = bluez.hci_filter_new() opcode = bluez.cmd_opcode_pack(0x04, 0x0002) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) bluez.hci_filter_set_event(flt, bluez.EVT_CMD_COMPLETE); bluez.hci_filter_set_opcode(flt, opcode) self.sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, flt) # Send the Read Local Supported Commands command bluez.hci_send_cmd(self.sock, 0x04, 0x0002) pkt = self.sock.recv(65) status = struct.unpack("65B", pkt) status = status[6:] # restore old filter self.sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) # Check if the requested bit is set. if len(status) >= octet+1: return status[octet+1] & mask == mask return False
def write_inquiry_mode(sock, mode): """returns 0 on success, -1 on failure""" # save current filter old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # Setup socket filter to receive only events related to the # write_inquiry_mode command flt = bluez.hci_filter_new() opcode = bluez.cmd_opcode_pack(bluez.OGF_HOST_CTL, bluez.OCF_WRITE_INQUIRY_MODE) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) bluez.hci_filter_set_event(flt, bluez.EVT_CMD_COMPLETE); bluez.hci_filter_set_opcode(flt, opcode) sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt ) # send the command! bluez.hci_send_cmd(sock, bluez.OGF_HOST_CTL, bluez.OCF_WRITE_INQUIRY_MODE, struct.pack("B", mode) ) pkt = sock.recv(255) status = struct.unpack("xxxxxxB", pkt)[0] # restore old filter sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) if status != 0: return -1 return 0
def read_inquiry_scan_activity(sock): """returns the current inquiry scan interval and window, or -1 on failure""" # save current filter old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # Setup socket filter to receive only events related to the # read_inquiry_mode command flt = bluez.hci_filter_new() opcode = bluez.cmd_opcode_pack(bluez.OGF_HOST_CTL, bluez.OCF_READ_INQ_ACTIVITY) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) bluez.hci_filter_set_event(flt, bluez.EVT_CMD_COMPLETE); bluez.hci_filter_set_opcode(flt, opcode) sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt ) # first read the current inquiry mode. bluez.hci_send_cmd(sock, bluez.OGF_HOST_CTL, bluez.OCF_READ_INQ_ACTIVITY ) pkt = sock.recv(255) status,interval,window = struct.unpack("!xxxxxxBHH", pkt) interval = bluez.btohs(interval) interval = (interval >> 8) | ( (interval & 0xFF) << 8 ) window = (window >> 8) | ( (window & 0xFF) << 8 ) if status != 0: mode = -1 # restore old filter sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return interval, window
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 find_local_bdaddr(self): dev_id = 0 hci_sock = _bt.hci_open_dev(dev_id) old_filter = hci_sock.getsockopt( _bt.SOL_HCI, _bt.HCI_FILTER, 14) flt = _bt.hci_filter_new() opcode = _bt.cmd_opcode_pack(_bt.OGF_INFO_PARAM, _bt.OCF_READ_BD_ADDR) _bt.hci_filter_set_ptype(flt, _bt.HCI_EVENT_PKT) _bt.hci_filter_set_event(flt, _bt.EVT_CMD_COMPLETE); _bt.hci_filter_set_opcode(flt, opcode) hci_sock.setsockopt(_bt.SOL_HCI, _bt.HCI_FILTER, flt) _bt.hci_send_cmd(hci_sock, _bt.OGF_INFO_PARAM, _bt.OCF_READ_BD_ADDR) pkt = hci_sock.recv(255) status,raw_bdaddr = struct.unpack("xxxxxxB6s", pkt) assert status == 0 t = [ "%X" % ord(b) for b in raw_bdaddr ] t.reverse() bdaddr = ":".join(t) # restore old filter hci_sock.setsockopt( _bt.SOL_HCI, _bt.HCI_FILTER, old_filter ) return bdaddr
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 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 _write_inquiry_tx_power(self, power): """ Returns 0 on success, error status code or -1 on failure. """ if not self._check_command_support(18, 0b10): return -1 # save current filter old_filter = self.sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) # Setup socket filter to receive only events related to the # read_inquiry_mode command flt = bluez.hci_filter_new() opcode = bluez.cmd_opcode_pack(bluez.OGF_HOST_CTL, 0x0059) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) bluez.hci_filter_set_event(flt, bluez.EVT_CMD_COMPLETE); bluez.hci_filter_set_opcode(flt, opcode) self.sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, flt) # first read the current inquiry mode. bluez.hci_send_cmd(self.sock, bluez.OGF_HOST_CTL, 0x0059, struct.pack("b", power)) pkt = self.sock.recv(255) status = struct.unpack("xxxxxxB", pkt)[0] # restore old filter self.sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return status
def read_inquiry_mode(sock): """returns the current mode, or -1 on failure""" # save current filter old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # Setup socket filter to receive only events related to the # read_inquiry_mode command flt = bluez.hci_filter_new() opcode = bluez.cmd_opcode_pack(bluez.OGF_HOST_CTL, bluez.OCF_READ_INQUIRY_MODE) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) bluez.hci_filter_set_event(flt, bluez.EVT_CMD_COMPLETE); bluez.hci_filter_set_opcode(flt, opcode) sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt ) # first read the current inquiry mode. bluez.hci_send_cmd(sock, bluez.OGF_HOST_CTL, bluez.OCF_READ_INQUIRY_MODE ) pkt = sock.recv(255) status,mode = struct.unpack("xxxxxxBB", pkt) if status != 0: mode = -1 # restore old filter sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return mode
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 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 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 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 ) 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 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 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 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 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, 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 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 get_localAdapter(self, deviceNr): "Return name and address of a local adapter" name = None address = None sock = bt.hci_open_dev(deviceNr) if sock.getsockid() >= 0: sock.settimeout(3) # Save original filter orig_filter = sock.getsockopt(bt.SOL_HCI, bt.HCI_FILTER, 14) # Create new filter new_filter = orig_filter new_filter = bt.hci_filter_new() bt.hci_filter_set_ptype(new_filter, bt.HCI_EVENT_PKT) bt.hci_filter_set_event(new_filter, bt.EVT_CMD_COMPLETE) # CMD Read local name opcode = bt.cmd_opcode_pack(bt.OGF_HOST_CTL, bt.OCF_READ_LOCAL_NAME) bt.hci_filter_set_opcode(new_filter, opcode) sock.setsockopt(bt.SOL_HCI, bt.HCI_FILTER, new_filter) bt.hci_send_cmd(sock, bt.OGF_HOST_CTL, bt.OCF_READ_LOCAL_NAME) try: data = sock.recv(255) name = data[7:] name = name[:name.find('\0')] except bluetooth._bluetooth.timeout: print 'bluetooth timeout during local device scan for name' # CMD Read local address opcode = bt.cmd_opcode_pack(bt.OGF_INFO_PARAM, bt.OCF_READ_BD_ADDR) bt.hci_filter_set_opcode(new_filter, opcode) sock.setsockopt(bt.SOL_HCI, bt.HCI_FILTER, new_filter) bt.hci_send_cmd(sock, bt.OGF_INFO_PARAM, bt.OCF_READ_BD_ADDR) try: data = sock.recv(255) status, raw_bdaddr = struct.unpack('xxxxxxB6s', data) address = ['%02X' % ord(b) for b in raw_bdaddr] address.reverse() address = ':'.join(address) except bluetooth._bluetooth.timeout: print 'bluetooth timeout during local device scan for address' # Restore original filter sock.setsockopt(bt.SOL_HCI, bt.HCI_FILTER, orig_filter) sock.close() return name, address
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]) 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): #isBeacon = returnstringpacket(pkt[report_pkt_offset -22]) isBeacon2 = returnstringpacket(pkt[report_pkt_offset - 21]) isBeacon3 = returnstringpacket(pkt[report_pkt_offset - 20]) if (DEBUG == True and isBeacon2 == "aa" and isBeacon3 == "fc"): print "-------------" print "\tfullpacket: ", printpacket(pkt) print "\tMAC address: ", packed_bdaddr_to_string( pkt[report_pkt_offset + 3:report_pkt_offset + 9]) print "\tACCEL: ", returnstringpacket( pkt[report_pkt_offset + 24:report_pkt_offset + 30]) print "....." t1 = int( returnstringpacket(pkt[report_pkt_offset + 25:report_pkt_offset + 26]), 16) t2 = int( returnstringpacket(pkt[report_pkt_offset + 27:report_pkt_offset + 28]), 16) t3 = int( returnstringpacket(pkt[report_pkt_offset + 29:report_pkt_offset + 30]), 16) print "\tA1:", t1 print "\tA2:", t2 print "\tA3:", t3 intru = 0 if (t1 > 1 and t1 < 254): intru = 1 if (t2 > 32 or t2 < 30): intru = 1 if (t3 > 0 and t3 < 252): intru = 1 if (intru == 1): print "!!!!!!!!!! INTRUSION !!!!!!!!!!" trame = returnstringpacket( pkt[report_pkt_offset + 18:report_pkt_offset + 37]) print "\tTRAME:", trame print "....." temp = 0 temp2 = 0 temp3 = 0 temp = returnstringpacket( pkt[report_pkt_offset + 30:report_pkt_offset + 34]) temp2 = int(temp, 16) temp3 = int("00FFFFFF", 16) print "\tTEMP: ", (temp2 & temp3) / 100 txpower, = struct.unpack("b", pkt[report_pkt_offset - 3]) print "\tBATT:", txpower print "\tPOSITION: ", returnstringpacket( pkt[report_pkt_offset - 2:report_pkt_offset - 1]) rssi, = struct.unpack("b", pkt[report_pkt_offset - 1]) print "\tRSSI:", rssi done = True sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return myFullList
def parse_events(sock, loop_count=100, cnt=0, scanner_id=1): 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 = [] clr = 0 counter = cnt 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', bytes([pkt[3]])) #subevent, = struct.unpack('B',pkt[3]) #PYTHON 2 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", bytes([pkt[0]]))[0] report_pkt_offset = 0 #print(returnstringpacket(pkt[report_pkt_offset -27: report_pkt_offset - 25])) for i in range(0, num_reports): # build the return string if iBeacon packet received if (returnstringpacket( pkt[report_pkt_offset - 22:report_pkt_offset - 6]) == "12345678901234567890123456789012" or returnstringpacket( pkt[report_pkt_offset - 22:report_pkt_offset - 6]) == "01234567890123456789012345678901"): Adstring = str(scanner_id) Adstring += ";" #Counter if counter > 9999: Adstring += str(clr) counter = 0 else: Adstring += str(counter) Adstring += ";" #Mac Adstring += packed_bdaddr_to_string( pkt[report_pkt_offset + 3:report_pkt_offset + 9]) Adstring += ";" #Major Adstring += "%i" % returnnumberpacket( pkt[report_pkt_offset - 6:report_pkt_offset - 4]) Adstring += ";" #Minor #Adstring += "%i" % returnnumberpacket(pkt[report_pkt_offset -4: report_pkt_offset - 2]) #Adstring += ";" #Rssi Adstring += "%i" % struct.unpack( "b", bytes([pkt[report_pkt_offset - 1]])) Adstring += ";" results.append(Adstring) print(Adstring) #print Adstring counter += 1 done = True return counter, results sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter)
def scan(): beacon_found = False for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT]: signal.signal(sig, handler) # Setup logging: FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' if "logOutFilename" in globals() : logging.basicConfig(format=FORMAT,filename=logOutFilename,level=logLevel) else: logging.basicConfig(format=FORMAT,level=logLevel) # Reset Bluetooth interface, hci0 os.system("sudo hciconfig hci0 down") os.system("sudo hciconfig hci0 up") # Make sure device is up interface = subprocess.Popen(["sudo hciconfig"], stdout=subprocess.PIPE, shell=True) (output, err) = interface.communicate() # Get the output from bytes to text (UTF-8): output = output.decode("utf-8") # Check return of hciconfig to make sure it's up: # (This validation will only make sense if the hci0 is the only hci available.) if "RUNNING" in output: logging.debug('Ok hci0 interface Up n running !') else: logging.critical('Error : hci0 interface not Running. Do you have a BLE device connected to hci0 ? Check with hciconfig !') sys.exit(1) # Define the hci number. In this case, hci0: devId = 0 # Try to open connection with hci0: try: sock = bluez.hci_open_dev(devId) logging.debug('Connect to bluetooth device %i',devId) except: logging.critical('Unable to connect to bluetooth device...') sys.exit(1) # Gets the value of the given socket option, which can contain 14 characteres # at maximum: old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) hci_toggle_le_scan(sock, 0x01) # Start scanning! print("Scanning...") call_count = 0 testbed_counter = 0 while True: old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) # Creates new filter: 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) # Receive data from the socket (255 bytes at maximum): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) # Verifies the type of the event received by the socket: if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI or event == bluez.EVT_NUM_COMP_PKTS or event == bluez.EVT_DISCONN_COMPLETE: i = 0 elif event == LE_META_EVENT: subevent = pkt[3] #logging.info(pkt) 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): macAddressSeen = packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) if "0c:f3:ee:04" in macAddressSeen: #logging.debug('is beacon!') #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]) #logging.debug(type(pkt)) #logging.debug(pkt) #logging.debug(pkt[4:].decode("utf-8")) datetime = time.strftime("%Y-%m-%d %H:%M:%S") logging.debug('%s, %s, %d', datetime, macAddressSeen, testbed_counter + 1) distance = -1 testbed_counter = testbed_counter + 1 try: upsert_by_macaddress({"cellId":CELL_ID, "dateTime":datetime, "distanceFromCell":distance, "macAddress":macAddressSeen}) except firebase_admin.db.ApiCallError: logging.error("Error while inserting the beacon into Firebase.") # if testbed_counter >= TESTBED_SAMPLES: # logging.debug('Test finished.') # break sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) time.sleep(10 / 1000) logging.debug('------------------------------')
def device_inquiry_with_with_rssi(sock, show_name=False, show_extra_info=False, color=True, ret_table=False): global LOADING_HANDLER # 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 = 1 max_responses = 255 cmd_pkt = struct.pack("BBBBB", 0x33, 0x8b, 0x9e, duration, max_responses) # TODO Optimize code for performance # update the global device name dictionary before sending hci cmd(which changes mode) headers = ["Name", "MAC Address", "RSSI"] data = [] results = [] if show_extra_info or show_name: devices = bluetooth.discover_devices(lookup_names=True, lookup_class=True) if show_name: update_dict = {i[0]: i[1] for i in devices} NAME_DICT.update(update_dict) if show_extra_info: update_dict = {i[0]: i[2] for i in devices} CLASS_DICT.update(update_dict) headers.extend(["Major Dev Class", "Minor Dev Class", "Services"]) populate_info_dict() 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 = bluetooth.get_byte(pkt[0]) for i in range(nrsp): # get human readable addr 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])) # retrieve device name, or assign address as name try: name = NAME_DICT[addr] except: name = addr results.append((addr, rssi, name)) if color: data.append([name, addr, rssi_to_colour_str(rssi)]) else: data.append([name, addr, rssi]) if show_extra_info: extra_info = get_device_extra(addr) # extend last data list with extra info data[-1].extend(extra_info) 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 = 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, "UNK")) print("[%s] (no RRSI)" % addr) else: logging.debug("unrecognized packet type 0x%02x" % ptype) logging.debug("event %s", event) # restore old filter sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) # if ordered to return a table by analyze_all, ignore other sequence if ret_table: if len(results) < 1: return ((None, headers)) return ((data, headers)) else: # print all the data at once since blessings clears the screen just before if len(results) >= 1: # terminate concurrent loading handler if bool(LOADING_HANDLER): LOADING_HANDLER.terminate() show_header("BLUETOOTH") print(tabulate(data, headers=headers, disable_numparse=True)) else: # LOADING_HANDLER = spin(before="Searching", # after="\nNo devices found in nearby range") LOADING_HANDLER.terminate() LOADING_HANDLER = spin(before="No BT devices in nearby range") return results
def parse_events(sock, loop_count=100,macfilter=None): 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]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: i =0 elif event == ADV_IND: 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:] offset = 0 mac = packed_bdaddr_to_string(pkt[offset + 3:offset + 9]) if plen < 40: break print "\t len:"+str(plen)+" fullpacket: ", printpacket(pkt) if subevent == EVT_LE_CONN_COMPLETE: le_handle_connection_complete(pkt) elif subevent == EVT_LE_ADVERTISING_REPORT: #print "advertising report" num_reports,adv_type = struct.unpack("BB", pkt[0:2]) if adv_type == ADV_SCAN_RSP: print "ignoring ADV_SCAN_RSP ("+hex(adv_type)+") Advertising" elif adv_type == ADV_SCAN_IND : print "ignoring ADV_SCAN_IND ("+hex(adv_type)+") Advertising" # elif adv_type == ADV_IND : # print "ignoring ADV_IND ("+hex(adv_type)+") Advertising" else: print " ("+hex(adv_type)+") Advertising" if macfilter or macfilter == mac: m_offset = offset +10 s = mac + " - "+str(datetime.now()) bat, = struct.unpack("B",pkt[m_offset+13]) x,y,z = struct.unpack(">hhh",pkt[m_offset+14:m_offset+20]) xf = float(x)/256.0 yf = float(y)/256.0 zf = float(z)/256.0 f = "%0.2f" s += " x:"+f%xf+" y:"+f%yf+" z:"+f%zf r,t = calcAngles(xf,yf,zf) s += " r:"+f%r+" t:"+f%t print s else: for i in range(0, num_reports): if (DEBUG == True): print "-------------" #print "\tfullpacket: ", printpacket(pkt) print "\tUDID: ", printpacket(pkt[offset -22: offset - 6]) print "\tMAJOR: ", printpacket(pkt[offset -6: offset - 4]) print "\tMINOR: ", printpacket(pkt[offset -4: offset - 2]) print "\tMAC address: ", packed_bdaddr_to_string(pkt[offset + 3:offset + 9]) # commented out - don't know what this byte is. It's NOT TXPower txpower, = struct.unpack("b", pkt[offset -2]) print "\t(Unknown):", txpower rssi, = struct.unpack("b", pkt[offset -1]) print "\tRSSI:", rssi # build the return string Adstring = packed_bdaddr_to_string(pkt[offset + 3:offset + 9]) Adstring += "," Adstring += returnstringpacket(pkt[offset -22: offset - 6]) Adstring += "," Adstring += "%i" % returnnumberpacket(pkt[offset -2]) Adstring += "," Adstring += "%i" % returnnumberpacket(pkt[offset -6: offset - 4]) Adstring += "," Adstring += "%i" % returnnumberpacket(pkt[offset -4: offset - 2]) Adstring += "," Adstring += "%i" % struct.unpack("b", pkt[offset -2]) Adstring += "," Adstring += "%i" % struct.unpack("b", pkt[offset -1]) # Adstring += "=("+str(len(pkt))+")\t" # Adstring += returnstringpacket(pkt) #print "\tAdstring=", Adstring myFullList.append(Adstring) done = True sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return myFullList
def parse_events(sock, queue, loop_count=100): logger.info('Started parsing BLE events...') 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 filter = bluez.hci_filter_new() bluez.hci_filter_all_events(filter) bluez.hci_filter_set_ptype(filter, bluez.HCI_EVENT_PKT) sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, filter) for i in range(0, loop_count): if not is_running: break 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_offset = 0 for i in range(0, num_reports): # print 'Raw: ', return_string_from_packet(pkt) report_event_type = struct.unpack("B", pkt[report_offset + 1])[0] mac = packed_bdaddr_to_string(pkt[report_offset + 3:report_offset + 9]) report_data_length = struct.unpack("B", pkt[report_offset + 9])[0] pkt = pkt[report_offset + 10:] if report_event_type == ADV_IND: # print "\tADV_IND" adv_scan_rsp[mac] = pkt[:report_data_length] continue elif report_event_type == ADV_DIRECT_IND: # print "\tADV_DIRECT_IND" adv_scan_rsp[mac] = pkt[:report_data_length] continue elif report_event_type == ADV_SCAN_IND: # print "\tADV_SCAN_IND" adv_scan_rsp[mac] = pkt[:report_data_length] continue # elif report_event_type == ADV_NONCONN_IND: # print "\tADV_NONCONN_IND" elif report_event_type == ADV_SCAN_RSP: # print "\tADV_SCAN_RSP" previous_pkt = adv_scan_rsp.get(mac, None) if previous_pkt is not None: del adv_scan_rsp[mac] pkt = previous_pkt + pkt[report_offset:] # else: # print "\tUnknown or reserved event type" try: manufacturer = return_string_from_packet( pkt[report_offset + 5:7]) if manufacturer.lower( ) == 'c6a0': # Ignore mac address if Gimbal mac = '' ble_type = return_string_from_packet( pkt[report_offset + 7:9]) # Get UUID if report_data_length > report_offset + 25 and \ manufacturer.lower() == '4c00' and ble_type.lower() == '0215': uuid = return_string_from_packet( pkt[report_offset + 9:report_offset + 25]) elif report_data_length > report_offset + 31 and \ manufacturer.lower() == 'c6a0': uuid = return_string_from_packet( pkt[report_offset + 22:report_offset + 31]) else: uuid = '' # Get Data if uuid == '' and report_data_length > report_offset + 9: data = return_string_from_packet( pkt[report_offset + 9:-1]) elif report_data_length > report_offset + 25 and \ manufacturer.lower() != 'c6a0': data = return_string_from_packet( pkt[report_offset + 25:-1]) else: data = '' # major = return_number_from_packet(pkt[report_offset + 25: report_offset + 27]) # minor = return_number_from_packet(pkt[report_offset + 27: report_offset + 29]) # power = struct.unpack('b', pkt[report_offset + 29])[0] if report_data_length > report_offset + 30: battery = struct.unpack('b', pkt[report_offset + 30])[0] else: battery = 0 rssi = struct.unpack('b', pkt[-1])[0] now = int(time.time() * 1000) + server_time_offset previous_item = queue.queue[-1] if not queue.empty( ) else {} # dict() if uuid != previous_item.get('beacon_uid', None) or \ (uuid == previous_item.get('beacon_uid', None) and (now - previous_item.get('timestamp')) >= 1000): logger.debug('Raw: %s', return_string_from_packet(pkt)) logger.info( 'Parsed: %s,%s,%s,%s,%i,%i' % (mac, manufacturer, uuid, data, battery, rssi)) print 'Parsed: %s,%s,%s,%s,%i,%i' % ( mac, manufacturer, uuid, data, battery, rssi) sighting = {} # dict() sighting['timestamp'] = now sighting['beacon_mac'] = mac.replace(':', '') sighting['beacon_uid'] = uuid sighting['beacon_battery'] = battery sighting['rssi'] = rssi queue.put(sighting) # else: # logger.info('Skipping packet as a similar one happened less than 1 second ago.') except Exception as ex: logger.exception( 'Failed to parse beacon advertisement package:') report_offset = report_offset + 10 + report_data_length + 1 sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) logger.info('Finished parsing events.')
def parse_le_advertising_events(sock, mac_addr=None, packet_length=None, handler=None, debug=False): """ Parse and report LE advertisements. This is a blocking call, an infinite loop is started and the given handler will be called each time a new LE advertisement packet is detected and corresponds to the given filters. .. note:: The :func:`.start_le_advertising` function must be called before calling this function. :param sock: A bluetooth HCI socket (retrieved using the ``hci_open_dev`` PyBluez function). :param mac_addr: list of filtered mac address representations (uppercase, with ':' separators). If not specified, the LE advertisement of any device will be reported. Example: mac_addr=('00:2A:5F:FF:25:11', 'DA:FF:12:33:66:12') :type mac_addr: ``list`` of ``string`` :param packet_length: Filter a specific length of LE advertisement packet. :type packet_length: ``int`` :param handler: Handler that will be called each time a LE advertisement packet is available (in accordance with the ``mac_addr`` and ``packet_length`` filters). :type handler: ``callable`` taking 4 parameters: mac (``str``), adv_type (``int``), data (``bytes``) and rssi (``int``) :param debug: Enable debug prints. :type debug: ``bool`` """ if not debug and handler is None: raise ValueError("You must either enable debug or give a handler !") old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) flt = bluez.hci_filter_new() bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) # bluez.hci_filter_all_events(flt) bluez.hci_filter_set_event(flt, LE_META_EVENT) sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, flt) # print("socket filter set to ptype=HCI_EVENT_PKT event=LE_META_EVENT") # print("Listening ...") try: while True: pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event != LE_META_EVENT: # Should never occur because we filtered with this type of event print("Not a LE_META_EVENT !") continue sub_event, = struct.unpack("B", pkt[3:4]) if sub_event != EVT_LE_ADVERTISING_REPORT: if debug: print("Not a EVT_LE_ADVERTISING_REPORT !") continue pkt = pkt[4:] adv_type = struct.unpack("b", pkt[1:2])[0] mac_addr_str = bluez.ba2str(pkt[3:9]) if packet_length and plen != packet_length: # ignore this packet if debug: print( "packet with non-matching length: mac=%s adv_type=%02x plen=%s" % (mac_addr_str, adv_type, plen)) print(raw_packet_to_str(pkt)) continue data = pkt[9:-1] rssi = struct.unpack("b", pkt[-2:-1])[0] if mac_addr and mac_addr_str not in mac_addr: if debug: print( "packet with non-matching mac %s adv_type=%02x data=%s RSSI=%s" % (mac_addr_str, adv_type, raw_packet_to_str(data), rssi)) continue if debug: print( "LE advertisement: mac=%s adv_type=%02x data=%s RSSI=%d" % (mac_addr_str, adv_type, raw_packet_to_str(data), rssi)) if handler is not None: try: handler(mac_addr_str, adv_type, data, rssi) except Exception as e: print( 'Exception when calling handler with a BLE advertising event: %r' % (e, )) except KeyboardInterrupt: print("\nRestore previous socket filter") sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) raise
def device_inquiry(sock, cycle_period, hash_addrs, log_out, device_queue): # 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 filtr = bluez.hci_filter_new() bluez.hci_filter_all_events(filtr) bluez.hci_filter_set_ptype(filtr, bluez.HCI_EVENT_PKT) sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, filtr) max_responses = 255 cmd_pkt = struct.pack("BBBBB", 0x33, 0x8b, 0x9e, int(cycle_period / 1.25), max_responses) bluez.hci_send_cmd(sock, bluez.OGF_LINK_CTL, bluez.OCF_INQUIRY, cmd_pkt) #While still scanning done = False while not done: sock.settimeout(5) try: pkt = sock.recv(255) except: break ptype, event, plen = struct.unpack("BBB", pkt[:3]) #Enquiry result with rssi 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]) if (hash_addrs): addr = hashlib.sha224(addr.replace(":", "")).hexdigest() rssi = bluetooth.byte_to_signed_int( bluetooth.get_byte(pkt[1 + 13 * nrsp + i])) register_device(addr, rssi, log_out, device_queue) #Enquiry result without rssi 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]) if (hash_addrs): addr = hashlib.sha224(addr.replace(":", "")).hexdigest() register_device(addr, None, log_out, device_queue) #On finish elif event == bluez.EVT_INQUIRY_COMPLETE: done = True #Status update? elif event == bluez.EVT_CMD_STATUS: status, ncmd, opcode = struct.unpack("BBH", pkt[3:7]) if status != 0: done = True # restore old filter sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return
# Connect to hci adapter try: sock = bluez.hci_open_dev(hciId) logging.debug('Connected to bluetooth adapter hci%i', hciId) except: logging.critical('Unable to connect to bluetooth device...') sys.exit(1) # Enable LE scan hci_toggle_le_scan(sock, 0x01) # Infinite loop to listen socket while True: 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) 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] for i in range(0, num_reports): macAdressSeen = packed_bdaddr_to_string(pkt[3:9]) ts = int(time.time()) # time of 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 = [] done = False if True: pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: pkt = pkt[3:] curr_time = current_milli_time() 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 (int(rssi) >= -45 and addr not in purchased): if addr in first_time: if curr_time - first_time[addr] >= 4000 and curr_time - prev_time[addr] <= 10000: purchased.append(addr) print("Purchased ticket: [%s], final ping!" % addr) with SocketIO('52.229.115.195', 80, LoggingNamespace) as socketIO: socketIO.emit('beacon-purchased', addr); socketIO.wait(seconds=1) else: if curr_time - prev_time[addr] > 10000: print("Purchasing ticket: [%s] (reset), ping!" % addr) first_time[addr] = curr_time prev_time[addr] = curr_time with SocketIO('52.229.115.195', 80, LoggingNamespace) as socketIO: socketIO.emit('beacon-ping', addr); socketIO.wait(seconds=1) else: print("Purchasing ticket: [%s], ping!" % addr) prev_time[addr] = curr_time with SocketIO('52.229.115.195', 80, LoggingNamespace) as socketIO: socketIO.emit('beacon-ping', addr); socketIO.wait(seconds=1) else: print("Purchasing ticket: [%s], ping!" % addr) first_time[addr] = curr_time prev_time[addr] = curr_time with SocketIO('52.229.115.195', 80, LoggingNamespace) as socketIO: socketIO.emit('beacon-ping', addr); socketIO.wait(seconds=1) # 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) 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]) packetOffset = 0 dataString = packetToString(packet) """ If the bluetooth device is an beacon then show the beacon. """ #print (dataString) if dataString[34:50] == '0303aafe1516aafe' or '0303AAFE1116AAFE': """ Selects parts of the bluetooth packets. """ broadcastType = dataString[50:52] if broadcastType == '00': type = "Eddystone UID" namespace = dataString[54:74].upper() instance = dataString[74:86].upper() resultsArray = [{ "type": type, "namespace": namespace, "instance": instance }] return resultsArray elif broadcastType == '10': type = "Eddystone URL" urlprefix = dataString[54:56] if urlprefix == '00': prefix = 'http://www.' elif urlprefix == '01': prefix = 'https://www.' elif urlprefix == '02': prefix = 'http://' elif urlprefix == '03': prefix = 'https://' hexUrl = dataString[56:][:-2] url = prefix + hexUrl.decode("hex") rssi, = struct.unpack("b", packet[packetOffset - 1]) resultsArray = [{"type": type, "url": url}] return resultsArray elif broadcastType == '20': type = "Eddystone TLM" resultsArray = [{"type": type}] return resultsArray elif broadcastType == '30': type = "Eddystone EID" resultsArray = [{"type": type}] return resultsArray elif broadcastType == '40': type = "Eddystone RESERVED" resultsArray = [{"type": type}] return resultsArray if dataString[38:46] == '4c000215': """ Selects parts of the bluetooth packets. """ type = "iBeacon" uuid = dataString[46:54] + "-" + dataString[ 54:58] + "-" + dataString[58:62] + "-" + dataString[ 62:66] + "-" + dataString[66:78] major = dataString[78:82] minor = dataString[82:86] majorVal = int("".join(major.split()[::-1]), 16) minorVal = int("".join(minor.split()[::-1]), 16) """ Organises Mac Address to display properly """ scrambledAddress = dataString[14:26] fixStructure = iter("".join( reversed([ scrambledAddress[i:i + 2] for i in range(0, len(scrambledAddress), 2) ]))) macAddress = ':'.join(a + b for a, b in zip(fixStructure, fixStructure)) if sys.version_info[0] == 3: rssi, = struct.unpack("b", bytes([packet[packetOffset - 1]])) else: rssi, = struct.unpack("b", packet[packetOffset - 1]) resultsArray = [{ "type": type, "uuid": uuid, "major": majorVal, "minor": minorVal, "rssi": rssi, "macAddress": macAddress }] return resultsArray return results
def parse_events(sock, callback, 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 = {} ret = {} 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): company = returnhexpacket(pkt[report_pkt_offset + 15: report_pkt_offset + 17]) if (DEBUG == True): printpacket(pkt) nm = returnstringpacket(pkt[report_pkt_offset+33:report_pkt_offset+33+8]) if (company == "3301" or nm=='C481AF21' or nm=='C2E4EB1B'): nameLength = int(pkt[report_pkt_offset + 32]) name = returnstringpacket(pkt[report_pkt_offset + 33:report_pkt_offset + (33+nameLength-1)]) ret['make'] = company ret['model'] = pkt[report_pkt_offset+17] ret['name'] = name ret["udid"] = returnhexpacket(pkt[report_pkt_offset + 22: report_pkt_offset - 6]) ret["mac"] = returnhexpacket(pkt[report_pkt_offset + 3: report_pkt_offset + 9]) if (ret['model'] == 27 ): # Purple ret["temperature"] = float(returnnumberpacket(pkt[report_pkt_offset + 23:report_pkt_offset + 25]))/10 ret["humidity"] = float(returnnumberpacket(pkt[report_pkt_offset + 25:report_pkt_offset + 27]))/10 ret["pressure"] = float(returnnumberpacket(pkt[report_pkt_offset + 27:report_pkt_offset + 29]))/10 else: #if (ret['model'] == 23 ): # Blue ret["temperature"] = float(returnnumberpacket(pkt[report_pkt_offset + 23:report_pkt_offset + 25]))/10 ret["humidity"] = float(returnnumberpacket(pkt[report_pkt_offset + 25:report_pkt_offset + 27]))/10 ret["dewpoint"] = float(returnnumberpacket(pkt[report_pkt_offset + 27:report_pkt_offset + 29]))/10 ret["battery"] = float(float(returnnumberpacket(pkt[report_pkt_offset + 18:report_pkt_offset + 19]) / float(25500) ) * 100) ret["data"] = pkt callback(ret) sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return results
def parse_events(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 = [] myFullList = [] for i in range(0, loop_count): try: sock.settimeout(5) pkt = sock.recv(255) except: timeout_raised=1 pkt = "" if (LOGLEVEL >= 4): sys.stdout = open(logfile, "a") print str(datetime.datetime.now()) + " [Python] <WARNING> Timeout..." sys.stdout = sys.__stdout__ break 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): if (LOGLEVEL >= 7): sys.stdout = open(logfile, "a") print str(datetime.datetime.now()) + " [Python] -----------------------------------------\n" + hexdump( pkt ) print str(datetime.datetime.now()) + " [Python] MAC 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 str(datetime.datetime.now()) + " [Python] RSSI:", rssi sys.stdout = sys.__stdout__ # 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 += "%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]) myFullList.append(Adstring) rssi, = struct.unpack("b", pkt[report_pkt_offset -1]) conn = sqlite3.connect('/tmp/ble_scanner.dat') c = conn.cursor() sql = "REPLACE INTO `ble_scanner` (MAC,rssi,Timestamp) VALUES ('" + packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) + "','" + "-" + str(abs(rssi)) + "',CURRENT_TIMESTAMP);" if (LOGLEVEL >= 6): sys.stdout = open(logfile, "a") print str(datetime.datetime.now()) + " [Python] <INFO> SQLite:", sql sys.stdout = sys.__stdout__ try: # Execute the SQLite command c.execute(sql) # Commit changes in the database conn.commit() conn.close() except: # Rollback in case there is any error conn.rollback() conn.close() done = True sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return myFullList
def scan(self, timeout=10, UUID=None): old_filter = self.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) self.sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, flt) self.sock.settimeout(timeout) beacons = [] timeStart = time.time() while (time.time() - timeStart) < timeout: try: pkt = self.sock.recv(255) except bluez.timeout: return None ptype, event, plen = struct.unpack('BBB', pkt[:3]) if event == LE_META_EVENT: subevent = pkt[3] pkt = pkt[4:] if subevent == EVT_LE_CONN_COMPLETE: le_handle_connection_complete(pkt) newBLE = {} # Parse the trame newBLE['MACADDR'] = ':'.join(('%012X' % int.from_bytes(pkt[3: 9], byteorder='big', signed=False))[i:i+2] for i in range(0, 12, 2)) newBLE['UUID'] = self.returnstringpacket(pkt[-22: -6]) newBLE['MAJOR'] = self.returnnumberpacket(pkt[-6: -4]) newBLE['MINOR'] = self.returnnumberpacket(pkt[-4: -2]) newBLE['TXPOWER'] = pkt[-2] newBLE['RSSI'] = pkt[-1] addThisBLE = True # If this beacon just scanned has not already been scanned for beacon in beacons: if beacon['MACADDR'] == newBLE['MACADDR']: addThisBLE = False # If this beacon is an Estimote (default UUID) if UUID is not None and not newBLE['UUID'] == UUID: addThisBLE = False # If so, we add this beacon if addThisBLE: beacons.append(newBLE) self.sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return beacons
def parse_events(sock, loop_count=10): global sensorBeaconList 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 xrange(0, loop_count): sock.settimeout(10) try: pkt = sock.recv(255) except socket.timeout: print "connection timed out!" pass except socket.error as e: print "connection erred out: {}!".format(e) pass except: print "time out!" pass # Raw avertise packet data from Bluez scan # Packet Type (1byte) + BT Event ID (1byte) + Packet Length (1byte) + # BLE sub-Event ID (1byte) + Number of Advertising reports (1byte) + # Report type ID (1byte) + BT Address Type (1byte) + BT Address (6byte) + # Data Length (1byte) + Data ((Data Length)byte) + RSSI (1byte) # # Packet Type = 0x04 # BT Event ID = EVT_LE_META_EVENT = 0x3E (BLE events) # (All LE commands result in a metaevent, specified by BLE sub-Event ID) # BLE sub-Event ID = { # EVT_LE_CONN_COMPLETE = 0x01 # EVT_LE_ADVERTISING_REPORT = 0x02 # EVT_LE_CONN_UPDATE_COMPLETE = 0x03 # EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE = 0x04 # EVT_LE_LTK_REQUEST = 0x05 # } # Number of Advertising reports = 0x01 (normally) # Report type ID = { # LE_ADV_IND = 0x00 # LE_ADV_DIRECT_IND = 0x01 # LE_ADV_SCAN_IND = 0x02 # LE_ADV_NONCONN_IND = 0x03 # LE_ADV_SCAN_RSP = 0x04 # } # BT Address Type = { # LE_PUBLIC_ADDRESS = 0x00 # LE_RANDOM_ADDRESS = 0x01 # } # Data Length = 0x00 - 0x1F # * Maximum Data Length of an advertising packet = 0x1F parsed_packet = 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': if (DEBUG == True): for report in parsed_packet["advertising_reports"]: print "----------------------------------------------------" print packet_as_hex_string(pkt, flag_with_spacing = True, flag_force_capitalize = True) print "Found BLE device:", report['peer_bluetooth_address'] for k, v in report.items(): print "\t%s: %s" % (k, v) for report in parsed_packet["advertising_reports"]: if (sensorCheck_IM(report)): sensorBeacon = SensorBeacon(report["peer_bluetooth_address_s"], report["payload_binary"]) index = sensorInList(sensorBeacon, sensorBeaconList) if (DEBUG == True): print (" -- sensor data ---") sensorBeacon.debugPrint() lock = threading.Lock() lock.acquire() if (index != -1): # BT Address found in sensorBeaconList if (sensorBeacon.checkDiffSeqNum(index)): data = sensorBeacon.upload() sensorBeacon.update(index) else : # new SensorBeacon sensorBeaconList.append(sensorBeacon) data = sensorBeacon.upload() lock.release() else: pass else: pass sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return sensorBeaconList
def parse_events(sock, loop_count): 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 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) TempTrackIdString = (109, 112, 116, 114) # Type - x6D (109) # MFGID - x7A x74 (112 116) # Type - x72 (114) 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 struct.unpack("BBBBB", pkt[14:19]) == iBeaconIdString: parser = iBeaconParser elif struct.unpack("BBBB", pkt[14:18]) == custBeaconIdString: parser = custBeaconParser elif struct.unpack("BBBB", pkt[14:18]) == TempTrackIdString: parser = TempTrackParser 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 __parseEvents(self, sensor_id, num_events, tx_list): self.__old_filter = self.__socket.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # @UndefinedVariable # perform a device inquiry on bluetooth device # 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() # @UndefinedVariable bluez.hci_filter_all_events(flt) # @UndefinedVariable bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) # @UndefinedVariable self.__socket.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt ) # @UndefinedVariable done = False results = [] udid = "" mac_address = "" major = 0 minor = 0 rssi = "" txPower = "" packet_cnt = 0 while (not done): # for i in range(0, num_events): pkt = self.__socket.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) #print "--------------" if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: # @UndefinedVariable i =0 elif event == bluez.EVT_NUM_COMP_PKTS: # @UndefinedVariable i =0 elif event == bluez.EVT_DISCONN_COMPLETE: # @UndefinedVariable i =0 elif event == self.LE_META_EVENT: # subevent, = struct.unpack("B", pkt[3]) subevent, = struct.unpack("B", pkt[3:4]) pkt = pkt[4:] if subevent == self.EVT_LE_CONN_COMPLETE: le_handle_connection_complete(pkt) # @UndefinedVariable elif subevent == self.EVT_LE_ADVERTISING_REPORT: num_reports = struct.unpack("B", pkt[0:1])[0] report_pkt_offset = 0 for i in range(0, num_reports): # self.__printpacket(pkt) rptPktLen = int(len(pkt) / num_reports) advertType = struct.unpack("B", pkt[1:2])[0] mac_address = MacAddress.unformat_mac_address(self.__packed_bdaddr_to_string(pkt[report_pkt_offset + 3:report_pkt_offset + 9])) udid = self.__returnstringpacket(pkt[rptPktLen -22: rptPktLen - 6]) major = self.__returnnumberpacket(pkt[rptPktLen -6: rptPktLen - 4]) minor = self.__returnnumberpacket(pkt[rptPktLen -4: rptPktLen - 2]) if (self.__bleInList(tx_list=tx_list, mac_address=mac_address, uuid=udid, major=major, minor=minor)): rssi = struct.unpack("b", pkt[rptPktLen -1:rptPktLen]) txPower = struct.unpack("b", pkt[rptPktLen -2:rptPktLen -1]) #TODO: Not getting transmit power back if (isinstance(txPower, tuple)): txPower = txPower[0] if ((txPower == 0) or (txPower == -1)): if (advertType == self.ADV_SCAN_RSP): txPower = self.__TX_Power_AdvScanResp else: txPower = self.__TX_Power_AdvIndirect self.__packet_number += 1 blePkt = BLE_Packet( mac_address, udid, major, minor, rssi, txPower, advertType, self.__packet_number, sensor_id) results.append(blePkt) report_pkt_offset += rptPktLen packet_cnt += 1 if (packet_cnt >= num_events): done = True done = True else: #Unknown even type # print("Uknown ble event: ", str(event)) pass self.__socket.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, self.__old_filter ) # @UndefinedVariable return results
def parse_events(sock, loop_count=100, hostScript="", macid=""): 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): if (DEBUG == True): Reqstring = hostScript Reqdict = {} Reqdict['ddatetime'] = "2014-09-27T23:55:00" Reqdict['ddatetime'] = time.strftime( '%Y-%m-%d %H:%M:%S') Reqdict[ 'raspMac'] = macid # "b8:27:eb:50:53:a7" # magnus RPI MAC, kolon escaped med %3A Reqdict['beaconMac'] = packed_bdaddr_to_string( pkt[report_pkt_offset + 3:report_pkt_offset + 9]) rssi, = struct.unpack("b", pkt[report_pkt_offset - 1]) Reqdict['rcvStrength'] = rssi r = requests.get(Reqstring, params=Reqdict) print(r.url) 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 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 "\tAdstring=", Adstring myFullList.append(Adstring) 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 myFullList = [] distances = [] 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): 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 uuid = returnstringpacket(pkt[report_pkt_offset - 22: report_pkt_offset - 6]) if uuid in beaconList: # 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 += "%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 += "," txPower = struct.unpack("b", pkt[report_pkt_offset - 2]) # Adstring += "%i" % struct.unpack("b", pkt[report_pkt_offset -2]) Adstring += "%i" % txPower Adstring += "," rssi = struct.unpack("b", pkt[report_pkt_offset - 1]) # Adstring += "%i" % struct.unpack("b", pkt[report_pkt_offset -1]) Adstring += "%i," % rssi dist = calculateDistance(rssi[0], txPower[0]) distances.append(dist) Adstring += "[%.2fm]," % dist Adstring += "[%.2fm]" % calculateRoughDistance(rssi[0], txPower[0]) # print "\tAdstring=", Adstring # if Adstring not in myFullList: myFullList.append(Adstring) done = True if len(distances)>2: distances.remove(max(distances)) distances.remove(min(distances)) avg = sum(distances) / float(len(distances)) print "avg:",avg cmd = 'DIST '+str(NODE_ID)+' 1 9 '+str(avg) print "cmd:",cmd try: netcat('localhost',8888,cmd) except socket.error as e: print "Socket Error" if avg < 0.3: print "***** blink *****" # led.flash_led(led.LED_PIN,3,0.2) 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].to_bytes(1, 'little')) 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].to_bytes(1,'little'))[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 + 1: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].to_bytes(1,'little')) print("\t(Unknown):", txpower) rssi, = struct.unpack("b", pkt[report_pkt_offset -1].to_bytes(1,'little')) print("\tRSSI:", rssi) # 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 += "%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].to_bytes(1,'little')) Adstring += "," Adstring += "%i" % struct.unpack("b", pkt[report_pkt_offset -1].to_bytes(1,'little')) #print "\tAdstring=", Adstring myFullList.append(Adstring) 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 = [] for i in range(0, loop_count): pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) print "-------------- ptype: 0x%02x event: 0x%02x plen: 0x%02x" % ( ptype, event, plen) 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 "Inquiry: [%s] RSSI: [%d]" % (addr, rssi) elif event == bluez.EVT_NUM_COMP_PKTS: print "num completed packets" pkt = pkt[3:] num_connection_handles = struct.unpack("B", pkt[0])[0] pkt = pkt[1:] print "handles:", num_connection_handles for i in range(0, num_connection_handles): handle, = struct.unpack("H", pkt[0:2]) completed_packets, = struct.unpack("H", pkt[2:4]) print "\thandle: 0x%04x completed packets: 0x%04x" % ( handle, completed_packets) pkt = pkt[4:] elif event == bluez.EVT_DISCONN_COMPLETE: pkt = pkt[3:] status, handle, reason = struct.unpack("<BHB", pkt) print "Disconnected, status: 0x%02x handle: 0x%04x reason: 0x%02x" % ( status, handle, reason) elif event == LE_META_EVENT: subevent, = struct.unpack("B", pkt[3]) pkt = pkt[4:] print "LE META EVENT subevent: 0x%02x" % (subevent, ) if subevent == EVT_LE_CONN_COMPLETE: print "connection 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 print "Number of reports in the report: 0x%02x" % num_reports for i in range(0, num_reports): 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] print "\tadvertising report event type: 0x%02x" % report_event_type print "\tbdaddr type: 0x%02x" % (bdaddr_type, ) print "\tdevice address: ", packed_bdaddr_to_string( pkt[report_pkt_offset + 3:report_pkt_offset + 9]) report_data_length, = struct.unpack( "B", pkt[report_pkt_offset + 9]) print "\tadvertising packet metadata length: ", report_data_length if report_event_type == ADV_IND: print "\tADV_IND" elif report_event_type == ADV_DIRECT_IND: print "\tADV_DIRECT_IND" elif report_event_type == ADV_SCAN_IND: print "\tADV_SCAN_IND" elif report_event_type == ADV_NONCONN_IND: print "\tADV_NONCONN_IND" elif report_event_type == ADV_SCAN_RSP: print "\tADV_SCAN_RSP" local_name_len, = struct.unpack( "B", pkt[report_pkt_offset + 11]) name = pkt[report_pkt_offset + 12:report_pkt_offset + 12 + local_name_len] print "\tname:", name else: print "\tUnknown or reserved event type" # 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]) print "\tRSSI:", rssi #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 "Meta: [%s] RSSI: [%d]" % (addr, rssi) elif subevent == EVT_LE_CONN_UPDATE_COMPLETE: print "connection updated" printpacket(pkt) elif subevent == EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE: print "read remote used features complete" else: print "unknown LE_META_EVENT subevent" elif event == bluez.EVT_INQUIRY_COMPLETE: print "device inquiry complete" 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 RSSI)" % (addr, ) elif event == bluez.EVT_CMD_COMPLETE: ncmd, opcode = struct.unpack("BB", pkt[4:6]) print "command complete: cmd: 0x%02x opcode: 0x%02x" % (ncmd, opcode) else: print "unknown packet, event 0x%02x " % event print "unrecognized packet type 0x%02x" % ptype print "event ", event sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter)
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]) 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: if sys.version_info[0] == 3: subevent = pkt[3] else: subevent = struct.unpack("B", pkt[3])[0] pkt = pkt[4:] if subevent == EVT_LE_CONN_COMPLETE: le_handle_connection_complete(pkt) elif subevent == EVT_LE_ADVERTISING_REPORT: if sys.version_info[0] == 3: num_reports = pkt[0] else: num_reports = struct.unpack("B", pkt[0])[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 - 26:report_pkt_offset - 22]) 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]) # TO DO: make last bytes conversion compatible to Python 3 #Adstring += "," #Adstring += "%i" % struct.unpack("b", pkt[report_pkt_offset -2]) #Adstring += "," #Adstring += "%i" % struct.unpack("b", pkt[report_pkt_offset -1]) myFullList.append(Adstring) done = True sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return myFullList
def parse_events(sock, mqtt_client, pi_id, loop_count=100): old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) #print "pi_id = " + pi_id # 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): #?? uuid = returnstringpacket(pkt[report_pkt_offset -22: report_pkt_offset - 6]) #print "\n" + "rsting: " + returnstringpacket(pkt) #print "\n" + "uudid: " + uuid #mqtt_client.publish("paxton10/location/" + uuid) #if uuid == "010300010000d60b00120201060303a4fe0afffbce": #if uuid.__contains__("010300010000d60b00120201060303a4fe0afffbce"): if "010300010000d60b00120201060303a4fe0afffbce" in returnstringpacket(pkt): #if "0103000100" in uuid: print "\n" + uuid print "\n" + returnstringpacket(pkt) 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 "\tAdstring=", Adstring myFullList.append(Adstring) mqtt_client.publish("paxton10/location/" + str(pi_id), payload=Adstring, qos=1, retain=False) else: print "****\n" done = True sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return myFullList
def device_inquiry_with_with_rssi(sock): #check for rssi value #CREDIT: code.google.com # 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 = [] pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) done = False xil = 0 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 == target_address: xil = xil + 1 print " [%s] [%d]" % (addr, xil) results.append((addr, rssi)) if xil > 0: break #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 else: print "unrecognized packet type 0x%02x" % ptype # restore old filter sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) if len(results) == 0: return 0 else: return 100 + results[0][1]
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): company = returnstringpacket( pkt[report_pkt_offset + 15:report_pkt_offset + 17]) print "===============================================================================================================" if (DEBUG == True): print "\tfullpacket: ", printpacket(pkt) if (company == "3301"): print "\tCompany: ", company udid = returnstringpacket( pkt[report_pkt_offset + 22:report_pkt_offset - 6]) print "\tUDID: ", udid myFullList["udid"] = udid 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]) mac = returnstringpacket(pkt[report_pkt_offset + 3:report_pkt_offset + 9]) myFullList["mac"] = mac print "\tMAC Address string: ", returnstringpacket( pkt[report_pkt_offset + 3:report_pkt_offset + 9]) tempString = returnstringpacket( pkt[report_pkt_offset + 23:report_pkt_offset + 25]) print "\tTemp: ", tempString temp = float( returnnumberpacket( pkt[report_pkt_offset + 23:report_pkt_offset + 25])) / 10 print "\tTemp: ", temp myFullList["temp"] = temp print "\tHumidity: ", printpacket( pkt[report_pkt_offset + 25:report_pkt_offset + 27]) humidity = float( returnnumberpacket( pkt[report_pkt_offset + 25:report_pkt_offset + 27])) / 10 print "\tHumidity: ", humidity myFullList["humidity"] = humidity dewpoint = float( returnnumberpacket( pkt[report_pkt_offset + 27:report_pkt_offset + 29])) / 10 print "\tDewpoint: ", dewpoint myFullList["dewpoint"] = dewpoint nameLength = int( returnstringpacket(pkt[report_pkt_offset + 32])) print "\tNameLength: ", nameLength name = returnstringpacket( pkt[report_pkt_offset + 33:report_pkt_offset + (33 + nameLength - 1)]) print "\tName: %s %d " % (name.decode("hex"), nameLength) myFullList["name"] = name.decode("hex") print "\tBattery: ", printpacket( pkt[report_pkt_offset + 18:report_pkt_offset + 19]) battery = float( float( returnnumberpacket(pkt[report_pkt_offset + 18]) / float(25500)) * 100) print "\tBattery: ", battery myFullList["battery"] = battery done = True else: print "\tNon blue maestro packet found" sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) return myFullList
def parse_events(sock, loop_count): 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 iBeaconIdString = (255, 76, 0, 2, 21) # Type - xFF (255) # MFGID - x4C x00 (76 0) # Type - Proximity / iBeacon - x02 (2) # Length - x15 (21) 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 (DEBUG == True): print("------ptype, event, plen-------- \n", 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, = struct.unpack("B", pkt[3]) subevent = pkt[3] pkt = pkt[4:] isiBeacon = False if (pkt[14:19]): isiBeacon = True if struct.unpack("BBBBB", pkt[14:19]) == iBeaconIdString else False if (DEBUG == True): print("----- isIbeacon -----", isiBeacon) if subevent == EVT_LE_CONN_COMPLETE: le_handle_connection_complete(pkt) elif ((subevent == EVT_LE_ADVERTISING_REPORT) and isiBeacon): #print "advertising report" num_reports = pkt[0] report_pkt_offset = 0 for i in range(0, num_reports): #pktbs = bitstring.BitStream(pkt) Previous way to get two last values from pkt #pktbs.pos += len(pktbs) - (2 * 8) #txpower = pktbs.read('int:8') #rssi = pktbs.read('int:8') if (DEBUG == True): print("-------------") print("fullpacket:", end = ' ') print(printpacket(pkt)) print("UDID:", end = ' ') print(printpacket(pkt[report_pkt_offset -22: report_pkt_offset - 6])) print("TTMFGID:", end = ' ') print(printpacket(pkt[report_pkt_offset -27: report_pkt_offset - 22])) print("MAJOR:", end = ' ') print(printpacket(pkt[report_pkt_offset -6: report_pkt_offset - 4])) print("MINOR:", end = ' ') print(printpacket(pkt[report_pkt_offset -4: report_pkt_offset - 2])) print("MAC address:", end = ' ') print(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: report_pkt_offset -1])[0] rssi = struct.unpack("b", pkt[report_pkt_offset -1: report_pkt_offset -2:-1])[0] print ('TXPOWER:', txpower) print("RSSI:", rssi) # 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 += "%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: report_pkt_offset -1])[0] Adstring += "," Adstring += "%i" % struct.unpack("b", pkt[report_pkt_offset -1: report_pkt_offset -2:-1])[0] if (DEBUG == True): print("Adstring =", Adstring) myFullList.append(Adstring) 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) results = [] for i in range(0, loop_count): packet = sock.recv(255) # ptype, event, plen = struct.unpack("BBB", packet[:3]) # packetOffset = 0 dataString = packetToString(packet) """ If the bluetooth device is an beacon then show the beacon. """ # print(dataString) # print(dataString[32:40]) # if dataString[34:50] == '0303aafe1516aafe' or '0303AAFE1116AAFE': # """ # Selects parts of the bluetooth packets. # """ # broadcastType = dataString[50:52] # if broadcastType == '00' : # type = "Eddystone UID" # namespace = dataString[54:74].upper() # instance = dataString[74:86].upper() # resultsArray = [ # {"type": type, "namespace": namespace, "instance": instance}] # return resultsArray # elif broadcastType == '10': # type = "Eddystone URL" # urlprefix = dataString[54:56] # if urlprefix == '00': # prefix = 'http://www.' # elif urlprefix == '01': # prefix = 'https://www.' # elif urlprefix == '02': # prefix = 'http://' # elif urlprefix == '03': # prefix = 'https://' # hexUrl = dataString[56:][:-2] # url = prefix + hexUrl.decode("hex") # rssi, = struct.unpack("b", packet[packetOffset -1]) # resultsArray = [{"type": type, "url": url}] # return resultsArray # elif broadcastType == '20': # type = "Eddystone TLM" # resultsArray = [{"type": type}] # return resultsArray # elif broadcastType == '30': # type = "Eddystone EID" # resultsArray = [{"type": type}] # return resultsArray # elif broadcastType == '40': # type = "Eddystone RESERVED" # resultsArray = [{"type": type}] # return resultsArray # if dataString[38:46] == '4c000215': if dataString[32:40] == '4c000215': # return packet """ Selects parts of the bluetooth packets. """ type = "iBeacon" # uuid = dataString[46:54] + "-" + dataString[54:58] + "-" + dataString[58:62] + "-" + dataString[62:66] + "-" + dataString[66:78] uuid = dataString[40:48] + "-" + dataString[ 48:52] + "-" + dataString[52:56] + "-" + dataString[ 56:60] + "-" + dataString[60:72] # print(uuid) major = dataString[72:76] minor = dataString[76:80] # print(major, minor) majorVal = int("".join(major.split()[::-1]), 16) minorVal = int("".join(minor.split()[::-1]), 16) # print(majorVal, minorVal) """ Organises Mac Address to display properly """ scrambledAddress = dataString[14:26] fixStructure = iter("".join( reversed([ scrambledAddress[i:i + 2] for i in range(0, len(scrambledAddress), 2) ]))) macAddress = ':'.join(a + b for a, b in zip(fixStructure, fixStructure)) rssi, = struct.unpack("b", packet[len(packet) - 1:]) # print(packet[len(packet)-1:]) txp, = struct.unpack("b", packet[len(packet) - 2:len(packet) - 1]) # print(packet[len(packet)-3:len(packet)-2], txp) # print("TX Power:", txp) resultsArray = [{ "type": type, "uuid": uuid, "major": majorVal, "minor": minorVal, "rssi": rssi, "macAddress": macAddress }] return resultsArray return results
def parse_events(sock, loop_count=100): old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) result = False 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): # build the return string #printpacket(pkt[report_pkt_offset -6: report_pkt_offset - 4]) #print(printpacket(pkt[report_pkt_offset -6: report_pkt_offset - 4])) if (returnnumberpacket( pkt[report_pkt_offset - 6:report_pkt_offset - 4]) == 4660): print("major : %d" % returnnumberpacket( pkt[report_pkt_offset - 6:report_pkt_offset - 4])) rssi, = struct.unpack("b", pkt[report_pkt_offset - 1]) #print "\tRSSI:", rssi numr = int(rssi) #print(numr) if (numr > (-40)): result = True 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 "\tAdstring=", Adstring myFullList.append(Adstring) done = True sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, old_filter) #return myFullList #return result if (result == True): return result