def slot_pbutton_ap_leases_refresh_clicked(self):
        def cb_dnsmasq_leases_content(content):
            self.pbutton_ap_leases_refresh.setText('Refresh')
            self.pbutton_ap_leases_refresh.setEnabled(True)

            self.tview_ap_leases.setEnabled(True)

            leases_lines = content.splitlines()

            leases_model = QStandardItemModel(0, 3, self)
            leases_model.setHorizontalHeaderItem(0, QStandardItem("Hostname"))
            leases_model.setHorizontalHeaderItem(1, QStandardItem("MAC"))
            leases_model.setHorizontalHeaderItem(2, QStandardItem("IP"))
            leases_model.setHorizontalHeaderItem(3, QStandardItem("Expiration"))

            for i, l in enumerate(leases_lines):
                l_split = l.strip().split(' ')
                if len(l_split) != 5:
                    continue

                for j in range(0, len(l_split)):
                    if j == 4:
                        continue

                    if j == 0:
                        #FIXME: fromTime_t is obsolete: https://doc.qt.io/qt-5/qdatetime-obsolete.html#toTime_t
                        leases_model.setItem(i, 3, QStandardItem(QDateTime.fromTime_t(int(l_split[j])).toString('yyyy-MM-dd HH:mm:ss')))
                    elif j == 3:
                        leases_model.setItem(i, 0, QStandardItem(l_split[j]))
                    else:
                        leases_model.setItem(i, j, QStandardItem(l_split[j]))

            self.tview_ap_leases.setModel(leases_model)

            self.tview_ap_leases.setColumnWidth(0, DEFAULT_TVIEW_HOST_NAME_HEADER_WIDTH)
            self.tview_ap_leases.setColumnWidth(1, DEFAULT_TVIEW_MAC_HEADER_WIDTH)
            self.tview_ap_leases.setColumnWidth(2, DEFAULT_TVIEW_IP_HEADER_WIDTH)
            self.tview_ap_leases.setColumnWidth(3, DEFAULT_TVIEW_EXPIRATION_HEADER_WIDTH)

        def cb_dnsmasq_leases_error(kind, error):
            self.pbutton_ap_leases_refresh.setText('Refresh')
            self.pbutton_ap_leases_refresh.setEnabled(True)

            kind_text = {
                TextFile.ERROR_KIND_OPEN: 'opening',
                TextFile.ERROR_KIND_READ: 'reading',
                TextFile.ERROR_KIND_UTF8: 'decoding'
            }

            QMessageBox.critical(get_main_window(),
                                 'Settings | Access Point',
                                 'Error {0} dnsmasq leases file:\n\n{1}'.format(kind_text[kind], error))

        self.pbutton_ap_leases_refresh.setText('Refreshing...')
        self.pbutton_ap_leases_refresh.setEnabled(False)

        TextFile.read_async(self.session, DNSMASQ_LEASES_FILE,
                            cb_dnsmasq_leases_content, cb_dnsmasq_leases_error)
Example #2
0
    def slot_pbutton_ap_leases_refresh_clicked(self):
        def cb_dnsmasq_leases_content(content):
            self.pbutton_ap_leases_refresh.setText('Refresh')
            self.pbutton_ap_leases_refresh.setEnabled(True)

            self.tview_ap_leases.setEnabled(True)

            leases_lines = content.splitlines()

            leases_model = QtGui.QStandardItemModel(0, 3, self)
            leases_model.setHorizontalHeaderItem(0, QtGui.QStandardItem("Hostname"))
            leases_model.setHorizontalHeaderItem(1, QtGui.QStandardItem("MAC"))
            leases_model.setHorizontalHeaderItem(2, QtGui.QStandardItem("IP"))
            leases_model.setHorizontalHeaderItem(3, QtGui.QStandardItem("Expiration"))

            for i, l in enumerate(leases_lines):
                l_split = l.strip().split(' ')
                if len(l_split) != 5:
                    continue

                for j in range(0, len(l_split)):
                    if j == 4:
                        continue

                    if j == 0:
                        leases_model.setItem(i, 3, QtGui.QStandardItem(QtCore.QDateTime.fromTime_t(int(l_split[j])).toString('yyyy-MM-dd HH:mm:ss')))
                    elif j == 3:
                        leases_model.setItem(i, 0, QtGui.QStandardItem(l_split[j]))
                    else:
                        leases_model.setItem(i, j, QtGui.QStandardItem(l_split[j]))

            self.tview_ap_leases.setModel(leases_model)

            self.tview_ap_leases.setColumnWidth(0, DEFAULT_TVIEW_HOST_NAME_HEADER_WIDTH)
            self.tview_ap_leases.setColumnWidth(1, DEFAULT_TVIEW_MAC_HEADER_WIDTH)
            self.tview_ap_leases.setColumnWidth(2, DEFAULT_TVIEW_IP_HEADER_WIDTH)
            self.tview_ap_leases.setColumnWidth(3, DEFAULT_TVIEW_EXPIRATION_HEADER_WIDTH)

        def cb_dnsmasq_leases_error(kind, error):
            self.pbutton_ap_leases_refresh.setText('Refresh')
            self.pbutton_ap_leases_refresh.setEnabled(True)

            kind_text = {
            TextFile.ERROR_KIND_OPEN: 'opening',
            TextFile.ERROR_KIND_READ: 'reading',
            TextFile.ERROR_KIND_UTF8: 'decoding'
            }

            QtGui.QMessageBox.critical(get_main_window(),
                                       'Settings | Access Point',
                                       'Error {0} dnsmasq leases file:\n\n{1}'.format(kind_text[kind], error))

        self.pbutton_ap_leases_refresh.setText('Refreshing...')
        self.pbutton_ap_leases_refresh.setEnabled(False)

        TextFile.read_async(self.session, DNSMASQ_LEASES_FILE,
                            cb_dnsmasq_leases_content, cb_dnsmasq_leases_error)
