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 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 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 read_remote_supported_features(self, cmd_params: dict) -> dict: ''' cmd_params -- {'Connection_Handle': 0x0000 to 0x0EFF} ''' dd = hci_open_dev(self.devid) bin_cmd_params = cmd_params['Connection_Handle'].to_bytes(2, 'little') flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_READ_REMOTE_FEATURES_COMPLETE) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_LINK_CTL, OCF_READ_REMOTE_FEATURES, bin_cmd_params) while True: event_params = dd.recv(3 + EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE)[3:] status, conn_handle, lmp_features = struct.unpack( '<BH8s', event_params) event_params = { 'Status': status, 'Connection_Handle': conn_handle, 'LMP_Features': lmp_features } if event_params['Connection_Handle'] == cmd_params[ 'Connection_Handle']: break hci_close_dev(dd.fileno()) return event_params
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 disconnect(self, cmd_params: dict) -> dict: ''' cmd_params -- { 'Connection_Handle': int, 2 bytes, 'Reason': int, 1 bytes } ''' dd = hci_open_dev(self.devid) flt = hci_filter_new() hci_filter_clear(flt) hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_DISCONN_COMPLETE) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) bin_cmd_params = cmd_params['Connection_Handle'].to_bytes(2, 'little') + \ cmd_params['Reason'].to_bytes(1, 'little') hci_send_cmd(dd, OGF_LINK_CTL, OCF_DISCONNECT, bin_cmd_params) # Receive and exclude HCI packet type (1 B) event_params = dd.recv(3 + EVT_DISCONN_COMPLETE_SIZE)[3:] status, conn_handle, reason, = struct.unpack('<BHB', event_params) event_params = { 'Status': status, 'Connection_Handle': conn_handle, 'Reason': reason } hci_close_dev(dd.fileno()) return event_params
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 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 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 create_connection(self, cmd_params: dict): ''' cmd_params -- { 'BD_ADDR': str, 'Packet_Type': int, 'Page_Scan_Repetition_Mode': , 'Reserved': , 'Clock_Offset': , 'Allow_Role_Switch': } ''' dd = hci_open_dev(self.devid) bin_cmd_params = bytes.fromhex( cmd_params['BD_ADDR'].replace(':', ''))[::-1] + \ cmd_params['Packet_Type'].to_bytes(2, 'little') + \ cmd_params['Page_Scan_Repetition_Mode'].to_bytes(1, 'little') + \ cmd_params['Reserved'].to_bytes(1, 'little') + \ cmd_params['Clock_Offset'].to_bytes(2, 'little') + \ cmd_params['Allow_Role_Switch'].to_bytes(1, 'little') flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_CONN_COMPLETE) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_LINK_CTL, OCF_CREATE_CONN, bin_cmd_params) while True: event_params = dd.recv(3 + EVT_CONN_COMPLETE_SIZE)[3:] status, conn_handle, bd_addr, link_type, encrypt_enabled = \ struct.unpack('<BH6sBB', event_params) event_params = { 'Status': status, 'Connection_Handle': conn_handle, 'BD_ADDR': ':'.join(['%02x' % b for b in bd_addr[::-1]]), 'Link_Type': link_type, 'Encryption_Enabled': encrypt_enabled, } if event_params['BD_ADDR'].lower() == cmd_params['BD_ADDR'].lower( ): break else: print(WARNING, 'Another HCI_Connection_Complete event detected', event_params) hci_close_dev(dd.fileno()) return event_params
def inquiry(self, lap=0x9e8b33, inquiry_len=0x08, num_rsp=0x00): print(INFO, "BR scanning on " + blue("hci%d"%self.devid) + \ " with timeout " + blue("%.2f sec\n"%(inquiry_len*1.28))+'\n') self.scanned_dev = [] cmd_params = lap.to_bytes(3, 'little') + \ inquiry_len.to_bytes(1, 'little') + num_rsp.to_bytes(1, 'little') # If no filter is set, we can't receive any inquiry result. flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_all_events(flt) dd = hci_open_dev(self.devid) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_LINK_CTL, OCF_INQUIRY, cmd_params) try: while True: data = dd.recv(300) if len(data) >= 4: event_code = data[1] if event_code == EVT_CMD_STATUS: # print(DEBUG, 'HCI_Command_Status') pass elif event_code == EVT_INQUIRY_RESULT: print(DEBUG, 'HCI_Inquiry_Result') self.pp_inquiry_result(data[3:]) elif event_code == EVT_INQUIRY_RESULT_WITH_RSSI: # print(DEBUG, 'HCI_Inquiry_Result_with_RSSI') self.pp_inquiry_result_with_rssi(data[3:]) elif event_code == EVT_EXTENDED_INQUIRY_RESULT: # print(DEBUG, 'HCI_Extended_Inquiry_Result') self.pp_extended_inquiry_result(data[3:]) elif event_code == EVT_INQUIRY_COMPLETE: # print(DEBUG, 'HCI_Inquiry_Complete') print(INFO, 'Inquiry completed') break else: print(DEBUG, "Unknow:", data) except KeyboardInterrupt as e: print(INFO, "BR/EDR devices scan canceled\n") HCI(self.iface).inquiry_cancel() hci_close_dev(dd.fileno())
def pp_le_scanner_addr(cls): hci = HCI('hci0') hci.le_set_advertising_parameters() bytes.fromhex('020106020aeb0303ff00') + bytes(0x1f - 10) hci.le_set_advertising_data({ 'Advertising_Data_Length': 0x12, 'Advertising_Data': bytes.fromhex('020106020aeb0303ff000709424c45435446') + bytes(0x1f - 0x12) }) hci.le_set_scan_response_data({ 'Scan_Response_Data_Length': 0x0a, 'Scan_Response_Data': bytes.fromhex('020106020aeb0303ff00') + bytes(0x1f - 0x0a) }) hci.le_set_advertising_enable({'Advertising_Enable': 0x01}) dd = hci_open_dev(0) 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 + SUBEVT_LE_SCAN_REQUEST_RECEIVED_SIZE)[3:] if event_params[0] != SUBEVT_LE_SCAN_REQUEST_RECEIVED: continue subevt_code, adv_handle, scanner_addr_type, scanner_addr = struct.unpack( '<BBB6s', event_params) event_params = { 'Subevent_Code': subevt_code, 'Advertising_Handle': adv_handle, 'Scanner_Address_Type': scanner_addr_type, 'Scanner_Address': scanner_addr } print(event_params) hci_close_dev(dd.fileno())
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 read_remote_extended_features(self, cmd_params: dict) -> dict: ''' cmd_params -- { 'Connection_Handle': 0x0000 to 0x0EFF, 'Page_Number': int } ''' dd = hci_open_dev(self.devid) bin_cmd_params = cmd_params[ 'Connection_Handle'].to_bytes(2, 'little') + \ cmd_params['Page_Number'].to_bytes(1, 'little') flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_READ_REMOTE_EXT_FEATURES_COMPLETE) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_LINK_CTL, OCF_READ_REMOTE_EXT_FEATURES, bin_cmd_params) while True: event_params = dd.recv(3 + \ EVT_READ_REMOTE_EXT_FEATURES_COMPLETE_SIZE)[3:] status, conn_handle, page_num, max_page_num, ext_lmp_features = \ struct.unpack('<BHBB8s', event_params) event_params = { 'Status': status, 'Connection_Handle': conn_handle, 'Page_Number': page_num, 'Maximum_Page_Number': max_page_num, 'Extended_LMP_Features': ext_lmp_features } if event_params['Connection_Handle'] == cmd_params['Connection_Handle'] and \ event_params['Page_Number'] == cmd_params['Page_Number']: break 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 read_remote_version_information(self, cmd_params: dict) -> dict: ''' cmd_params -- { 'Connection_Handle': 0x0000 } ''' dd = hci_open_dev(self.devid) bin_cmd_params = cmd_params['Connection_Handle'].to_bytes(2, 'little') flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_set_event(flt, EVT_READ_REMOTE_VERSION_COMPLETE) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_LINK_CTL, OCF_READ_REMOTE_VERSION, bin_cmd_params) while True: event_params = dd.recv(3 + \ EVT_READ_REMOTE_VERSION_COMPLETE_SIZE)[3:] status, conn_handle, ver, manufacturer_name, subver = \ struct.unpack('<BHBHH', event_params) event_params = { 'Status': status, 'Connection_Handle': conn_handle, 'Version': ver, 'Manufacturer_Name': manufacturer_name, 'Subversion': subver } if event_params['Connection_Handle'] == cmd_params[ 'Connection_Handle']: break 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
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 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 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 inquiry(self, lap=0x9e8b33, inquiry_len=0x08, num_rsp=0x00): logger.info('BR scanning on ' + blue("hci%d"%self.devid) + \ ' with timeout ' + blue("%.2f sec\n"%(inquiry_len*1.28))+'\n') self.scanned_dev = [] self.remote_name_req_flag = True cmd_params = lap.to_bytes(3, 'little') + \ inquiry_len.to_bytes(1, 'little') + num_rsp.to_bytes(1, 'little') # If no filter is set, we can't receive any inquiry result. flt = hci_filter_new() hci_filter_set_ptype(flt, HCI_EVENT_PKT) hci_filter_all_events(flt) dd = hci_open_dev(self.devid) dd.setsockopt(SOL_HCI, HCI_FILTER, flt) hci_send_cmd(dd, OGF_LINK_CTL, OCF_INQUIRY, cmd_params) try: while True: data = dd.recv(300) if len(data) >= 4: event_code = data[1] if event_code == EVT_CMD_STATUS: logger.debug('HCI_Command_Status') pass elif event_code == EVT_INQUIRY_RESULT: logger.debug('HCI_Inquiry_Result') self.pp_inquiry_result(data[3:]) elif event_code == EVT_INQUIRY_RESULT_WITH_RSSI: logger.debug('HCI_Inquiry_Result_with_RSSI') self.pp_inquiry_result_with_rssi(data[3:]) elif event_code == EVT_EXTENDED_INQUIRY_RESULT: logger.debug('HCI_Extended_Inquiry_Result') self.pp_extended_inquiry_result(data[3:]) elif event_code == EVT_INQUIRY_COMPLETE: logger.debug('HCI_Inquiry_Complete') logger.info('Inquiry completed\n') if self.remote_name_req_flag and len( self.scanned_dev) != 0: logger.info( 'Requesting the name of the scanned devices...' ) for bd_addr in self.scanned_dev: try: name = HCI(self.iface).remote_name_request( { 'BD_ADDR': bytes.fromhex( bd_addr.replace(':', '')), 'Page_Scan_Repetition_Mode': 0x01, 'Reserved': 0x00, 'Clock_Offset': 0x0000 })['Remote_Name'].decode().strip() except Exception as e: print(e) name = '' print(bd_addr + ':', blue(name)) break else: logger.debug('Unknow: {}'.format(data)) except KeyboardInterrupt as e: logger.info('BR/EDR devices scan canceled\n') HCI(self.iface).inquiry_cancel() hci_close_dev(dd.fileno())
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 ) try: socket = bluez.hci_open_dev(devid) except: print "failed open ble socket..." sys.exit(1) listen_le_scan(socket) parse_le_events(socket) try: bluez.hci_close_dev(devid) print "close hci connection..." except: print "failed close ble socket..." sys.exit(1)