def set_inquiry_mode(self, mode): """ Set bluetooth inquiry mode :param mode: :return: 0 if success, -1 on failure """ old_filter = self._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) self._sock.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, flt) # send the command! bluez.hci_send_cmd(self._sock, bluez.OGF_HOST_CTL, bluez.OCF_WRITE_INQUIRY_MODE, struct.pack("B", mode)) 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) 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 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_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 _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_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 exit_periodic_inquiry_mode(self) -> dict: ''' Return -- { 'Num_HCI_Command_Packets': int, 'Command_Opcode': int, 'Status': int } ''' dd = hci_open_dev(self.devid) flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_CMD_COMPLETE) hci_filter_set_opcode( flt, cmd_opcode_pack(OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY)) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY) event_params = dd.recv(3 + EVT_CMD_COMPLETE_SIZE + 1)[3:] num_hci_cmd_pkts, cmd_opcode, status = struct.unpack( '<BHB', event_params) event_params = { 'Num_HCI_Command_Packets': num_hci_cmd_pkts, 'Command_Opcode': cmd_opcode, 'Status': status } hci_close_dev(dd.fileno()) return status
def create_connection_cancel(self, cmd_params: dict) -> dict: ''' cmd_params -- { 'BD_ADDR': str } ''' dd = hci_open_dev(self.devid) bin_cmd_params = bytes.fromhex(cmd_params['BD_ADDR'].replace(':', '')[::-1]) flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_CMD_COMPLETE) hci_filter_set_opcode( flt, cmd_opcode_pack(OGF_LINK_CTL, OCF_CREATE_CONN_CANCEL)) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_LINK_CTL, OCF_CREATE_CONN_CANCEL, bin_cmd_params) event_params = dd.recv(3 + EVT_CMD_COMPLETE_SIZE + 7)[3:] num_hci_cmd_pkts, cmd_opcode, status, \ bdaddr = struct.unpack('<BHB6s', event_params) hci_close_dev(dd.fileno()) return event_params
def le_set_scan_response_data( self, cmd_params={ 'Scan_Response_Data_Length': 0x1f, 'Scan_Response_Data': bytes(0x1f) } ) -> dict: dd = hci_open_dev(self.devid) bin_cmd_params = cmd_params['Scan_Response_Data_Length'].to_bytes(1, 'little') + \ cmd_params['Scan_Response_Data'] flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_CMD_COMPLETE) hci_filter_set_opcode( flt, cmd_opcode_pack(OGF_LE_CTL, OCF_LE_SET_SCAN_RESPONSE_DATA)) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_LE_CTL, OCF_LE_SET_SCAN_RESPONSE_DATA, bin_cmd_params) event_params = dd.recv(3 + EVT_CMD_COMPLETE_SIZE + 1)[3:] num_hci_cmd_pkts, cmd_opcode, status = struct.unpack( '<BHB', event_params) event_params = { 'Num_HCI_Command_Packets': num_hci_cmd_pkts, 'Command_Opcode': cmd_opcode, 'Status': status } hci_close_dev(dd.fileno()) return event_params
def le_set_advertising_enable(self, cmd_params={'Advertising_Enable': 0x00}) -> dict: dd = hci_open_dev(self.devid) bin_cmd_params = cmd_params['Advertising_Enable'].to_bytes(1, 'little') flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_CMD_COMPLETE) hci_filter_set_opcode( flt, cmd_opcode_pack(OGF_LE_CTL, OCF_LE_SET_ADVERTISING_ENABLE)) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_LE_CTL, OCF_LE_SET_ADVERTISING_ENABLE, bin_cmd_params) event_params = dd.recv(3 + EVT_CMD_COMPLETE_SIZE + 1)[3:] num_hci_cmd_pkts, cmd_opcode, status = struct.unpack( '<BHB', event_params) event_params = { 'Num_HCI_Command_Packets': num_hci_cmd_pkts, 'Command_Opcode': cmd_opcode, 'Status': status } hci_close_dev(dd.fileno()) return event_params
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 read_bd_addr(self) -> dict: r"""'Return BD_ADDR string "XX:XX:XX:XX:XX:XX'""" dd = hci_open_dev(self.devid) flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_CMD_COMPLETE) hci_filter_set_opcode( flt, cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_BD_ADDR)) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_INFO_PARAM, OCF_READ_BD_ADDR) event_params = dd.recv(HCI_MAX_EVENT_SIZE)[3:] num_hci_cmd_pkts, cmd_opcode, status, bd_addr = struct.unpack( "<BHB6s", event_params) bd_addr = ["%02X" % b for b in bd_addr] bd_addr.reverse() event_params = { 'Num_HCI_Command_Packets': num_hci_cmd_pkts, 'Command_Opcode': cmd_opcode, 'Status': status, 'BD_ADDR': ':'.join(bd_addr) } hci_close_dev(dd.fileno()) return event_params
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 _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 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 ) try: # first read the current inquiry mode. bluez.hci_send_cmd(sock, bluez.OGF_HOST_CTL, bluez.OCF_READ_INQUIRY_MODE ) except bluez.error as e: raise AdapterUnaccessibleError("Are you sure this a bluetooth 1.2 device? \nTurn On Your Bluetooth") 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 read_inquiry_mode(sock): """returns the current mode, or -1 on failure""" # save current filter old_filter = sock.getsockopt(bt.SOL_HCI, bt.HCI_FILTER, 14) # Setup socket filter to receive only events related to the # read_inquiry_mode command flt = bt.hci_filter_new() opcode = bt.cmd_opcode_pack(bt.OGF_HOST_CTL, bt.OCF_READ_INQUIRY_MODE) 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) sock.setsockopt(bt.SOL_HCI, bt.HCI_FILTER, flt) # first read the current inquiry mode. bt.hci_send_cmd(sock, bt.OGF_HOST_CTL, bt.OCF_READ_INQUIRY_MODE) pkt = sock.recv(255) status, mode = struct.unpack("xxxxxxBB", pkt) if status != 0: mode = -1 # restore old filter sock.setsockopt(bt.SOL_HCI, bt.HCI_FILTER, old_filter) return mode
def set_event_filter(self, cmd_params: dict) -> dict: '''A little complicated. see the core specification BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 4, Part E page 2078. Only support Filter_Type = 0x00 now. ''' dd = hci_open_dev(self.devid) bin_cmd_params = cmd_params['Filter_Type'].to_bytes(1, 'little') flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_CMD_COMPLETE) hci_filter_set_opcode(flt, cmd_opcode_pack(OGF_HOST_CTL, OCF_SET_EVENT_FLT)) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_HOST_CTL, OCF_SET_EVENT_FLT, bin_cmd_params) event_params = dd.recv(3 + EVT_CMD_COMPLETE_SIZE + 1)[3:] num_hci_cmd_pkts, cmd_opcode, status = struct.unpack( '<BHB', event_params) event_params = { 'Num_HCI_Command_Packets': num_hci_cmd_pkts, 'Command_Opcode': cmd_opcode, 'Status': status } hci_close_dev(dd.fileno()) return event_params
def write_inquiry_mode(sock, mode): """returns 0 on success, -1 on failure""" # save current filter old_filter = sock.getsockopt(bt.SOL_HCI, bt.HCI_FILTER, 14) # Setup socket filter to receive only events related to the # write_inquiry_mode command flt = bt.hci_filter_new() opcode = bt.cmd_opcode_pack(bt.OGF_HOST_CTL, bt.OCF_WRITE_INQUIRY_MODE) 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) sock.setsockopt(bt.SOL_HCI, bt.HCI_FILTER, flt) # send the command! bt.hci_send_cmd(sock, bt.OGF_HOST_CTL, bt.OCF_WRITE_INQUIRY_MODE, struct.pack("B", mode)) pkt = sock.recv(255) status = struct.unpack("xxxxxxB", pkt)[0] # restore old filter sock.setsockopt(bt.SOL_HCI, bt.HCI_FILTER, old_filter) if status != 0: return -1 return 0
def le_set_scan_enable(self, cmd_params: dict): ''' cmd_params -- { 'LE_Scan_Enable': int 0 or 1, 'Filter_Duplicates': int 0 or 1 } ''' dd = hci_open_dev(self.devid) bin_cmd_params = cmd_params['LE_Scan_Enable'].to_bytes(1, 'little') + \ cmd_params['Filter_Duplicates'].to_bytes(1, 'little') flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_CMD_COMPLETE) hci_filter_set_opcode( flt, cmd_opcode_pack(OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE)) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE, bin_cmd_params) event_params = dd.recv(3 + EVT_CMD_COMPLETE_SIZE + 1)[3:] num_hci_cmd_pkts, cmd_opcode, status = struct.unpack( '<BHB', event_params) event_params = { 'Num_HCI_Command_Packets': num_hci_cmd_pkts, 'Command_Opcode': cmd_opcode, 'Status': status } if event_params['Status'] != 0x00: raise RuntimeError( 'Status of HCI_LE_Set_Scan_Enable command: 0x%02x' % event_params['Status']) if not cmd_params['LE_Scan_Enable']: return event_params flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_LE_META) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) while True: event_params = dd.recv(3 + HCI_MAX_EVENT_SIZE)[3:] if event_params[0] != SUBEVT_LE_ADVERTISING_REPORT: continue num_reports = event_params[1] if num_reports == 1: event_type, addr_type, addr = struct.unpack( '<BB6s', event_params[2:10]) print('Event_Type:', event_type) print('Address_Type:', addr_type) print('Address:', addr) hci_close_dev(dd.fileno()) return event_params
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 set_filter(self, event_type=None, ogf=None, ocf=None): flt = _bt.hci_filter_new() _bt.hci_filter_set_ptype(flt, _bt.HCI_EVENT_PKT) if event_type: _bt.hci_filter_set_event(flt, event_type) if event_type == _bt.EVT_CMD_COMPLETE and ogf and ocf: _bt.hci_filter_set_opcode(flt, _bt.cmd_opcode_pack(ogf, ocf)) else: _bt.hci_filter_all_events(flt) self.hci_sock.setsockopt(_bt.SOL_HCI, _bt.HCI_FILTER, flt)
def read_local_bdaddr(sock): flt = bluez.hci_filter_new() opcode = bluez.cmd_opcode_pack(bluez.OGF_INFO_PARAM, bluez.OCF_READ_BD_ADDR) 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) bluez.hci_send_cmd(sock, bluez.OGF_INFO_PARAM, bluez.OCF_READ_BD_ADDR) pkt = 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) return bdaddr.lower()
def le_set_advertising_parameters( self, cmd_params={ 'Advertising_Interval_Min': 0x0800, 'Advertising_Interval_Max': 0x0800, 'Advertising_Type': 0x00, # ADV_IND 'Own_Address_Type': 0x00, # Public Device Address 'Peer_Address_Type': 0x00, # Public Device Address 'Peer_Address': bytes(6), 'Advertising_Channel_Map': 0x07, # 37, 38, 39 'Advertising_Filter_Policy': 0x00 # Process scan and connection requests from all devices } ) -> dict: dd = hci_open_dev(self.devid) bin_cmd_params = cmd_params['Advertising_Interval_Min'].to_bytes(2, 'little') + \ cmd_params['Advertising_Interval_Max'].to_bytes(2, 'little') + \ cmd_params['Advertising_Type'].to_bytes(1, 'little') + \ cmd_params['Own_Address_Type'].to_bytes(1, 'little') + \ cmd_params['Peer_Address_Type'].to_bytes(1, 'little') + \ cmd_params['Peer_Address'][::-1] + \ cmd_params['Advertising_Channel_Map'].to_bytes(1, 'little') + \ cmd_params['Advertising_Filter_Policy'].to_bytes(1, 'little') flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_CMD_COMPLETE) hci_filter_set_opcode( flt, cmd_opcode_pack(OGF_LE_CTL, OCF_LE_SET_ADVERTISING_PARAMETERS)) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_LE_CTL, OCF_LE_SET_ADVERTISING_PARAMETERS, bin_cmd_params) event_params = dd.recv(3 + EVT_CMD_COMPLETE_SIZE + 1)[3:] num_hci_cmd_pkts, cmd_opcode, status = struct.unpack( '<BHB', event_params) event_params = { 'Num_HCI_Command_Packets': num_hci_cmd_pkts, 'Command_Opcode': cmd_opcode, 'Status': status } hci_close_dev(dd.fileno()) return event_params
def reset(self) -> dict: dd = hci_open_dev(self.devid) flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_CMD_COMPLETE) hci_filter_set_opcode(flt, cmd_opcode_pack(OGF_HOST_CTL, OCF_RESET)) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_HOST_CTL, OCF_RESET) event_params = dd.recv(3 + EVT_CMD_COMPLETE_SIZE + 1)[3:] num_hci_cmd_pkts, cmd_opcode, status = struct.unpack( '<BHB', event_params) event_params = { 'Num_HCI_Command_Packets': num_hci_cmd_pkts, 'Command_Opcode': cmd_opcode, 'Status': status } hci_close_dev(dd.fileno()) return event_params
def write_page_timeout(self, cmd_params={'Page_Timeout': 0x2000}) -> dict: dd = hci_open_dev(self.devid) bin_cmd_params = cmd_params['Page_Timeout'].to_bytes(2, 'little') flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_CMD_COMPLETE) hci_filter_set_opcode( flt, cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT)) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT, bin_cmd_params) event_params = dd.recv(3 + EVT_CMD_COMPLETE_SIZE + 3)[3:] num_hci_cmd_pkts, cmd_opcode, status = struct.unpack( '<BHB', event_params) event_params = { 'Num_HCI_Command_Packets': num_hci_cmd_pkts, 'Command_Opcode': cmd_opcode, 'Status': status } hci_close_dev(dd.fileno()) return event_params
def read_local_name(self) -> dict: dd = hci_open_dev(self.devid) flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_CMD_COMPLETE) hci_filter_set_opcode( flt, cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_LOCAL_NAME)) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_HOST_CTL, OCF_READ_LOCAL_NAME) event_params = dd.recv(3 + EVT_CMD_COMPLETE_SIZE + 249)[3:] num_hci_cmd_pkts, cmd_opcode, status, local_name = struct.unpack( '<BHB248s', hci_cmd_complete) event_params = { 'Num_HCI_Command_Packets': num_hci_cmd_pkts, 'Command_Opcode': cmd_opcode, 'Status': status, 'Local_Name': local_name.decode() } hci_close_dev(dd.fileno()) return event_params
def write_inquiry_mode(self, cmd_params={'Inquiry_Mode': 0x00}) -> dict: dd = hci_open_dev(self.devid) bin_cmd_params = cmd_params['Inquiry_Mode'].to_bytes(1, 'little') flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_CMD_COMPLETE) hci_filter_set_opcode( flt, cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE)) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, bin_cmd_params) event_params = dd.recv(3 + EVT_CMD_COMPLETE_SIZE + 1)[3:] num_hci_cmd_pkts, cmd_opcode, status = struct.unpack( '<BHB', event_params) event_params = { 'Num_HCI_Command_Packets': num_hci_cmd_pkts, 'Command_Opcode': cmd_opcode, 'Status': status } hci_close_dev(dd.fileno()) return event_params
def read_class_of_device(self) -> dict: dd = hci_open_dev(self.devid) flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_CMD_COMPLETE) hci_filter_set_opcode( flt, cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_CLASS_OF_DEV)) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_HOST_CTL, OCF_READ_CLASS_OF_DEV) event_params = dd.recv(3 + HCI_MAX_EVENT_SIZE)[3:] num_hci_cmd_pkts, cmd_opcode, status, cod = struct.unpack( '<BHB3s', event_params) event_params = { 'Num_HCI_Command_Packets': num_hci_cmd_pkts, 'Command_Opcode': cmd_opcode, 'Status': status, 'Class_Of_Device': cod[::-1] } hci_close_dev(dd.fileno()) return event_params
def read_extended_page_timeout(self): dd = hci_open_dev(self.devid) flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_CMD_COMPLETE) hci_filter_set_opcode( flt, cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_EXT_PAGE_TIMEOUT)) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_HOST_CTL, OCF_READ_EXT_PAGE_TIMEOUT) event_params = dd.recv(3 + EVT_CMD_COMPLETE_SIZE + 3)[3:] num_hci_cmd_pkts, cmd_opcode, status, \ ext_page_timeout = struct.unpack('<BHBH', event_params) event_params = { 'Num_HCI_Command_Packets': num_hci_cmd_pkts, 'Command_Opcode': cmd_opcode, 'Status': status, 'Extended_Page_Timeout': ext_page_timeout } hci_close_dev(dd.fileno()) return event_params