From 394668483428fa2c370fd27fa4e7ee2c1328ea24 Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Fri, 15 Nov 2019 20:35:06 -0600 Subject: Qt UI: Wi-Fi --- ui/qt5/CMakeLists.txt | 2 +- ui/qt5/netsimplewifipage.cc | 113 +++++++++++++++++++++++++++++++++++++++++++- ui/qt5/netsimplewifipage.hh | 22 ++++++++- 3 files changed, 133 insertions(+), 4 deletions(-) diff --git a/ui/qt5/CMakeLists.txt b/ui/qt5/CMakeLists.txt index a5c88ab..cef07fb 100644 --- a/ui/qt5/CMakeLists.txt +++ b/ui/qt5/CMakeLists.txt @@ -26,6 +26,6 @@ IF(INSTALL) pkg_check_modules(XKBFile REQUIRED xkbfile) pkg_check_modules(LIBX11 REQUIRED x11) pkg_check_modules(LibCap REQUIRED libcap) - target_link_libraries(horizon-qt5 ${LIBUDEV_LIBRARIES} ${LibCap_LIBRARIES} ${LIBX11_LIBRARIES} ${XKBFile_LIBRARIES}) + target_link_libraries(horizon-qt5 ${BCNM} skarnet ${LIBUDEV_LIBRARIES} ${LibCap_LIBRARIES} ${LIBX11_LIBRARIES} ${XKBFile_LIBRARIES}) # add_executable(horizon-run-qt5 ${RUN_QT_SOURCES}) ENDIF(INSTALL) diff --git a/ui/qt5/netsimplewifipage.cc b/ui/qt5/netsimplewifipage.cc index 3aef02f..b1286fa 100644 --- a/ui/qt5/netsimplewifipage.cc +++ b/ui/qt5/netsimplewifipage.cc @@ -11,10 +11,18 @@ */ #include "netsimplewifipage.hh" +#include "netdhcppage.hh" -#include +#include #include +#ifdef HAS_INSTALL_ENV +int scanResults(wpactrl_t *control, char const *s, size_t len, void *page, tain_t *) { + NetworkSimpleWirelessPage *our_page = reinterpret_cast(page); + return our_page->processScan(control, s, len); +} +#endif /* HAS_INSTALL_ENV */ + NetworkSimpleWirelessPage::NetworkSimpleWirelessPage(QWidget *parent) : HorizonWizardPage(parent) { QVBoxLayout *layout; @@ -25,11 +33,24 @@ NetworkSimpleWirelessPage::NetworkSimpleWirelessPage(QWidget *parent) statusLabel = new QLabel(tr("Scanning for networks...")); rescanButton = new QPushButton(tr("&Rescan Networks")); - rescanButton->setEnabled(false); connect(rescanButton, &QPushButton::clicked, [=](void) { doScan(); }); +#ifdef HAS_INSTALL_ENV + tain_now_g(); + if(!wpactrl_start_g(&control, "/var/run/wpa_supplicant", 2000)) { + rescanButton->setEnabled(false); + statusLabel->setText(tr("Couldn't communicate with wireless subsystem.")); + } + notify = nullptr; +#endif /* HAS_INSTALL_ENV */ + ssidListView = new QListWidget; + exchange_item = { + .filter = "CTRL-EVENT-SCAN-RESULTS", + .cb = &scanResults + }; + passphrase = new QLineEdit(this); passphrase->setEchoMode(QLineEdit::Password); passphrase->setPlaceholderText(tr("Passphrase")); @@ -45,15 +66,103 @@ NetworkSimpleWirelessPage::NetworkSimpleWirelessPage(QWidget *parent) setLayout(layout); } +NetworkSimpleWirelessPage::~NetworkSimpleWirelessPage() { +#ifdef HAS_INSTALL_ENV + wpactrl_end(&control); +#endif /* HAS_INSTALL_ENV */ +} + +void NetworkSimpleWirelessPage::scanDone(QString message) { + rescanButton->setEnabled(true); + statusLabel->setText(message); +} + void NetworkSimpleWirelessPage::doScan() { +#ifdef HAS_INSTALL_ENV ssidListView->clear(); rescanButton->setEnabled(false); + statusLabel->setText(tr("Scanning for networks...")); + + tain_t deadline; + wparesponse_t response; + + response = wpactrl_command_g(&control, "SCAN"); + if(response != WPA_OK && response != WPA_FAILBUSY) { + scanDone(tr("Couldn't scan for wireless networks.")); + return; + } + + tain_from_millisecs(&deadline, 15000); + tain_add_g(&deadline, &deadline); + wpactrl_xchg_init(&exchange, &exchange_item, 1, &deadline, this); + if(!wpactrl_xchg_start(&control, &exchange)) { + scanDone(tr("Failed to scan for wireless networks.")); + return; + } + + if(notify != nullptr) { + notify->deleteLater(); + notify = nullptr; + } + + notify = new QSocketNotifier(wpactrl_fd(&control), QSocketNotifier::Read, this); + connect(notify, &QSocketNotifier::activated, [=](int) { + QString status; + + if(wpactrl_xchg_timeout_g(&control, &exchange)) { + status = tr("Network scan timed out."); + } else { + if(wpactrl_update(&control) < 0) { + status = tr("Issue communicating with wireless subsystem."); + } else { + int code = wpactrl_xchg_event_g(&control, &exchange); + if(code < 0) { + status = tr("Issue processing scanned networks."); + } else if(code == 0) { + /* Not finished yet, so don't do anything. */ + return; + } else { + status = tr("Scan successful."); + } + } + } + notify->setEnabled(false); + notify->deleteLater(); + notify = nullptr; + statusLabel->setText(status); + return; + }); + notify->setEnabled(true); +#endif /* HAS_INSTALL_ENV */ } void NetworkSimpleWirelessPage::initializePage() { doScan(); } +bool NetworkSimpleWirelessPage::isComplete() const { + return (ssidListView->currentRow() != -1); +} + int NetworkSimpleWirelessPage::nextId() const { return HorizonWizard::Page_Network_DHCP; } + +#ifdef HAS_INSTALL_ENV +int NetworkSimpleWirelessPage::processScan(wpactrl_t *c, const char *s, size_t len) { + assert(c == &control); + QString network(s); + ssidListView->addItem(network); + return 0; +} +#endif /* HAS_INSTALL_ENV */ + +bool NetworkSimpleWirelessPage::validatePage() { + /* What a hack! + * + * Independent Pages means the DHCP page is never cleaned, even when Back + * is chosen. So, we have to do it from here. */ + horizonWizard()->removePage(HorizonWizard::Page_Network_DHCP); + horizonWizard()->setPage(HorizonWizard::Page_Network_DHCP, new NetDHCPPage); + return true; +} diff --git a/ui/qt5/netsimplewifipage.hh b/ui/qt5/netsimplewifipage.hh index f199903..ab5187b 100644 --- a/ui/qt5/netsimplewifipage.hh +++ b/ui/qt5/netsimplewifipage.hh @@ -15,6 +15,11 @@ #include "horizonwizardpage.hh" +#ifdef HAS_INSTALL_ENV +# include +# include +#endif /* HAS_INSTALL_ENV */ + #include #include #include @@ -24,16 +29,31 @@ class NetworkSimpleWirelessPage : public HorizonWizardPage { public: NetworkSimpleWirelessPage(QWidget *parent = nullptr); + ~NetworkSimpleWirelessPage(); void initializePage(); - void doScan(); + bool isComplete() const; int nextId() const; + bool validatePage(); private: QLabel *statusLabel; QPushButton *rescanButton; QListWidget *ssidListView; QLineEdit *passphrase; + + void doScan(); + void scanDone(QString message); + +#ifdef HAS_INSTALL_ENV + wpactrl_t control; + wpactrl_xchg_t exchange; + wpactrl_xchgitem_t exchange_item; + QSocketNotifier *notify; + + int processScan(wpactrl_t *, const char *, size_t); + friend int scanResults(wpactrl_t *, char const *, size_t, void *, tain_t *); +#endif /* HAS_INSTALL_ENV */ }; #endif /* !NETWORKSIMPLEWIRELESSPAGE_HH */ -- cgit v1.2.3-60-g2f50