Example #3
0
    def read_config_files(self):
        def cb_hostapd_conf_content(content):
            if not self.is_tab_on_focus or len(content) == 0:
                return

            def cb_settings_ap_get_interfaces(result):
                if not self.is_tab_on_focus:
                    return

                if not report_script_result(
                        result, 'Settings | Access Point',
                        'Error getting access point interfaces:'):
                    return

                ap_mode_interfaces = json.loads(result.stdout)

                if len(ap_mode_interfaces) <= 0:
                    self.label_ap_status.setText(
                        'Inactive - No wireless interface available')
                    self.cbox_ap_interface.clear()
                    self.pbutton_ap_save.setEnabled(False)
                    self.update_ui_state()
                    return

                self.pbutton_ap_save.setEnabled(True)
                self.cbox_ap_interface.clear()

                self.cbox_ap_interface.currentIndexChanged.disconnect()

                for intf in ap_mode_interfaces:
                    self.cbox_ap_interface.addItem(intf)
                    current_item_index = self.cbox_ap_interface.count() - 1

                    if ap_mode_interfaces[intf]['ip']:
                        self.cbox_ap_interface.setItemData(
                            current_item_index, ap_mode_interfaces[intf]['ip'],
                            AP_INTERFACE_IP_USER_ROLE)
                    else:
                        self.cbox_ap_interface.setItemData(
                            current_item_index, '192.168.42.1',
                            AP_INTERFACE_IP_USER_ROLE)

                    if ap_mode_interfaces[intf]['mask']:
                        self.cbox_ap_interface.setItemData(
                            current_item_index,
                            ap_mode_interfaces[intf]['mask'],
                            AP_INTERFACE_MASK_USER_ROLE)

                    else:
                        self.cbox_ap_interface.setItemData(
                            current_item_index, '255.255.255.0',
                            AP_INTERFACE_MASK_USER_ROLE)
                self.cbox_ap_interface.setCurrentIndex(-1)
                self.cbox_ap_interface.currentIndexChanged.connect(
                    self.slot_cbox_ap_interface_current_index_changed)

                if not interface:
                    self.cbox_ap_interface.setCurrentIndex(0)

                elif not interface and self.cbox_ap_interface.count() > 0:
                    self.cbox_ap_interface.setCurrentIndex(0)

                else:
                    broke = False
                    for i in range(0, self.cbox_ap_interface.count()):
                        if self.cbox_ap_interface.itemText(i) == interface:
                            self.cbox_ap_interface.setCurrentIndex(i)
                            broke = True
                            break

                    if not broke:
                        self.cbox_ap_interface.setCurrentIndex(0)

                self.update_ui_state()

            try:
                lines = content.splitlines()
                interface = ''
                ssid = ''
                channel = 1
                ssid_hidden = '0'
                wpa_key = ''

                for l in lines:
                    l_split = l.strip().split('=')

                    if len(l_split) != 2:
                        continue

                    if l_split[0].strip(' ') == 'interface':
                        interface = l_split[1].strip(' ')

                    elif l_split[0].strip(' ') == 'ssid':
                        ssid = l_split[1].strip(' ')

                    elif l_split[0].strip(' ') == 'channel':
                        channel = l_split[1].strip(' ')

                    elif l_split[0].strip(' ') == 'ignore_broadcast_ssid':
                        ssid_hidden = l_split[1].strip(' ')

                    elif l_split[0].strip(' ') == 'wpa_passphrase':
                        wpa_key = l_split[1]

                self.script_manager.execute_script(
                    'settings_ap_get_interfaces',
                    cb_settings_ap_get_interfaces)
                self.ledit_ap_ssid.setText(ssid)
                self.chkbox_ap_ssid_hidden.setChecked(ssid_hidden != '0')

                self.sbox_ap_channel.setValue(int(channel))
                self.ledit_ap_wpa_key.setText(wpa_key)
            except Exception as e:
                QMessageBox.critical(
                    get_main_window(), 'Settings | Access Point',
                    'Error parsing hostapd.conf file:\n\n{0}'.format(e))

            self.update_ui_state()

        def cb_dnsmasq_conf_content(content):
            if not self.is_tab_on_focus or len(content) == 0:
                return

            try:
                lines = content.splitlines()
                dns_dhcp_enabled = True
                dhcp_range_start = '192.168.42.50'
                dhcp_range_end = '192.168.42.254'
                domain = 'red-brick-ap'
                dhcp_option_netmask = '255.255.255.0'

                for l in lines:
                    if l.strip().strip(' ') == '#Enabled':
                        dns_dhcp_enabled = True
                    elif l.strip().strip(' ') == '#Disabled':
                        dns_dhcp_enabled = False

                    l_split = l.strip().split('=')

                    if len(l_split) != 2:
                        continue

                    if l_split[0].strip(' ') == 'dhcp-range':
                        dhcp_range = l_split[1].strip(' ').split(',')
                        dhcp_range_start = dhcp_range[0]
                        dhcp_range_end = dhcp_range[1]

                    elif l_split[0].strip(' ') == 'domain':
                        domain = l_split[1].strip(' ')

                    elif l_split[0].strip(' ') == 'dhcp-option':
                        dhcp_option = l_split[1].strip(' ').split(',')

                        if len(dhcp_option) == 2:
                            if dhcp_option[0].strip(' ') == 'option:netmask':
                                dhcp_option_netmask = dhcp_option[1]

                self.chkbox_ap_enable_dns_dhcp.setChecked(dns_dhcp_enabled)

                if domain:
                    self.ledit_ap_domain.setText(domain)

                dhcp_range_start_list = dhcp_range_start.split('.')
                dhcp_range_end_list = dhcp_range_end.split('.')
                dhcp_option_netmask_list = dhcp_option_netmask.split('.')

                self.sbox_ap_pool_start1.setValue(int(
                    dhcp_range_start_list[0]))
                self.sbox_ap_pool_start2.setValue(int(
                    dhcp_range_start_list[1]))
                self.sbox_ap_pool_start3.setValue(int(
                    dhcp_range_start_list[2]))
                self.sbox_ap_pool_start4.setValue(int(
                    dhcp_range_start_list[3]))

                self.sbox_ap_pool_end1.setValue(int(dhcp_range_end_list[0]))
                self.sbox_ap_pool_end2.setValue(int(dhcp_range_end_list[1]))
                self.sbox_ap_pool_end3.setValue(int(dhcp_range_end_list[2]))
                self.sbox_ap_pool_end4.setValue(int(dhcp_range_end_list[3]))

                self.sbox_ap_pool_mask1.setValue(
                    int(dhcp_option_netmask_list[0]))
                self.sbox_ap_pool_mask2.setValue(
                    int(dhcp_option_netmask_list[1]))
                self.sbox_ap_pool_mask3.setValue(
                    int(dhcp_option_netmask_list[2]))
                self.sbox_ap_pool_mask4.setValue(
                    int(dhcp_option_netmask_list[3]))
            except Exception as e:
                QMessageBox.critical(
                    get_main_window(), 'Settings | Access Point',
                    'Error parsing dnsmasq.conf file:\n\n{0}'.format(e))

            self.update_ui_state()

        def cb_text_file_error(title, kind, error):
            self.update_ui_state()

            kind_text = {
                TextFile.ERROR_KIND_OPEN: 'opening',
                TextFile.ERROR_KIND_READ: 'reading',
                TextFile.ERROR_KIND_UTF8: 'decoding'
            }

            QMessageBox.critical(
                get_main_window(), 'Settings | Access Point',
                'Error {0} {1} file:\n\n{2}'.format(kind_text[kind], title,
                                                    error))

        TextFile.read_async(
            self.session, HOSTAPD_CONF_PATH,
            cb_hostapd_conf_content, lambda kind, error: cb_text_file_error(
                'hostapd.conf', kind, error))

        TextFile.read_async(
            self.session, DNSMASQ_CONF_PATH,
            cb_dnsmasq_conf_content, lambda kind, error: cb_text_file_error(
                'dnsmasq.conf', kind, error))
    def read_config_files(self):
        def cb_hostapd_conf_content(content):
            if not self.is_tab_on_focus or len(content) == 0:
                return

            def cb_settings_ap_get_interfaces(result):
                if not self.is_tab_on_focus:
                    return

                if result and not result.stderr and result.exit_code == 0:
                    ap_mode_interfaces = json.loads(result.stdout)

                    if len(ap_mode_interfaces) <= 0:
                        self.label_ap_status.setText('Inactive - No wireless interface available')
                        self.cbox_ap_interface.clear()
                        self.pbutton_ap_save.setEnabled(False)
                        self.update_ui_state()
                        return

                    self.pbutton_ap_save.setEnabled(True)
                    self.cbox_ap_interface.clear()

                    self.cbox_ap_interface.currentIndexChanged.disconnect()

                    for intf in ap_mode_interfaces:
                        self.cbox_ap_interface.addItem(intf)
                        current_item_index = self.cbox_ap_interface.count() - 1

                        if ap_mode_interfaces[intf]['ip']:
                            self.cbox_ap_interface.setItemData(current_item_index,
                                                               ap_mode_interfaces[intf]['ip'],
                                                               AP_INTERFACE_IP_USER_ROLE)
                        else:
                            self.cbox_ap_interface.setItemData(current_item_index,
                                                               '192.168.42.1',
                                                               AP_INTERFACE_IP_USER_ROLE)

                        if ap_mode_interfaces[intf]['mask']:
                            self.cbox_ap_interface.setItemData(current_item_index,
                                                               ap_mode_interfaces[intf]['mask'],
                                                               AP_INTERFACE_MASK_USER_ROLE)

                        else:
                            self.cbox_ap_interface.setItemData(current_item_index,
                                                               '255.255.255.0',
                                                               AP_INTERFACE_MASK_USER_ROLE)
                    self.cbox_ap_interface.setCurrentIndex(-1)
                    self.cbox_ap_interface.currentIndexChanged.connect(self.slot_cbox_ap_interface_current_index_changed)

                    if not interface:
                        self.cbox_ap_interface.setCurrentIndex(0)

                    elif not interface and self.cbox_ap_interface.count() > 0:
                        self.cbox_ap_interface.setCurrentIndex(0)

                    else:
                        broke = False
                        for i in range(0, self.cbox_ap_interface.count()):
                            if self.cbox_ap_interface.itemText(i) == interface:
                                self.cbox_ap_interface.setCurrentIndex(i)
                                broke = True
                                break

                        if not broke:
                            self.cbox_ap_interface.setCurrentIndex(0)
                else:
                    QtGui.QMessageBox.critical(get_main_window(),
                                               'Settings | Access Point',
                                               'Error getting access point interfaces:\n\n' + result.stderr)

                self.update_ui_state()

            try:
                lines       = content.splitlines()
                interface   = ''
                ssid        = ''
                channel     = 1
                ssid_hidden = '0'
                wpa_key     = ''

                for l in lines:
                    l_split = l.strip().split('=')

                    if len(l_split) != 2:
                        continue

                    if l_split[0].strip(' ') == 'interface':
                        interface = l_split[1].strip(' ')

                    elif l_split[0].strip(' ') == 'ssid':
                        ssid = l_split[1].strip(' ')

                    elif l_split[0].strip(' ') == 'channel':
                        channel = l_split[1].strip(' ')

                    elif l_split[0].strip(' ') == 'ignore_broadcast_ssid':
                        ssid_hidden = l_split[1].strip(' ')

                    elif l_split[0].strip(' ') == 'wpa_passphrase':
                        wpa_key = l_split[1]

                self.script_manager.execute_script('settings_ap_get_interfaces',
                                                   cb_settings_ap_get_interfaces)
                self.ledit_ap_ssid.setText(ssid)
                self.chkbox_ap_ssid_hidden.setChecked(ssid_hidden != '0')

                self.sbox_ap_channel.setValue(int(channel))
                self.ledit_ap_wpa_key.setText(wpa_key)
            except Exception as e:
                QtGui.QMessageBox.critical(get_main_window(),
                                           'Settings | Access Point',
                                           'Error parsing hostapd.conf file:\n\n{0}'.format(e))

            self.update_ui_state()

        def cb_dnsmasq_conf_content(content):
            if not self.is_tab_on_focus or len(content) == 0:
                return

            try:
                lines               = content.splitlines()
                dns_dhcp_enabled    = True
                dhcp_range_start    = '192.168.42.50'
                dhcp_range_end      = '192.168.42.254'
                domain              = 'red-brick-ap'
                dhcp_option_netmask = '255.255.255.0'

                for l in lines:
                    if l.strip().strip(' ') == '#Enabled':
                        dns_dhcp_enabled = True
                    elif l.strip().strip(' ') == '#Disabled':
                        dns_dhcp_enabled = False

                    l_split = l.strip().split('=')

                    if len(l_split) != 2:
                        continue

                    if l_split[0].strip(' ') == 'dhcp-range':
                        dhcp_range = l_split[1].strip(' ').split(',')
                        dhcp_range_start = dhcp_range[0]
                        dhcp_range_end = dhcp_range[1]

                    elif l_split[0].strip(' ') == 'domain':
                        domain= l_split[1].strip(' ')

                    elif l_split[0].strip(' ') == 'dhcp-option':
                        dhcp_option = l_split[1].strip(' ').split(',')
                        if len(dhcp_option) == 2:
                            if dhcp_option[0].strip(' ') == 'option:netmask':
                                dhcp_option_netmask = dhcp_option[1]

                self.chkbox_ap_enable_dns_dhcp.setChecked(dns_dhcp_enabled)

                if domain:
                    self.ledit_ap_domain.setText(domain)

                dhcp_range_start_list = dhcp_range_start.split('.')
                dhcp_range_end_list = dhcp_range_end.split('.')
                dhcp_option_netmask_list = dhcp_option_netmask.split('.')

                self.sbox_ap_pool_start1.setValue(int(dhcp_range_start_list[0]))
                self.sbox_ap_pool_start2.setValue(int(dhcp_range_start_list[1]))
                self.sbox_ap_pool_start3.setValue(int(dhcp_range_start_list[2]))
                self.sbox_ap_pool_start4.setValue(int(dhcp_range_start_list[3]))

                self.sbox_ap_pool_end1.setValue(int(dhcp_range_end_list[0]))
                self.sbox_ap_pool_end2.setValue(int(dhcp_range_end_list[1]))
                self.sbox_ap_pool_end3.setValue(int(dhcp_range_end_list[2]))
                self.sbox_ap_pool_end4.setValue(int(dhcp_range_end_list[3]))

                self.sbox_ap_pool_mask1.setValue(int(dhcp_option_netmask_list[0]))
                self.sbox_ap_pool_mask2.setValue(int(dhcp_option_netmask_list[1]))
                self.sbox_ap_pool_mask3.setValue(int(dhcp_option_netmask_list[2]))
                self.sbox_ap_pool_mask4.setValue(int(dhcp_option_netmask_list[3]))
            except Exception as e:
                QtGui.QMessageBox.critical(get_main_window(),
                                           'Settings | Access Point',
                                           'Error parsing dnsmasq.conf file:\n\n{0}'.format(e))

            self.update_ui_state()

        def cb_text_file_error(title, kind, error):
            self.update_ui_state()

            kind_text = {
            TextFile.ERROR_KIND_OPEN: 'opening',
            TextFile.ERROR_KIND_READ: 'reading',
            TextFile.ERROR_KIND_UTF8: 'decoding'
            }

            QtGui.QMessageBox.critical(get_main_window(),
                                       'Settings | Access Point',
                                       'Error {0} {1} file:\n\n{2}'.format(kind_text[kind], title, error))

        TextFile.read_async(self.session, HOSTAPD_CONF_PATH,
                            cb_hostapd_conf_content,
                            lambda kind, error: cb_text_file_error('hostapd.conf', kind, error))

        TextFile.read_async(self.session, DNSMASQ_CONF_PATH,
                            cb_dnsmasq_conf_content,
                            lambda kind, error: cb_text_file_error('hostapd.conf', kind, error))