diff --git a/selfdrive/ui/qt/offroad/networking.cc b/selfdrive/ui/qt/offroad/networking.cc index bb35bead3..5f78d7c5e 100644 --- a/selfdrive/ui/qt/offroad/networking.cc +++ b/selfdrive/ui/qt/offroad/networking.cc @@ -26,26 +26,7 @@ void NetworkStrengthWidget::paintEvent(QPaintEvent* event) { Networking::Networking(QWidget* parent, bool show_advanced) : QWidget(parent), show_advanced(show_advanced) { main_layout = new QStackedLayout(this); - QLabel* warning = new QLabel("Network manager is inactive!"); - warning->setAlignment(Qt::AlignCenter); - warning->setStyleSheet(R"(font-size: 65px;)"); - - main_layout->addWidget(warning); - - QTimer* timer = new QTimer(this); - QObject::connect(timer, &QTimer::timeout, this, &Networking::requestScan); - timer->start(5000); - attemptInitialization(); -} - -void Networking::attemptInitialization() { - // Checks if network manager is active - try { - wifi = new WifiManager(this); - } catch (std::exception &e) { - return; - } - + wifi = new WifiManager(this); connect(wifi, &WifiManager::wrongPassword, this, &Networking::wrongPassword); connect(wifi, &WifiManager::refreshSignal, this, &Networking::refresh); @@ -66,7 +47,6 @@ void Networking::attemptInitialization() { wifiWidget->setObjectName("wifiWidget"); connect(wifiWidget, &WifiUI::connectToNetwork, this, &Networking::connectToNetwork); vlayout->addWidget(new ScrollView(wifiWidget, this), 1); - main_layout->addWidget(wifiScreen); an = new AdvancedNetworking(this, wifi); @@ -89,29 +69,11 @@ void Networking::attemptInitialization() { } )"); main_layout->setCurrentWidget(wifiScreen); - ui_setup_complete = true; - wifi->requestScan(); -} - -void Networking::requestScan() { - if (!this->isVisible()) { - return; - } - if (!ui_setup_complete) { - attemptInitialization(); - if (!ui_setup_complete) { - return; - } - } - wifi->requestScan(); } void Networking::refresh() { - if (this->isVisible() || firstRefresh) { - wifiWidget->refresh(); - an->refresh(); - firstRefresh = false; - } + wifiWidget->refresh(); + an->refresh(); } void Networking::connectToNetwork(const Network &n) { diff --git a/selfdrive/ui/qt/offroad/networking.h b/selfdrive/ui/qt/offroad/networking.h index cb681392d..e52396507 100644 --- a/selfdrive/ui/qt/offroad/networking.h +++ b/selfdrive/ui/qt/offroad/networking.h @@ -67,14 +67,10 @@ private: QStackedLayout* main_layout = nullptr; // nm_warning, wifiScreen, advanced QWidget* wifiScreen = nullptr; AdvancedNetworking* an = nullptr; - bool ui_setup_complete = false; bool show_advanced; - bool firstRefresh = true; WifiUI* wifiWidget; WifiManager* wifi = nullptr; - void attemptInitialization(); - void requestScan(); public slots: void refresh(); diff --git a/selfdrive/ui/qt/offroad/wifiManager.cc b/selfdrive/ui/qt/offroad/wifiManager.cc index 1d839c9e6..657570e53 100644 --- a/selfdrive/ui/qt/offroad/wifiManager.cc +++ b/selfdrive/ui/qt/offroad/wifiManager.cc @@ -41,6 +41,7 @@ const QString nm_service = "org.freedesktop.NetworkManager"; const int state_connected = 100; const int state_need_auth = 60; +const int device_type_wifi = 2; const int reason_wrong_password = 8; const int dbus_timeout = 100; @@ -69,13 +70,31 @@ WifiManager::WifiManager(QWidget* parent) : QWidget(parent) { qDBusRegisterMetaType(); qDBusRegisterMetaType(); connecting_to_network = ""; - adapter = get_adapter(); - bool has_adapter = adapter != ""; - if (!has_adapter) { - throw std::runtime_error("Error connecting to NetworkManager"); + // Set tethering ssid as "weedle" + first 4 characters of a dongle id + tethering_ssid = "weedle"; + std::string bytes = Params().get("DongleId"); + if (bytes.length() >= 4) { + tethering_ssid += "-" + QString::fromStdString(bytes.substr(0,4)); } + adapter = getAdapter(); + if (!adapter.isEmpty()) { + setup(); + } else { + bus.connect(nm_service, nm_path, nm_iface, "DeviceAdded", this, SLOT(deviceAdded(QDBusObjectPath))); + } + + QTimer* timer = new QTimer(this); + QObject::connect(timer, &QTimer::timeout, this, [=]() { + if (!adapter.isEmpty() && this->isVisible()) { + requestScan(); + } + }); + timer->start(5000); +} + +void WifiManager::setup() { QDBusInterface nm(nm_service, adapter, device_iface, bus); bus.connect(nm_service, adapter, device_iface, "StateChanged", this, SLOT(stateChange(unsigned int, unsigned int, unsigned int))); bus.connect(nm_service, adapter, props_iface, "PropertiesChanged", this, SLOT(propertyChange(QString, QVariantMap, QStringList))); @@ -87,18 +106,7 @@ WifiManager::WifiManager(QWidget* parent) : QWidget(parent) { device_props.setTimeout(dbus_timeout); QDBusMessage response = device_props.call("Get", device_iface, "State"); raw_adapter_state = get_response(response); - - // Set tethering ssid as "weedle" + first 4 characters of a dongle id - tethering_ssid = "weedle"; - std::string bytes = Params().get("DongleId"); - if (bytes.length() >= 4) { - tethering_ssid+="-"+QString::fromStdString(bytes.substr(0,4)); - } - - // Create dbus interface for tethering button. This populates the introspection cache, - // making sure all future creations are non-blocking - // https://bugreports.qt.io/browse/QTBUG-14485 - QDBusInterface(nm_service, nm_settings_path, nm_settings_iface, bus); + requestScan(); } void WifiManager::refreshNetworks() { @@ -295,6 +303,13 @@ void WifiManager::forgetConnection(const QString &ssid) { } } +bool WifiManager::isWirelessAdapter(const QDBusObjectPath &path) { + QDBusInterface device_props(nm_service, path.path(), props_iface, bus); + device_props.setTimeout(dbus_timeout); + const uint deviceType = get_response(device_props.call("Get", device_iface, "DeviceType")); + return deviceType == device_type_wifi; +} + void WifiManager::requestScan() { QDBusInterface nm(nm_service, adapter, wireless_device_iface, bus); nm.setTimeout(dbus_timeout); @@ -335,36 +350,17 @@ unsigned int WifiManager::get_ap_strength(const QString &network_path) { return get_response(response); } -QString WifiManager::get_adapter() { +QString WifiManager::getAdapter() { QDBusInterface nm(nm_service, nm_path, nm_iface, bus); nm.setTimeout(dbus_timeout); - QDBusMessage response = nm.call("GetDevices"); - QVariant first = response.arguments().at(0); - - QString adapter_path = ""; - - const QDBusArgument &args = first.value(); - args.beginArray(); - while (!args.atEnd()) { - QDBusObjectPath path; - args >> path; - - // Get device type - QDBusInterface device_props(nm_service, path.path(), props_iface, bus); - device_props.setTimeout(dbus_timeout); - - QDBusMessage response = device_props.call("Get", device_iface, "DeviceType"); - uint device_type = get_response(response); - - if (device_type == 2) { // Wireless - adapter_path = path.path(); - break; + const QDBusReply> &response = nm.call("GetDevices"); + for (const QDBusObjectPath &path : response.value()) { + if (isWirelessAdapter(path)) { + return path.path(); } } - args.endArray(); - - return adapter_path; + return ""; } void WifiManager::stateChange(unsigned int new_state, unsigned int previous_state, unsigned int change_reason) { @@ -388,12 +384,19 @@ void WifiManager::propertyChange(const QString &interface, const QVariantMap &pr knownConnections = listConnections(); } if (this->isVisible()) { - refreshNetworks(); // TODO: only refresh on first scan, then use AccessPointAdded and Removed signals + refreshNetworks(); emit refreshSignal(); } } } +void WifiManager::deviceAdded(const QDBusObjectPath &path) { + if (isWirelessAdapter(path) && (adapter.isEmpty() || adapter == "/")) { + adapter = path.path(); + setup(); + } +} + void WifiManager::connectionRemoved(const QDBusObjectPath &path) { knownConnections.remove(path); } @@ -442,10 +445,9 @@ void WifiManager::activateWifiConnection(const QString &ssid) { const QDBusObjectPath &path = getConnectionPath(ssid); if (!path.path().isEmpty()) { connecting_to_network = ssid; - QString devicePath = get_adapter(); QDBusInterface nm3(nm_service, nm_path, nm_iface, bus); nm3.setTimeout(dbus_timeout); - nm3.call("ActivateConnection", QVariant::fromValue(path), QVariant::fromValue(QDBusObjectPath(devicePath)), QVariant::fromValue(QDBusObjectPath("/"))); + nm3.call("ActivateConnection", QVariant::fromValue(path), QVariant::fromValue(QDBusObjectPath(adapter)), QVariant::fromValue(QDBusObjectPath("/"))); } } @@ -494,8 +496,13 @@ void WifiManager::disableTethering() { } bool WifiManager::tetheringEnabled() { - QString active_ap = get_active_ap(); - return get_property(active_ap, "Ssid") == tethering_ssid; + if (adapter != "" && adapter != "/") { + QString active_ap = get_active_ap(); + if (active_ap != "" && active_ap != "/") { + return get_property(active_ap, "Ssid") == tethering_ssid; + } + } + return false; } void WifiManager::changeTetheringPassword(const QString &newPassword) { diff --git a/selfdrive/ui/qt/offroad/wifiManager.h b/selfdrive/ui/qt/offroad/wifiManager.h index 00f6617a8..9913bab7a 100644 --- a/selfdrive/ui/qt/offroad/wifiManager.h +++ b/selfdrive/ui/qt/offroad/wifiManager.h @@ -62,7 +62,8 @@ private: QString tethering_ssid; QString tetheringPassword = "swagswagcommma"; - QString get_adapter(); + QString getAdapter(); + bool isWirelessAdapter(const QDBusObjectPath &path); QString get_ipv4_address(); QList get_networks(); void connect(const QByteArray &ssid, const QString &username, const QString &password, SecurityType security_type); @@ -76,6 +77,7 @@ private: QDBusObjectPath getConnectionPath(const QString &ssid); QMap listConnections(); QString getConnectionSsid(const QDBusObjectPath &path); + void setup(); signals: void wrongPassword(const QString &ssid); @@ -84,6 +86,7 @@ signals: private slots: void stateChange(unsigned int new_state, unsigned int previous_state, unsigned int change_reason); void propertyChange(const QString &interface, const QVariantMap &props, const QStringList &invalidated_props); + void deviceAdded(const QDBusObjectPath &path); void connectionRemoved(const QDBusObjectPath &path); void newConnection(const QDBusObjectPath &path); };