diff --git a/CMakeLists.txt b/CMakeLists.txt index 4189a949..c19de02e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ option(DEBUG "Enable debug mode" OFF) option(RELEASE "Enable release mode" OFF) option(docker_cross "Cross compile option for docker container" OFF) set(KIPR_VERSION_MAJOR 1) -set(KIPR_VERSION_MINOR 1) +set(KIPR_VERSION_MINOR 2) set(KIPR_VERSION_PATCH 0) cmake_minimum_required(VERSION 2.8.11) diff --git a/include/botui/NetworkManager.h b/include/botui/NetworkManager.h index 3b403c3a..ff6e6629 100644 --- a/include/botui/NetworkManager.h +++ b/include/botui/NetworkManager.h @@ -50,6 +50,7 @@ class NetworkManager : public QObject, public Singleton void changeWifiBands(QString band, int channel); void requestScan(); void deactivateAP(); + void getRaspberryPiType(); bool isOn() const; diff --git a/rc/qml.qrc b/rc/qml.qrc index 4e86dfa9..d3b2d9cc 100644 --- a/rc/qml.qrc +++ b/rc/qml.qrc @@ -3,6 +3,7 @@ qml/loading.qml qml/lock.qml qml/50-screenlock.png + qml/disabled.png qml/left.png qml/right.png qml/Event_Mode_Background.png diff --git a/rc/qml/disabled.png b/rc/qml/disabled.png new file mode 100644 index 00000000..18b96786 Binary files /dev/null and b/rc/qml/disabled.png differ diff --git a/src/NetworkManager.cpp b/src/NetworkManager.cpp index af4815d3..cd694f37 100644 --- a/src/NetworkManager.cpp +++ b/src/NetworkManager.cpp @@ -275,8 +275,6 @@ void NetworkManager::changeWifiBands(QString band, int channel) qDebug() << "Correct connection ssid " << connectionSettings[NM_802_11_WIRELESS_KEY]["ssid"].toString(); QPair correctConnectionPair = getConnection(connectionSettings[NM_802_11_WIRELESS_KEY]["ssid"].toString()); - - QDBusPendingReply reply = m_nm->ActivateConnection(correctConnectionPair.second, devicePath, QDBusObjectPath("/")); reply.waitForFinished(); getReply(reply); @@ -325,6 +323,102 @@ bool NetworkManager::enableAP() qDebug() << "AP Path: " << apPath.path(); qDebug() << "AP Path Connection already exists"; qDebug() << "AP Strength: " << active().strength(); + qDebug() << "State: " << m_device->state(); + OrgFreedesktopNetworkManagerSettingsConnectionInterface connection(NM_SERVICE, apPath.path(), QDBusConnection::systemBus()); + + Connection settings = connection.GetSettings().value(); + QMap wirelessSettings = settings.value("802-11-wireless"); + + qDebug() << "Settings before anything: " << settings; + bool containsBand = wirelessSettings.contains("band"); + bool containsChannel = wirelessSettings.contains("channel"); + + qDebug() << "AP settings: " << settings; + qDebug() << "Contains band? : " << containsBand; + qDebug() << "Contains channel? : " << containsChannel; + + // Check if the settings contain "band" and "channel" + if (!containsBand || !containsChannel) + { + qDebug() << "Missing 'band' or 'channel' in AP settings. Recreating AP configuration."; + + bool activeConnectionOn = NetworkManager::ref().isActiveConnectionOn(); + + if (activeConnectionOn == true) + { + qDebug() << "Current active connection: " << m_device->activeConnection().path(); + QDBusPendingReply deactivateReply = m_nm->DeactivateConnection(m_device->activeConnection()); + deactivateReply.waitForFinished(); + + if (deactivateReply.isError()) + { + qWarning() << "Error deactivating connection:" << deactivateReply.error().message(); + return false; // Handle the error appropriately + } + else + { + qDebug() << "Connection deactivated successfully."; + } + } + + if (RASPBERRYPI_TYPE == "3B+") + { + settings[NM_802_11_WIRELESS_KEY]["band"] = "a"; + settings[NM_802_11_WIRELESS_KEY]["channel"] = 36; + } + else if (RASPBERRYPI_TYPE == "3B") + { + settings[NM_802_11_WIRELESS_KEY]["band"] = "bg"; + settings[NM_802_11_WIRELESS_KEY]["channel"] = 1; + } + + qDebug() << "Modified AP settings: band and channel added."; + + QDBusPendingReply reply = connection.Update(settings); + reply.waitForFinished(); + + if (reply.isError()) + { + qWarning() << "Error in Update:" << reply.error().message(); + return false; + } + + if (reply.isValid()) + { + qDebug() << "AP settings updated successfully."; + qDebug() << "Connection after update: " << connection.GetSettings().value(); + } + + QDBusPendingReply activateReply = m_nm->ActivateConnection(apPath, devicePath, QDBusObjectPath("/")); + activateReply.waitForFinished(); + + if (activateReply.isError()) + { + qWarning() << "Error activating connection:" << activateReply.error().message(); + return false; // Handle the error appropriately + } + else + { + qDebug() << "Connection activated successfully."; + } + + qDebug() << "Device is now active. Proceeding to reapply settings."; + + QDBusPendingReply reapplyReply = m_device->Reapply(settings, 0, 0); + reapplyReply.waitForFinished(); + + if (reapplyReply.isError()) + { + qWarning() << "Error in Reapply:" << reapplyReply.error().message(); + return false; + } + else + { + qDebug() << "Reapply successful."; + } + + return true; + } if (NetworkManager::ref().isActiveConnectionOn() == true) { @@ -332,6 +426,7 @@ bool NetworkManager::enableAP() } else if (NetworkManager::ref().isActiveConnectionOn() == false) { + turnOn(); uint stateReply; while (true) @@ -619,7 +714,7 @@ NetworkManager::NetworkManager() m_device(0), m_wifi(0), m_dev(nullptr) { - + getRaspberryPiType(); // Register our metatype with dbus qDBusRegisterMetaType(); qDBusRegisterMetaType(); @@ -682,6 +777,33 @@ NetworkManager::NetworkManager() qDebug() << "Active strength: " << active().strength(); } +void NetworkManager::getRaspberryPiType() +{ + QStringList arguments; + arguments << "-c" << "cat /proc/cpuinfo | grep Revision | awk '{print $3}'"; + + QProcess *myProcess = new QProcess(this); + myProcess->start("/bin/sh", arguments); // Use /bin/sh or /bin/bash to interpret the command + myProcess->waitForFinished(); + QByteArray output = myProcess->readAllStandardOutput(); + + qDebug() << "Revision code output: " << output; + if (output.trimmed() == "a020d3" || output.trimmed() == "a020d4") + { + RASPBERRYPI_TYPE = "3B+"; + } + else if (output.trimmed() == "a02082" || output.trimmed() == "a22082" || output.trimmed() == "a32082" || output.trimmed() == "a52082" || output.trimmed() == "a22083") + { + RASPBERRYPI_TYPE = "3B"; + } + else + { + RASPBERRYPI_TYPE = "Unknown"; + } + + qDebug() << "RASPBERRYPI_TYPE: " << RASPBERRYPI_TYPE; +} + void NetworkManager::nmAccessPointAdded(const QDBusObjectPath &accessPoint) { Network network = createAccessPoint(accessPoint); diff --git a/src/NetworkSettingsWidget.cpp b/src/NetworkSettingsWidget.cpp index fc87f129..26c23353 100644 --- a/src/NetworkSettingsWidget.cpp +++ b/src/NetworkSettingsWidget.cpp @@ -97,11 +97,12 @@ void NetworkSettingsWidget::eventModeDisabledState() getWombatName(); // Get Wombat name INITIAL_CONNECTION_CONFIG = getConnectionConfig(); // Get initial connection config - RASPBERRYPI_TYPE_SETTINGS = "3B+"; + RASPBERRYPI_TYPE_SETTINGS = getRaspberryPiType(); if (RASPBERRYPI_TYPE_SETTINGS == "3B+") // if RaspberryPi is 3B+ { - + ui->TwoFourGHZLabel->setEnabled(true); // Enable 2.4GHz label + ui->FiveGHZLabel->setEnabled(true); // Enable 5GHz label if (INITIAL_CONNECTION_CONFIG.contains("band=a")) // If currently on 5GHz band { ui->toggleSwitch->setChecked(true); // 5GHz toggle side @@ -118,6 +119,8 @@ void NetworkSettingsWidget::eventModeDisabledState() { ui->toggleSwitch->setChecked(false); // 2.4GHz toggle side ui->toggleSwitch->setEnabled(false); // If 3B, can only use 2.4GHz + ui->TwoFourGHZLabel->setEnabled(false); //Grey out 2.4GHz label + ui->FiveGHZLabel->setEnabled(false); //Grey out 5GHz label } ui->connectionModeSelect->clear(); @@ -156,15 +159,18 @@ QString NetworkSettingsWidget::getRaspberryPiType() QByteArray output = myProcess->readAllStandardOutput(); qDebug() << "Revision code output: " << output; - - if (output.contains("a020d3")) + if (output.trimmed() == "a020d3" || output.trimmed() == "a020d4") { RASPBERRYPI_TYPE_SETTINGS = "3B+"; } - else if (output.contains("a02082") || output.contains("a22082")) + else if (output.trimmed() == "a02082" || output.trimmed() == "a22082" || output.trimmed() == "a32082" || output.trimmed() == "a52082" || output.trimmed() == "a22083") { RASPBERRYPI_TYPE_SETTINGS = "3B"; } + else + { + RASPBERRYPI_TYPE_SETTINGS = "Unknown"; + } qDebug() << "RASPBERRYPI_TYPE_SETTINGS: " << RASPBERRYPI_TYPE_SETTINGS; return RASPBERRYPI_TYPE_SETTINGS; diff --git a/src/WombatUpdateWidget.cpp b/src/WombatUpdateWidget.cpp index e384c4cb..37a1948a 100644 --- a/src/WombatUpdateWidget.cpp +++ b/src/WombatUpdateWidget.cpp @@ -7,66 +7,75 @@ #include WombatUpdateWidget::WombatUpdateWidget(Device *device, QWidget *parent) - : StandardWidget(device, parent), - ui(new Ui::WombatUpdateWidget) + : StandardWidget(device, parent), + ui(new Ui::WombatUpdateWidget) { ui->setupUi(this); performStandardSetup("Update"); - + ui->updateConsole->setVisible(false); - + connect(ui->update, SIGNAL(clicked()), SLOT(update())); connect(ui->refresh, SIGNAL(clicked()), SLOT(refresh())); - connect(ui->ethernet, SIGNAL(clicked()), SLOT(ethernet())); + connect(ui->ethernet, SIGNAL(clicked()), SLOT(ethernet())); } WombatUpdateWidget::~WombatUpdateWidget() { delete ui; } - + void WombatUpdateWidget::update() -{ +{ // Get single selected item const QList selected = ui->updateList->selectedItems(); - if(selected.size() != 1) + if (selected.size() != 1) return; const QString selectedName = selected.at(0)->text(); - + // Verify with user that they want to do the update - if(QMessageBox::question(this, "Update?", - QString("Are you sure you want to update using %1?").arg(selectedName), - QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) - return; - + if (QMessageBox::question(this, "Update?", + QString("Are you sure you want to update using %1?").arg(selectedName), + QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) + return; + // Disable buttons ui->update->setEnabled(false); ui->refresh->setEnabled(false); ui->ethernet->setEnabled(false); // Mount USB drive - if(!this->mountUsb("/dev/sda1", WombatUpdateWidget::mountDir) && !this->mountUsb("/dev/sdb1", WombatUpdateWidget::mountDir)) + if (!this->mountUsb("/dev/sda1", WombatUpdateWidget::mountDir) && !this->mountUsb("/dev/sdb1", WombatUpdateWidget::mountDir)) QMessageBox::warning(this, "USB not found", "Failed to mount USB device"); - else { - // Check if update file exists - QDir subDir = WombatUpdateWidget::mountDir; - subDir.cd(selectedName); - if(!subDir.exists(WombatUpdateWidget::updateFileName)) - QMessageBox::warning(this, "File not found", "The update file no longer exists"); - else { + else + { + + // Check if selectedName contains ".zip" + if (!selectedName.contains(".zip", Qt::CaseInsensitive)) + { + QMessageBox::warning(this, "File Not Found", "The selected folder is not a .zip folder"); + } + else if (!selectedName.contains("wombat-os", Qt::CaseInsensitive)) + { + QMessageBox::warning(this, "File Not Found", "The selected folder is not a valid update file (missing wombat-os)"); + } + else + { // Change UI to show output ui->updateConsole->setVisible(true); ui->selectionWidget->setVisible(false); ui->statusLabel->setText("Update progress:"); - + // Run update process m_updateProc = new QProcess(); m_updateProc->setProcessChannelMode(QProcess::MergedChannels); - m_updateProc->setWorkingDirectory(subDir.absolutePath()); + m_updateProc->setWorkingDirectory("/home/kipr"); ui->updateConsole->setProcess(m_updateProc); connect(m_updateProc, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(updateFinished(int, QProcess::ExitStatus))); - m_updateProc->start("sh", QStringList() << WombatUpdateWidget::updateFileName); - + QString command = QString("/home/kipr/updateMe.sh %1").arg("/media/kipr/*/" + selectedName); + + m_updateProc->start("sh", QStringList() << "-c" << command); + // Update script will reboot the controller } } @@ -75,33 +84,31 @@ void WombatUpdateWidget::update() void WombatUpdateWidget::refresh() { ui->refresh->setEnabled(false); - + // Clear items ui->updateList->clear(); - + // Mount USB drive - if(!this->mountUsb("/dev/sda1", WombatUpdateWidget::mountDir) && !this->mountUsb("/dev/sdb1", WombatUpdateWidget::mountDir)) + if (!this->mountUsb("/dev/sda1", WombatUpdateWidget::mountDir) && !this->mountUsb("/dev/sdb1", WombatUpdateWidget::mountDir)) QMessageBox::warning(this, "USB not found", "Failed to mount USB device"); - else { + else + { // Look at each directory - foreach(const QString &name, WombatUpdateWidget::mountDir.entryList(QDir::NoDotAndDotDot | QDir::Dirs)) + foreach (const QString &file, WombatUpdateWidget::mountDir.entryList(QDir::Files)) { - // Filter out directories without updates - QDir subDir = WombatUpdateWidget::mountDir; - subDir.cd(name); - - if(!subDir.exists(WombatUpdateWidget::updateFileName)) + // Filter out files that aren't zip files + if (!file.contains(".zip", Qt::CaseInsensitive)) continue; - + // Add directory to the list - ui->updateList->addItem(subDir.dirName()); + ui->updateList->addItem(file); } - + // Unmount USB drive - if(!this->unmountUsb(WombatUpdateWidget::mountDir.absolutePath())) + if (!this->unmountUsb(WombatUpdateWidget::mountDir.absolutePath())) qDebug() << "Failed to unmount USB drive"; } - + ui->refresh->setEnabled(true); } @@ -109,26 +116,25 @@ void WombatUpdateWidget::updateFinished(int, QProcess::ExitStatus exitStatus) { StandardWidget::enableMenuBar(); - - //Check to see if the update failed - if(m_updateProc->exitStatus() != QProcess::NormalExit){ - ui->updateConsole->insertPlainText("\n Update Failed (Crashed): \n The update script has crashed with an error. \n Contact KIPR tech support for assistance if the problem persists \n"); - ui->updateConsole->moveCursor(QTextCursor::End, QTextCursor::KeepAnchor); - } + // Check to see if the update failed + if (m_updateProc->exitStatus() != QProcess::NormalExit) + { + ui->updateConsole->insertPlainText("\n Update Failed (Crashed): \n The update script has crashed with an error. \n Contact KIPR tech support for assistance if the problem persists \n"); + ui->updateConsole->moveCursor(QTextCursor::End, QTextCursor::KeepAnchor); + } // Cleanup process ui->updateConsole->setProcess(0); delete m_updateProc; - + // Unmount USB drive - if(!this->unmountUsb(WombatUpdateWidget::mountDir.absolutePath())) + if (!this->unmountUsb(WombatUpdateWidget::mountDir.absolutePath())) qDebug() << "Failed to unmount USB drive"; - + // Re-enable buttons ui->refresh->setEnabled(true); ui->update->setEnabled(true); - } bool WombatUpdateWidget::mountUsb(const QString device, const QDir dir) @@ -148,27 +154,25 @@ bool WombatUpdateWidget::unmountUsb(const QString device) const QString WombatUpdateWidget::updateFileName = "wombat_update.sh"; const QDir WombatUpdateWidget::mountDir = QDir("/mnt"); -void WombatUpdateWidget::ethernet(){ - if(QMessageBox::question(this, "Update?", QString("Is your controller connected to the internet over ethernet or Wifi?"), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) { +void WombatUpdateWidget::ethernet() +{ + if (QMessageBox::question(this, "Update?", QString("Is your controller connected to the internet over ethernet or Wifi?"), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) + { return; } - // Change UI to show output - ui->updateConsole->setVisible(true); - ui->selectionWidget->setVisible(false); - ui->statusLabel->setText("Update progress:"); - - - //Disables menubar (Back and Home buttons) in StandardWidget - StandardWidget::disableMenuBar(); - - - // Run update process - m_updateProc = new QProcess(); - m_updateProc->setProcessChannelMode(QProcess::MergedChannels); - ui->updateConsole->setProcess(m_updateProc); - connect(m_updateProc, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(updateFinished(int, QProcess::ExitStatus))); - m_updateProc->startCommand("sudo sh /home/kipr/updateMe.sh"); -} + // Change UI to show output + ui->updateConsole->setVisible(true); + ui->selectionWidget->setVisible(false); + ui->statusLabel->setText("Update progress:"); + // Disables menubar (Back and Home buttons) in StandardWidget + StandardWidget::disableMenuBar(); + // Run update process + m_updateProc = new QProcess(); + m_updateProc->setProcessChannelMode(QProcess::MergedChannels); + ui->updateConsole->setProcess(m_updateProc); + connect(m_updateProc, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(updateFinished(int, QProcess::ExitStatus))); + m_updateProc->startCommand("sudo sh /home/kipr/updateMe.sh"); +} diff --git a/ui/AboutWidget.ui b/ui/AboutWidget.ui index bf326af3..54aed17c 100644 --- a/ui/AboutWidget.ui +++ b/ui/AboutWidget.ui @@ -392,6 +392,9 @@ + + true + 0 diff --git a/ui/NetworkSettingsWidget.ui b/ui/NetworkSettingsWidget.ui index f149fe27..1ac02cf6 100644 --- a/ui/NetworkSettingsWidget.ui +++ b/ui/NetworkSettingsWidget.ui @@ -97,7 +97,16 @@ QCheckBox::indicator:checked{ QCheckBox::indicator:unchecked{ image:url("://qml/left.png"); -} +} + +QCheckBox::indicator:disabled:checked { + image: url("://qml/disabled.png"); +} + +QCheckBox::indicator:disabled:unchecked { + image: url("://qml/disabled.png"); +} +