def get_local_bdaddr(self): id = self.statusbar.get_context_id("device_info") try: hci_sock = _bt.hci_open_dev() 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 = ["%02X" % 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) self.statusbar.push(id, "Local bt device address: %s" % (bdaddr)) self.DEV_BLUE = True except: self.statusbar.push(id, "No local bt device found!")
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 write_inquiry_scan_activity(sock, interval, window): """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_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) # send the command! bluez.hci_send_cmd(sock, bluez.OGF_HOST_CTL, bluez.OCF_WRITE_INQ_ACTIVITY, struct.pack("HH", interval, window)) 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_local_bdaddr(): hci_sock = _bt.hci_open_dev(0) 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" % get_byte(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 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 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 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_local_bdaddr(): try: hci_sock = _bt.hci_open_dev(0) 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 = ["%02X" % get_byte(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] except _bt.error as e: raise BluetoothError(*e.args)
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 find_devices (self, lookup_names=True, duration=8, flush_cache=True): """ find_devices (lookup_names=True, service_name=None, duration=8, flush_cache=True) Call this method to initiate the device discovery process lookup_names - set to True if you want to lookup the user-friendly names for each device found. service_name - set to the name of a service you're looking for. only devices with a service of this name will be returned in device_discovered () NOT YET IMPLEMENTED ADVANCED PARAMETERS: (don't change these unless you know what you're doing) duration - the number of 1.2 second units to spend searching for bluetooth devices. If lookup_names is True, then the inquiry process can take a lot longer. flush_cache - return devices discovered in previous inquiries """ if self.is_inquiring: raise BluetoothError ("Already inquiring!") self.lookup_names = lookup_names self.sock = _gethcisock () flt = _bt.hci_filter_new () _bt.hci_filter_all_events (flt) _bt.hci_filter_set_ptype (flt, _bt.HCI_EVENT_PKT) try: self.sock.setsockopt (_bt.SOL_HCI, _bt.HCI_FILTER, flt) except: raise BluetoothError ("problem with local bluetooth device.") # send the inquiry command duration = 4 max_responses = 255 cmd_pkt = struct.pack ("BBBBB", 0x33, 0x8b, 0x9e, \ duration, max_responses) self.pre_inquiry () try: _bt.hci_send_cmd (self.sock, _bt.OGF_LINK_CTL, \ _bt.OCF_INQUIRY, cmd_pkt) except: raise BluetoothError ("problem with local bluetooth device.") self.is_inquiring = True self.names_to_find = {} self.names_found = {}
def find_devices (self, lookup_names=True, duration=8, flush_cache=True): """ find_devices (lookup_names=True, service_name=None, duration=8, flush_cache=True) Call this method to initiate the device discovery process lookup_names - set to True if you want to lookup the user-friendly names for each device found. service_name - set to the name of a service you're looking for. only devices with a service of this name will be returned in device_discovered () NOT YET IMPLEMENTED ADVANCED PARAMETERS: (don't change these unless you know what you're doing) duration - the number of 1.2 second units to spend searching for bluetooth devices. If lookup_names is True, then the inquiry process can take a lot longer. flush_cache - return devices discovered in previous inquiries """ if self.is_inquiring: raise BluetoothError ("Already inquiring!") self.lookup_names = lookup_names self.sock = _gethcisock (self.device_id) flt = _bt.hci_filter_new () _bt.hci_filter_all_events (flt) _bt.hci_filter_set_ptype (flt, _bt.HCI_EVENT_PKT) try: self.sock.setsockopt (_bt.SOL_HCI, _bt.HCI_FILTER, flt) except: 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) self.pre_inquiry () try: _bt.hci_send_cmd (self.sock, _bt.OGF_LINK_CTL, \ _bt.OCF_INQUIRY, cmd_pkt) except: raise BluetoothError ("problem with local bluetooth device.") self.is_inquiring = True self.names_to_find = {} self.names_found = {}
def device_inquiry_with_with_rssi(sock): # save current filter old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices flt = bluez.hci_filter_new() bluez.hci_filter_all_events(flt) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, flt) duration = 4 max_responses = 255 cmd_pkt = struct.pack("BBBBB", 0x33, 0x8B, 0x9E, duration, max_responses) bluez.hci_send_cmd(sock, bluez.OGF_LINK_CTL, bluez.OCF_INQUIRY, cmd_pkt) results = [] done = False while not done: pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: pkt = pkt[3:] 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) 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 device_inquiry_with_with_rssi(sock): # save current filter old_filter = sock.getsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices flt = bluez.hci_filter_new() bluez.hci_filter_all_events(flt) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, flt) duration = 4 max_responses = 255 cmd_pkt = struct.pack("BBBBB", 0x33, 0x8b, 0x9e, duration, max_responses) bluez.hci_send_cmd(sock, bluez.OGF_LINK_CTL, bluez.OCF_INQUIRY, cmd_pkt) results = [] done = False while not done: pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: pkt = pkt[3:] 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) 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 _send_next_name_req(self): assert len(self.names_to_find) > 0 address = self.names_to_find.keys()[0] device_class, psrm, pspm, clockoff = self.names_to_find[address] bdaddr = _bt.str2ba(address) cmd_pkt = "%s%s\0%s" % (bdaddr, psrm, clockoff) try: _bt.hci_send_cmd(self.sock, _bt.OGF_LINK_CTL, _bt.OCF_REMOTE_NAME_REQ, cmd_pkt) except Exception, e: raise BluetoothError("error request name of %s - %s" % (address, str(e)))
def _send_next_name_req(self): assert len(self.names_to_find) > 0 address = self.names_to_find.keys()[0] device_class, psrm, pspm, clockoff = self.names_to_find[address] bdaddr = _bt.str2ba(address) cmd_pkt = "%s%s\0%s" % (bdaddr, psrm, clockoff) try: _bt.hci_send_cmd (self.sock, _bt.OGF_LINK_CTL, \ _bt.OCF_REMOTE_NAME_REQ, cmd_pkt) except Exception, e: raise BluetoothError("error request name of %s - %s" % (address, str(e)))
def cancel_inquiry(self): """ Call this method to cancel an inquiry in process. inquiry_complete will still be called. """ self.names_to_find = {} if self.is_inquiring: try: _bt.hci_send_cmd(self.sock, _bt.OGF_LINK_CTL, _bt.OCF_INQUIRY_CANCEL) self.sock.close() self.sock = None except: raise BluetoothError("error canceling inquiry") self.is_inquiring = False
def _send_next_name_req(self): assert len(self.names_to_find) > 0 address = list(self.names_to_find.keys())[0] device_class, rssi, psrm, pspm, clockoff = self.names_to_find[address] bdaddr = _bt.str2ba(address) #TODO not supported in python3 cmd_pkt = "%s%s\0%s" % (bdaddr, psrm, clockoff) try: _bt.hci_send_cmd (self.sock, _bt.OGF_LINK_CTL, \ _bt.OCF_REMOTE_NAME_REQ, cmd_pkt) except _bt.error as e: raise BluetoothError( e.args[0], "error request name of %s - %s:" % (address, e.args[1]))
def cancel_inquiry(self): """ Call this method to cancel an inquiry in process. inquiry_complete will still be called. """ self.names_to_find = {} if self.is_inquiring: try: _bt.hci_send_cmd (self.sock, _bt.OGF_LINK_CTL, \ _bt.OCF_INQUIRY_CANCEL) self.sock.close() self.sock = None except: raise BluetoothError("error canceling inquiry") self.is_inquiring = False
def read_local_bdaddr(hci_sock): 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