We can now enable tethering on the device. The user still has to reconnect to the wifi network after disabling tethering, the network manager is lazy. 
old-commit-hash: ec671d4741
commatwo_master
grekiki 4 years ago committed by GitHub
parent fb9298b120
commit c76d239a8e
  1. 39
      selfdrive/ui/qt/offroad/wifi.cc
  2. 4
      selfdrive/ui/qt/offroad/wifi.hpp
  3. 87
      selfdrive/ui/qt/offroad/wifiManager.cc
  4. 8
      selfdrive/ui/qt/offroad/wifiManager.hpp

@ -6,7 +6,7 @@
#include <QLineEdit>
#include "wifi.hpp"
#include "widgets/toggle.hpp"
void clearLayout(QLayout* layout) {
while (QLayoutItem* item = layout->takeAt(0)) {
@ -30,9 +30,31 @@ WifiUI::WifiUI(QWidget *parent, int page_length) : QWidget(parent), networks_per
// Networks page
wifi_widget = new QWidget;
QVBoxLayout* networkLayout = new QVBoxLayout;
QHBoxLayout *tethering_field = new QHBoxLayout;
tethering_field->addWidget(new QLabel("Enable Tethering"));
Toggle* toggle_switch = new Toggle(this);
toggle_switch->setFixedSize(150, 100);
tethering_field->addWidget(toggle_switch);
if (wifi->tetheringEnabled()){
toggle_switch->togglePosition();
}
QObject::connect(toggle_switch, SIGNAL(stateChanged(int)), this, SLOT(toggleTethering(int)));
QWidget* tetheringWidget = new QWidget;
tetheringWidget->setLayout(tethering_field);
tetheringWidget->setFixedHeight(150);
networkLayout->addWidget(tetheringWidget);
vlayout = new QVBoxLayout;
wifi_widget->setLayout(vlayout);
swidget->addWidget(wifi_widget);
networkLayout->addWidget(wifi_widget);
QWidget* networkWidget = new QWidget;
networkWidget->setLayout(networkLayout);
swidget->addWidget(networkWidget);
// Keyboard page
input_field = new InputField();
@ -163,11 +185,19 @@ void WifiUI::refresh() {
vlayout->addWidget(w);
}
void WifiUI::toggleTethering(int enable){
if(enable){
wifi->enableTethering();
}else{
wifi->disableTethering();
}
}
void WifiUI::handleButton(QAbstractButton* button) {
QPushButton* btn = static_cast<QPushButton*>(button);
Network n = wifi->seen_networks[connectButtons->id(btn)];
input_field->setPromptText("Enter password for \"" + n.ssid + "\"");
connectToNetwork(n);
}
@ -176,6 +206,7 @@ void WifiUI::connectToNetwork(Network n){
if(n.security_type == SecurityType::OPEN){
wifi->connect(n);
} else if (n.security_type == SecurityType::WPA){
input_field->setPromptText("Enter password for \"" + n.ssid + "\"");
QString password = getStringFromUser();
if(password.size()){
wifi->connect(n, password);

@ -15,7 +15,7 @@ class WifiUI : public QWidget {
public:
int page;
explicit WifiUI(QWidget *parent = 0, int page_length = 6);
explicit WifiUI(QWidget *parent = 0, int page_length = 5);
private:
WifiManager* wifi;
@ -30,12 +30,14 @@ private:
QTimer *timer;
QString text;
QButtonGroup *connectButtons;
bool tetheringEnabled;
void connectToNetwork(Network n);
QString getStringFromUser();
private slots:
void handleButton(QAbstractButton* m_button);
void toggleTethering(int enable);
void refresh();
void receiveText(QString text);
void wrongPassword(QString ssid);

@ -1,11 +1,26 @@
#include <algorithm>
#include <set>
#include <stdlib.h>
#include <iostream>
#include "wifiManager.hpp"
#include "common/params.h"
/**
* We are using a NetworkManager DBUS API : https://developer.gnome.org/NetworkManager/1.26/spec.html
* */
// https://developer.gnome.org/NetworkManager/1.26/nm-dbus-types.html#NM80211ApFlags
const int NM_802_11_AP_FLAGS_PRIVACY = 0x00000001;
// https://developer.gnome.org/NetworkManager/1.26/nm-dbus-types.html#NM80211ApSecurityFlags
const int NM_802_11_AP_SEC_PAIR_WEP40 = 0x00000001;
const int NM_802_11_AP_SEC_PAIR_WEP104 = 0x00000002;
const int NM_802_11_AP_SEC_GROUP_WEP40 = 0x00000010;
const int NM_802_11_AP_SEC_GROUP_WEP104 = 0x00000020;
const int NM_802_11_AP_SEC_KEY_MGMT_PSK = 0x00000100;
const int NM_802_11_AP_SEC_KEY_MGMT_802_1X = 0x00000200;
QString nm_path = "/org/freedesktop/NetworkManager";
QString nm_settings_path = "/org/freedesktop/NetworkManager/Settings";
@ -40,8 +55,10 @@ bool compare_by_strength(const Network &a, const Network &b){
return a.strength > b.strength;
}
WifiManager::WifiManager(){
qDBusRegisterMetaType<Connection>();
qDBusRegisterMetaType<IpConfig>();
connecting_to_network = "";
adapter = get_adapter();
has_adapter = adapter != "";
@ -54,6 +71,13 @@ WifiManager::WifiManager(){
raw_adapter_state = get_response<uint>(response);
change(raw_adapter_state, 0, 0);
}
// Compute 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));
}
}
void WifiManager::refreshNetworks(){
@ -116,9 +140,12 @@ SecurityType WifiManager::getSecurityType(QString path){
int rsnflag = get_property(path, "RsnFlags").toInt();
int wpa_props = wpaflag | rsnflag;
// obtained by looking at flags of networks in the office as reported by an Android phone
const int supports_wpa = NM_802_11_AP_SEC_PAIR_WEP40 | NM_802_11_AP_SEC_PAIR_WEP104 | NM_802_11_AP_SEC_GROUP_WEP40 | NM_802_11_AP_SEC_GROUP_WEP104 | NM_802_11_AP_SEC_KEY_MGMT_PSK;
if (sflag == 0){
return SecurityType::OPEN;
} else if((sflag & 0x1) && (wpa_props & (0x333) && !(wpa_props & 0x200))) {
} else if ((sflag & NM_802_11_AP_FLAGS_PRIVACY) && (wpa_props & supports_wpa) && !(wpa_props & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) {
return SecurityType::WPA;
} else {
return SecurityType::UNSUPPORTED;
@ -135,10 +162,7 @@ void WifiManager::connect(Network n, QString password){
void WifiManager::connect(Network n, QString username, QString password){
connecting_to_network = n.ssid;
QString active_ap = get_active_ap();
if(active_ap!="" && active_ap!="/"){
deactivate_connections(get_property(active_ap, "Ssid")); //Disconnect from any connected networks
}
disconnect();
clear_connections(n.ssid); //Clear all connections that may already exist to the network we are connecting
connect(n.ssid, username, password, n.security_type);
}
@ -147,8 +171,8 @@ void WifiManager::connect(QByteArray ssid, QString username, QString password, S
Connection connection;
connection["connection"]["type"] = "802-11-wireless";
connection["connection"]["uuid"] = QUuid::createUuid().toString().remove('{').remove('}');
connection["connection"]["id"] = "OpenPilot connection "+QString::fromStdString(ssid.toStdString());
connection["connection"]["autoconnect-retries"] = 0;
connection["802-11-wireless"]["ssid"] = ssid;
connection["802-11-wireless"]["mode"] = "infrastructure";
@ -163,7 +187,7 @@ void WifiManager::connect(QByteArray ssid, QString username, QString password, S
connection["ipv6"]["method"] = "ignore";
QDBusInterface nm_settings(nm_service, nm_settings_path, nm_settings_iface, bus);
QDBusReply<QDBusObjectPath> result = nm_settings.call("AddConnection", QVariant::fromValue(connection));
nm_settings.call("AddConnection", QVariant::fromValue(connection));
}
void WifiManager::deactivate_connections(QString ssid){
@ -294,3 +318,52 @@ void WifiManager::change(unsigned int new_state,unsigned int previous_state,unsi
connecting_to_network = "";
}
}
void WifiManager::disconnect(){
QString active_ap = get_active_ap();
if (active_ap!="" && active_ap!="/"){
deactivate_connections(get_property(active_ap, "Ssid"));
}
}
//Functions for tethering
void WifiManager::enableTethering(){
disconnect();
Connection connection;
connection["connection"]["id"] = "Hotspot";
connection["connection"]["uuid"] = QUuid::createUuid().toString().remove('{').remove('}');
connection["connection"]["type"] = "802-11-wireless";
connection["connection"]["interface-name"] = "wlan0";
connection["802-11-wireless"]["band"] = "bg";
connection["802-11-wireless"]["mode"] = "ap";
connection["802-11-wireless"]["ssid"] = tethering_ssid.toUtf8();
connection["802-11-wireless-security"]["group"] = QStringList("ccmp");
connection["802-11-wireless-security"]["key-mgmt"] = "wpa-psk";
connection["802-11-wireless-security"]["pairwise"] = QStringList("ccmp");
connection["802-11-wireless-security"]["proto"] = QStringList("rsn");
connection["802-11-wireless-security"]["psk"] = "swagswagcomma";
connection["ipv4"]["method"] = "shared";
QMap<QString,QVariant> adress1;
adress1["address"] = "192.168.43.1";
adress1["prefix"] = 24u;
connection["ipv4"]["address-data"] = QVariant::fromValue(IpConfig() << adress1);
connection["ipv4"]["gateway"] = "192.168.43.1";
connection["ipv6"]["method"] = "ignore";
QDBusInterface nm_settings(nm_service, nm_settings_path, nm_settings_iface, bus);
nm_settings.call("AddConnection", QVariant::fromValue(connection));
}
void WifiManager::disableTethering(){
clear_connections(tethering_ssid);
}
bool WifiManager::tetheringEnabled(){
QString active_ap = get_active_ap();
return get_property(active_ap, "Ssid") == tethering_ssid;
}

@ -15,6 +15,7 @@ enum class ConnectedType{
};
typedef QMap<QString, QMap<QString, QVariant>> Connection;
typedef QVector<QMap<QString, QVariant>> IpConfig;
struct Network {
QString path;
@ -37,6 +38,11 @@ public:
void connect(Network ssid);
void connect(Network ssid, QString password);
void connect(Network ssid, QString username, QString password);
// Tethering functions
void enableTethering();
void disableTethering();
bool tetheringEnabled();
private:
QVector<QByteArray> seen_ssids;
@ -44,6 +50,7 @@ private:
QDBusConnection bus = QDBusConnection::systemBus();
unsigned int raw_adapter_state;//Connection status https://developer.gnome.org/NetworkManager/1.26/nm-dbus-types.html#NMDeviceState
QString connecting_to_network;
QString tethering_ssid;
QString get_adapter();
QList<Network> get_networks();
@ -56,6 +63,7 @@ private:
QByteArray get_property(QString network_path, QString property);
unsigned int get_ap_strength(QString network_path);
SecurityType getSecurityType(QString ssid);
void disconnect();
private slots:
void change(unsigned int new_state, unsigned int previous_state, unsigned int change_reason);

Loading…
Cancel
Save