diff --git a/QGCCommon.pri b/QGCCommon.pri
index 9c72586..5f162ab 100644
--- a/QGCCommon.pri
+++ b/QGCCommon.pri
@@ -22,6 +22,7 @@ linux {
CONFIG += LinuxBuild
DEFINES += __STDC_LIMIT_MACROS
DEFINES += QGC_GST_TAISYNC_ENABLED
+ DEFINES += QGC_GST_MICROHARD_ENABLED
linux-clang {
message("Linux clang")
QMAKE_CXXFLAGS += -Qunused-arguments -fcolor-diagnostics
@@ -31,12 +32,14 @@ linux {
CONFIG += LinuxBuild
DEFINES += __STDC_LIMIT_MACROS __rasp_pi2__
DEFINES += QGC_GST_TAISYNC_ENABLED
+ DEFINES += QGC_GST_MICROHARD_ENABLED
} else : android-g++ | android-clang {
CONFIG += AndroidBuild MobileBuild
DEFINES += __android__
DEFINES += __STDC_LIMIT_MACROS
DEFINES += QGC_ENABLE_BLUETOOTH
DEFINES += QGC_GST_TAISYNC_ENABLED
+ DEFINES += QGC_GST_MICROHARD_ENABLED
target.path = $$DESTDIR
equals(ANDROID_TARGET_ARCH, x86) {
CONFIG += Androidx86Build
@@ -54,6 +57,7 @@ linux {
CONFIG += WindowsBuild
DEFINES += __STDC_LIMIT_MACROS
DEFINES += QGC_GST_TAISYNC_ENABLED
+ DEFINES += QGC_GST_MICROHARD_ENABLED
} else {
error("Unsupported Windows toolchain, only Visual Studio 2015 is supported")
}
@@ -64,6 +68,7 @@ linux {
CONFIG += x86_64
CONFIG -= x86
DEFINES += QGC_GST_TAISYNC_ENABLED
+ DEFINES += QGC_GST_MICROHARD_ENABLED
equals(QT_MAJOR_VERSION, 5) | greaterThan(QT_MINOR_VERSION, 5) {
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
} else {
diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro
index c024873..79b2919 100644
--- a/qgroundcontrol.pro
+++ b/qgroundcontrol.pro
@@ -1149,6 +1149,23 @@ contains (DEFINES, QGC_GST_TAISYNC_ENABLED) {
}
#-------------------------------------------------------------------------------------
+# Microhard
+contains (DEFINES, QGC_GST_MICROHARD_ENABLED) {
+ INCLUDEPATH += \
+ src/Microhard
+
+ HEADERS += \
+ src/Microhard/MicrohardManager.h \
+ src/Microhard/MicrohardHandler.h \
+ src/Microhard/MicrohardSettings.h \
+
+ SOURCES += \
+ src/Microhard/MicrohardManager.cc \
+ src/Microhard/MicrohardHandler.cc \
+ src/Microhard/MicrohardSettings.cc \
+}
+
+#-------------------------------------------------------------------------------------
# AirMap
contains (DEFINES, QGC_AIRMAP_ENABLED) {
diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index b811f36..c414f09 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -201,6 +201,7 @@
src/AutoPilotPlugins/Common/SyslinkComponent.qml
src/ui/preferences/TcpSettings.qml
src/Taisync/TaisyncSettings.qml
+ src/Microhard/MicrohardSettings.qml
src/test.qml
src/ui/preferences/UdpSettings.qml
src/FlightMap/Widgets/ValuePageWidget.qml
diff --git a/src/Microhard/MicrohardHandler.cc b/src/Microhard/MicrohardHandler.cc
new file mode 100644
index 0000000..ee61f46
--- /dev/null
+++ b/src/Microhard/MicrohardHandler.cc
@@ -0,0 +1,62 @@
+/****************************************************************************
+ *
+ * (c) 2019 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+#include "MicrohardHandler.h"
+#include "SettingsManager.h"
+#include "QGCApplication.h"
+#include "VideoManager.h"
+
+QGC_LOGGING_CATEGORY(MicrohardLog, "MicrohardLog")
+QGC_LOGGING_CATEGORY(MicrohardVerbose, "MicrohardVerbose")
+
+//-----------------------------------------------------------------------------
+MicrohardHandler::MicrohardHandler(QObject* parent)
+ : QObject (parent)
+{
+}
+
+//-----------------------------------------------------------------------------
+MicrohardHandler::~MicrohardHandler()
+{
+ close();
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardHandler::close()
+{
+ bool res = false;
+ if(_tcpSocket) {
+ qCDebug(MicrohardLog) << "Close Microhard TCP socket on port" << _tcpSocket->localPort();
+ _tcpSocket->close();
+ _tcpSocket->deleteLater();
+ _tcpSocket = nullptr;
+ res = true;
+ }
+ return res;
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardHandler::_start(uint16_t port, QHostAddress addr)
+{
+ close();
+
+ _tcpSocket = new QTcpSocket();
+ QObject::connect(_tcpSocket, &QIODevice::readyRead, this, &MicrohardHandler::_readBytes);
+ qCDebug(MicrohardLog) << "Connecting to" << addr;
+ _tcpSocket->connectToHost(addr, port);
+ if (!_tcpSocket->waitForConnected(1000)) {
+ close();
+ return false;
+ }
+ emit connected();
+
+ return true;
+}
diff --git a/src/Microhard/MicrohardHandler.h b/src/Microhard/MicrohardHandler.h
new file mode 100644
index 0000000..1e46792
--- /dev/null
+++ b/src/Microhard/MicrohardHandler.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+ *
+ * (c) 2019 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+#pragma once
+
+#include "QGCLoggingCategory.h"
+
+#include
+#include
+
+#define MICROHARD_SETTINGS_PORT 23
+
+Q_DECLARE_LOGGING_CATEGORY(MicrohardLog)
+Q_DECLARE_LOGGING_CATEGORY(MicrohardVerbose)
+
+class MicrohardHandler : public QObject
+{
+ Q_OBJECT
+public:
+
+ explicit MicrohardHandler (QObject* parent = nullptr);
+ ~MicrohardHandler ();
+ virtual bool start () = 0;
+ virtual bool close ();
+
+protected:
+ virtual bool _start (uint16_t port, QHostAddress addr = QHostAddress::AnyIPv4);
+
+protected slots:
+ virtual void _readBytes () = 0;
+
+signals:
+ void connected ();
+ void rssiUpdated (int rssi);
+
+protected:
+ QTcpSocket* _tcpSocket = nullptr;
+};
diff --git a/src/Microhard/MicrohardManager.cc b/src/Microhard/MicrohardManager.cc
new file mode 100644
index 0000000..4735de1
--- /dev/null
+++ b/src/Microhard/MicrohardManager.cc
@@ -0,0 +1,272 @@
+/****************************************************************************
+ *
+ * (c) 2019 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+#include "MicrohardManager.h"
+#include "MicrohardSettings.h"
+#include "SettingsManager.h"
+#include "QGCApplication.h"
+#include "QGCCorePlugin.h"
+
+#include
+
+#define LONG_TIMEOUT 5000
+
+static const char *kMICROHARD_GROUP = "Microhard";
+static const char *kLOCAL_IP = "LocalIP";
+static const char *kREMOTE_IP = "RemoteIP";
+static const char *kGROUND_IP = "GroundIP";
+static const char *kAIR_IP = "AirIP";
+static const char *kNET_MASK = "NetMask";
+static const char *kCFG_PASSWORD = "ConfigPassword";
+static const char *kENC_KEY = "EncryptionKey";
+
+//-----------------------------------------------------------------------------
+MicrohardManager::MicrohardManager(QGCApplication* app, QGCToolbox* toolbox)
+ : QGCTool(app, toolbox)
+{
+ connect(&_workTimer, &QTimer::timeout, this, &MicrohardManager::_checkMicrohard);
+ _workTimer.setSingleShot(true);
+ connect(&_locTimer, &QTimer::timeout, this, &MicrohardManager::_locTimeout);
+ connect(&_remTimer, &QTimer::timeout, this, &MicrohardManager::_remTimeout);
+ QSettings settings;
+ settings.beginGroup(kMICROHARD_GROUP);
+ _localIPAddr = settings.value(kLOCAL_IP, QString("192.168.168.1")).toString();
+ _remoteIPAddr = settings.value(kREMOTE_IP, QString("192.168.168.2")).toString();
+ _groundIPAddr = settings.value(kGROUND_IP, QString("192.168.168.101")).toString();
+ _airIPAddr = settings.value(kAIR_IP, QString("192.168.168.213")).toString();
+ _netMask = settings.value(kNET_MASK, QString("255.255.255.0")).toString();
+ _configPassword = settings.value(kCFG_PASSWORD, QString("admin")).toString();
+ _encryptionKey = settings.value(kENC_KEY, QString("1234567890")).toString();
+ settings.endGroup();
+}
+
+//-----------------------------------------------------------------------------
+MicrohardManager::~MicrohardManager()
+{
+ _close();
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_close()
+{
+ _workTimer.stop();
+ _locTimer.stop();
+ _remTimer.stop();
+ if(_mhSettingsLoc) {
+ _mhSettingsLoc->close();
+ _mhSettingsLoc->deleteLater();
+ _mhSettingsLoc = nullptr;
+ }
+ if(_mhSettingsRem) {
+ _mhSettingsRem->close();
+ _mhSettingsRem->deleteLater();
+ _mhSettingsRem = nullptr;
+ }
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_reset()
+{
+ _close();
+ _isConnected = false;
+ emit connectedChanged();
+ _linkConnected = false;
+ emit linkConnectedChanged();
+ if(!_appSettings) {
+ _appSettings = _toolbox->settingsManager()->appSettings();
+ connect(_appSettings->enableMicrohard(), &Fact::rawValueChanged, this, &MicrohardManager::_setEnabled);
+ }
+ _setEnabled();
+}
+
+//-----------------------------------------------------------------------------
+FactMetaData*
+MicrohardManager::_createMetadata(const char* name, QStringList enums)
+{
+ FactMetaData* metaData = new FactMetaData(FactMetaData::valueTypeUint32, name, this);
+ QQmlEngine::setObjectOwnership(metaData, QQmlEngine::CppOwnership);
+ metaData->setShortDescription(name);
+ metaData->setLongDescription(name);
+ metaData->setRawDefaultValue(QVariant(0));
+ metaData->setHasControl(true);
+ metaData->setReadOnly(false);
+ for(int i = 0; i < enums.size(); i++) {
+ metaData->addEnumInfo(enums[i], QVariant(i));
+ }
+ metaData->setRawMin(0);
+ metaData->setRawMin(enums.size() - 1);
+ return metaData;
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::setToolbox(QGCToolbox* toolbox)
+{
+ QGCTool::setToolbox(toolbox);
+ //-- Start it all
+ _reset();
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardManager::setIPSettings(QString localIP_, QString remoteIP_, QString groundIP_, QString airIP_, QString netMask_, QString cfgPassword_, QString encryptionKey_)
+{
+ if (_localIPAddr != localIP_ || _remoteIPAddr != remoteIP_ || _netMask != netMask_ ||
+ _configPassword != cfgPassword_ || _encryptionKey != encryptionKey_ || _groundIPAddr != groundIP_ || _airIPAddr != airIP_)
+ {
+ if (_mhSettingsLoc && _encryptionKey != encryptionKey_) {
+ _mhSettingsLoc->setEncryptionKey(encryptionKey_);
+ }
+
+ _localIPAddr = localIP_;
+ _remoteIPAddr = remoteIP_;
+ _groundIPAddr = groundIP_;
+ _airIPAddr = airIP_;
+ _netMask = netMask_;
+ _configPassword = cfgPassword_;
+ _encryptionKey = encryptionKey_;
+
+ QSettings settings;
+ settings.beginGroup(kMICROHARD_GROUP);
+ settings.setValue(kLOCAL_IP, localIP_);
+ settings.setValue(kREMOTE_IP, remoteIP_);
+ settings.setValue(kGROUND_IP, groundIP_);
+ settings.setValue(kAIR_IP, airIP_);
+ settings.setValue(kNET_MASK, netMask_);
+ settings.setValue(kCFG_PASSWORD, cfgPassword_);
+ settings.setValue(kENC_KEY, encryptionKey_);
+ settings.endGroup();
+
+ _reset();
+
+ return true;
+ }
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_setEnabled()
+{
+ bool enable = _appSettings->enableMicrohard()->rawValue().toBool();
+ if(enable) {
+ if(!_mhSettingsLoc) {
+ _mhSettingsLoc = new MicrohardSettings(localIPAddr(), this, true);
+ connect(_mhSettingsLoc, &MicrohardSettings::connected, this, &MicrohardManager::_connectedLoc);
+ connect(_mhSettingsLoc, &MicrohardSettings::rssiUpdated, this, &MicrohardManager::_rssiUpdatedLoc);
+ }
+ if(!_mhSettingsRem) {
+ _mhSettingsRem = new MicrohardSettings(remoteIPAddr(), this);
+ connect(_mhSettingsRem, &MicrohardSettings::connected, this, &MicrohardManager::_connectedRem);
+ connect(_mhSettingsRem, &MicrohardSettings::rssiUpdated, this, &MicrohardManager::_rssiUpdatedRem);
+ }
+ _workTimer.start(1000);
+ } else {
+ //-- Stop everything
+ _close();
+ }
+ _enabled = enable;
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_connectedLoc()
+{
+ qCDebug(MicrohardLog) << "GND Microhard Settings Connected";
+ _isConnected = true;
+ _locTimer.start(LONG_TIMEOUT);
+ emit connectedChanged();
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_connectedRem()
+{
+ qCDebug(MicrohardLog) << "AIR Microhard Settings Connected";
+ _linkConnected = true;
+ _remTimer.start(LONG_TIMEOUT);
+ emit linkConnectedChanged();
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_rssiUpdatedLoc(int rssi)
+{
+ _downlinkRSSI = rssi;
+ _locTimer.stop();
+ _locTimer.start(LONG_TIMEOUT);
+ emit connectedChanged();
+ emit linkChanged();
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_rssiUpdatedRem(int rssi)
+{
+ _uplinkRSSI = rssi;
+ _remTimer.stop();
+ _remTimer.start(LONG_TIMEOUT);
+ emit linkConnectedChanged();
+ emit linkChanged();
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_locTimeout()
+{
+ _locTimer.stop();
+ _isConnected = false;
+ if(_mhSettingsLoc) {
+ _mhSettingsLoc->close();
+ _mhSettingsLoc->deleteLater();
+ _mhSettingsLoc = nullptr;
+ }
+ emit connectedChanged();
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_remTimeout()
+{
+ _remTimer.stop();
+ _linkConnected = false;
+ if(_mhSettingsRem) {
+ _mhSettingsRem->close();
+ _mhSettingsRem->deleteLater();
+ _mhSettingsRem = nullptr;
+ }
+ emit linkConnectedChanged();
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_checkMicrohard()
+{
+ if(_enabled) {
+ if(!_mhSettingsLoc || !_mhSettingsRem) {
+ _setEnabled();
+ return;
+ }
+
+ if(!_isConnected) {
+ _mhSettingsLoc->start();
+ } else {
+ _mhSettingsLoc->getStatus();
+ }
+ if(!_linkConnected) {
+ _mhSettingsRem->start();
+ } else {
+ _mhSettingsRem->getStatus();
+ }
+ }
+ _workTimer.start(_isConnected ? 1000 : LONG_TIMEOUT);
+}
diff --git a/src/Microhard/MicrohardManager.h b/src/Microhard/MicrohardManager.h
new file mode 100644
index 0000000..2dc4904
--- /dev/null
+++ b/src/Microhard/MicrohardManager.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+ *
+ * (c) 2019 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+#pragma once
+
+#include "QGCToolbox.h"
+#include "QGCLoggingCategory.h"
+#include "MicrohardSettings.h"
+#include "Fact.h"
+
+#include
+#include
+
+class AppSettings;
+class QGCApplication;
+
+//-----------------------------------------------------------------------------
+class MicrohardManager : public QGCTool
+{
+ Q_OBJECT
+public:
+
+ Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
+ Q_PROPERTY(bool linkConnected READ linkConnected NOTIFY linkConnectedChanged)
+ Q_PROPERTY(int uplinkRSSI READ uplinkRSSI NOTIFY linkChanged)
+ Q_PROPERTY(int downlinkRSSI READ downlinkRSSI NOTIFY linkChanged)
+ Q_PROPERTY(QString localIPAddr READ localIPAddr NOTIFY localIPAddrChanged)
+ Q_PROPERTY(QString remoteIPAddr READ remoteIPAddr NOTIFY remoteIPAddrChanged)
+ Q_PROPERTY(QString groundIPAddr READ groundIPAddr NOTIFY groundIPAddrChanged)
+ Q_PROPERTY(QString airIPAddr READ airIPAddr NOTIFY airIPAddrChanged)
+ Q_PROPERTY(QString netMask READ netMask NOTIFY netMaskChanged)
+ Q_PROPERTY(QString configPassword READ configPassword NOTIFY configPasswordChanged)
+ Q_PROPERTY(QString encryptionKey READ encryptionKey NOTIFY encryptionKeyChanged)
+
+ Q_INVOKABLE bool setIPSettings (QString localIP, QString remoteIP, QString groundIP, QString airIP, QString netMask, QString cfgPassword, QString encyrptionKey);
+
+ explicit MicrohardManager (QGCApplication* app, QGCToolbox* toolbox);
+ ~MicrohardManager () override;
+
+ void setToolbox (QGCToolbox* toolbox) override;
+
+ bool connected () { return _isConnected && _mhSettingsLoc && _mhSettingsLoc->loggedIn(); }
+ bool linkConnected () { return _linkConnected && _mhSettingsRem && _mhSettingsRem->loggedIn(); }
+ int uplinkRSSI () { return _downlinkRSSI; }
+ int downlinkRSSI () { return _uplinkRSSI; }
+ QString localIPAddr () { return _localIPAddr; }
+ QString remoteIPAddr () { return _remoteIPAddr; }
+ QString airIPAddr () { return _airIPAddr; }
+ QString groundIPAddr () { return _groundIPAddr; }
+ QString netMask () { return _netMask; }
+ QString configPassword () { return _configPassword; }
+ QString encryptionKey () { return _encryptionKey; }
+
+signals:
+ void linkChanged ();
+ void linkConnectedChanged ();
+ void connectedChanged ();
+ void localIPAddrChanged ();
+ void remoteIPAddrChanged ();
+ void airIPAddrChanged ();
+ void groundIPAddrChanged ();
+ void netMaskChanged ();
+ void configPasswordChanged ();
+ void encryptionKeyChanged ();
+
+private slots:
+ void _connectedLoc ();
+ void _rssiUpdatedLoc (int rssi);
+ void _connectedRem ();
+ void _rssiUpdatedRem (int rssi);
+ void _checkMicrohard ();
+ void _setEnabled ();
+ void _locTimeout ();
+ void _remTimeout ();
+
+private:
+ void _close ();
+ void _reset ();
+ FactMetaData *_createMetadata (const char *name, QStringList enums);
+
+private:
+ bool _isConnected = false;
+ AppSettings* _appSettings = nullptr;
+ MicrohardSettings* _mhSettingsLoc = nullptr;
+ MicrohardSettings* _mhSettingsRem = nullptr;
+ bool _enabled = true;
+ bool _linkConnected = false;
+ QTimer _workTimer;
+ QTimer _locTimer;
+ QTimer _remTimer;
+ int _downlinkRSSI = 0;
+ int _uplinkRSSI = 0;
+ QString _localIPAddr;
+ QString _remoteIPAddr;
+ QString _groundIPAddr;
+ QString _airIPAddr;
+ QString _netMask;
+ QString _configPassword;
+ QString _encryptionKey;
+ QTime _timeoutTimer;
+};
diff --git a/src/Microhard/MicrohardSettings.cc b/src/Microhard/MicrohardSettings.cc
new file mode 100644
index 0000000..5d6c0e7
--- /dev/null
+++ b/src/Microhard/MicrohardSettings.cc
@@ -0,0 +1,86 @@
+/****************************************************************************
+ *
+ * (c) 2019 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+#include "MicrohardSettings.h"
+#include "MicrohardManager.h"
+#include "SettingsManager.h"
+#include "QGCApplication.h"
+#include "VideoManager.h"
+
+//-----------------------------------------------------------------------------
+MicrohardSettings::MicrohardSettings(QString address_, QObject* parent, bool setEncryptionKey)
+ : MicrohardHandler(parent)
+{
+ _address = address_;
+ _setEncryptionKey = setEncryptionKey;
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardSettings::start()
+{
+ qCDebug(MicrohardLog) << "Start Microhard Settings";
+ _loggedIn = false;
+ return _start(MICROHARD_SETTINGS_PORT, QHostAddress(_address));
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardSettings::getStatus()
+{
+ if (_loggedIn) {
+ _tcpSocket->write("AT+MWSTATUS\n");
+ }
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardSettings::setEncryptionKey(QString key)
+{
+ QString cmd = "AT+MWVENCRYPT=1," + key + "\n";
+ _tcpSocket->write(cmd.toStdString().c_str());
+ qCDebug(MicrohardLog) << "setEncryptionKey: " << cmd;
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardSettings::_readBytes()
+{
+ QByteArray bytesIn = _tcpSocket->read(_tcpSocket->bytesAvailable());
+
+// qCDebug(MicrohardVerbose) << "Read bytes: " << bytesIn;
+
+ if (_loggedIn) {
+ int i1 = bytesIn.indexOf("RSSI (dBm)");
+ if (i1 > 0) {
+ int i2 = bytesIn.indexOf(": ", i1);
+ if (i2 > 0) {
+ i2 += 2;
+ int i3 = bytesIn.indexOf(" ", i2);
+ int val = bytesIn.mid(i2, i3 - i2).toInt();
+ if (val < 0) {
+ _rssiVal = val;
+ }
+ }
+ }
+ } else if (bytesIn.contains("UserDevice login:")) {
+ _tcpSocket->write("admin\n");
+ } else if (bytesIn.contains("Password:")) {
+ std::string pwd = qgcApp()->toolbox()->microhardManager()->configPassword().toStdString() + "\n";
+ _tcpSocket->write(pwd.c_str());
+ } else if (bytesIn.contains("UserDevice>")) {
+ if (!loggedIn() && _setEncryptionKey) {
+ setEncryptionKey(qgcApp()->toolbox()->microhardManager()->encryptionKey());
+ }
+ _loggedIn = true;
+ }
+
+ emit rssiUpdated(_rssiVal);
+}
+
diff --git a/src/Microhard/MicrohardSettings.h b/src/Microhard/MicrohardSettings.h
new file mode 100644
index 0000000..31be24f
--- /dev/null
+++ b/src/Microhard/MicrohardSettings.h
@@ -0,0 +1,35 @@
+/****************************************************************************
+ *
+ * (c) 2019 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+#pragma once
+
+#include "MicrohardHandler.h"
+
+class MicrohardSettings : public MicrohardHandler
+{
+ Q_OBJECT
+public:
+ explicit MicrohardSettings (QString address, QObject* parent = nullptr, bool setEncryptionKey = false);
+ bool start () override;
+ void getStatus ();
+ void setEncryptionKey (QString key);
+ bool loggedIn () { return _loggedIn; }
+
+protected slots:
+ void _readBytes () override;
+
+signals:
+ void updateRSSI (int rssi);
+
+private:
+ bool _loggedIn;
+ int _rssiVal;
+ QString _address;
+ bool _setEncryptionKey;
+};
diff --git a/src/Microhard/MicrohardSettings.qml b/src/Microhard/MicrohardSettings.qml
new file mode 100644
index 0000000..cba0245
--- /dev/null
+++ b/src/Microhard/MicrohardSettings.qml
@@ -0,0 +1,299 @@
+/****************************************************************************
+ *
+ * (c) 2019 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+
+import QtGraphicalEffects 1.0
+import QtMultimedia 5.5
+import QtQuick 2.3
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Dialogs 1.2
+import QtQuick.Layouts 1.2
+import QtLocation 5.3
+import QtPositioning 5.3
+
+import QGroundControl 1.0
+import QGroundControl.Controllers 1.0
+import QGroundControl.Controls 1.0
+import QGroundControl.FactControls 1.0
+import QGroundControl.FactSystem 1.0
+import QGroundControl.Palette 1.0
+import QGroundControl.ScreenTools 1.0
+import QGroundControl.SettingsManager 1.0
+
+QGCView {
+ id: _qgcView
+ viewPanel: panel
+ color: qgcPal.window
+ anchors.fill: parent
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+
+ property real _labelWidth: ScreenTools.defaultFontPixelWidth * 26
+ property real _valueWidth: ScreenTools.defaultFontPixelWidth * 20
+ property real _panelWidth: _qgcView.width * _internalWidthRatio
+ property Fact _microhardEnabledFact: QGroundControl.settingsManager.appSettings.enableMicrohard
+ property bool _microhardEnabled: _microhardEnabledFact.rawValue
+
+ readonly property real _internalWidthRatio: 0.8
+
+ QGCPalette { id: qgcPal }
+
+ QGCViewPanel {
+ id: panel
+ anchors.fill: parent
+ QGCFlickable {
+ clip: true
+ anchors.fill: parent
+ contentHeight: settingsColumn.height
+ contentWidth: settingsColumn.width
+ Column {
+ id: settingsColumn
+ width: _qgcView.width
+ spacing: ScreenTools.defaultFontPixelHeight * 0.5
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ //-----------------------------------------------------------------
+ //-- General
+ Item {
+ width: _panelWidth
+ height: generalLabel.height
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ QGCLabel {
+ id: generalLabel
+ text: qsTr("General")
+ font.family: ScreenTools.demiboldFontFamily
+ }
+ }
+ Rectangle {
+ height: generalRow.height + (ScreenTools.defaultFontPixelHeight * 2)
+ width: _panelWidth
+ color: qgcPal.windowShade
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ Row {
+ id: generalRow
+ spacing: ScreenTools.defaultFontPixelWidth * 4
+ anchors.centerIn: parent
+ Column {
+ spacing: ScreenTools.defaultFontPixelWidth
+ FactCheckBox {
+ text: qsTr("Enable Microhard")
+ fact: _microhardEnabledFact
+ enabled: true
+ visible: _microhardEnabledFact.visible
+ }
+ }
+ }
+ }
+ //-----------------------------------------------------------------
+ //-- Connection Status
+ Item {
+ width: _panelWidth
+ height: statusLabel.height
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ visible: _microhardEnabled
+ QGCLabel {
+ id: statusLabel
+ text: qsTr("Connection Status")
+ font.family: ScreenTools.demiboldFontFamily
+ }
+ }
+ Rectangle {
+ height: statusCol.height + (ScreenTools.defaultFontPixelHeight * 2)
+ width: _panelWidth
+ color: qgcPal.windowShade
+ visible: _microhardEnabled
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ Column {
+ id: statusCol
+ spacing: ScreenTools.defaultFontPixelHeight * 0.5
+ width: parent.width
+ anchors.centerIn: parent
+ GridLayout {
+ anchors.margins: ScreenTools.defaultFontPixelHeight
+ columnSpacing: ScreenTools.defaultFontPixelWidth * 2
+ anchors.horizontalCenter: parent.horizontalCenter
+ columns: 2
+ QGCLabel {
+ text: qsTr("Ground Unit:")
+ Layout.minimumWidth: _labelWidth
+ }
+ QGCLabel {
+ text: QGroundControl.microhardManager.connected ? qsTr("Connected") : qsTr("Not Connected")
+ color: QGroundControl.microhardManager.connected ? qgcPal.colorGreen : qgcPal.colorRed
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Air Unit:")
+ }
+ QGCLabel {
+ text: QGroundControl.microhardManager.linkConnected ? qsTr("Connected") : qsTr("Not Connected")
+ color: QGroundControl.microhardManager.linkConnected ? qgcPal.colorGreen : qgcPal.colorRed
+ }
+ QGCLabel {
+ text: qsTr("Uplink RSSI:")
+ }
+ QGCLabel {
+ text: QGroundControl.microhardManager.linkConnected && QGroundControl.microhardManager.uplinkRSSI < 0 ? QGroundControl.microhardManager.uplinkRSSI : ""
+ }
+ QGCLabel {
+ text: qsTr("Downlink RSSI:")
+ }
+ QGCLabel {
+ text: QGroundControl.microhardManager.linkConnected && QGroundControl.microhardManager.downlinkRSSI < 0 ? QGroundControl.microhardManager.downlinkRSSI : ""
+ }
+ }
+ }
+ }
+ //-----------------------------------------------------------------
+ //-- IP Settings
+ Item {
+ width: _panelWidth
+ height: ipSettingsLabel.height
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ visible: _microhardEnabled
+ QGCLabel {
+ id: ipSettingsLabel
+ text: qsTr("Network Settings")
+ font.family: ScreenTools.demiboldFontFamily
+ }
+ }
+ Rectangle {
+ height: ipSettingsCol.height + (ScreenTools.defaultFontPixelHeight * 2)
+ width: _panelWidth
+ color: qgcPal.windowShade
+ visible: _microhardEnabled
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ Column {
+ id: ipSettingsCol
+ spacing: ScreenTools.defaultFontPixelHeight * 0.5
+ width: parent.width
+ anchors.centerIn: parent
+ GridLayout {
+ anchors.margins: ScreenTools.defaultFontPixelHeight
+ columnSpacing: ScreenTools.defaultFontPixelWidth * 2
+ anchors.horizontalCenter: parent.horizontalCenter
+ columns: 2
+ QGCLabel {
+ text: qsTr("Local IP Address:")
+ Layout.minimumWidth: _labelWidth
+ }
+ QGCTextField {
+ id: localIP
+ text: QGroundControl.microhardManager.localIPAddr
+ enabled: true
+ inputMethodHints: Qt.ImhFormattedNumbersOnly
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Remote IP Address:")
+ }
+ QGCTextField {
+ id: remoteIP
+ text: QGroundControl.microhardManager.remoteIPAddr
+ enabled: true
+ inputMethodHints: Qt.ImhFormattedNumbersOnly
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Ground Unit IP Address:")
+ Layout.minimumWidth: _labelWidth
+ }
+ QGCTextField {
+ id: groundIP
+ text: QGroundControl.microhardManager.groundIPAddr
+ enabled: true
+ inputMethodHints: Qt.ImhFormattedNumbersOnly
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Air Unit IP Address:")
+ }
+ QGCTextField {
+ id: airIP
+ text: QGroundControl.microhardManager.airIPAddr
+ enabled: true
+ inputMethodHints: Qt.ImhFormattedNumbersOnly
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Network Mask:")
+ }
+ QGCTextField {
+ id: netMask
+ text: QGroundControl.microhardManager.netMask
+ enabled: true
+ inputMethodHints: Qt.ImhFormattedNumbersOnly
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Configuration password:")
+ }
+ QGCTextField {
+ id: configPassword
+ text: QGroundControl.microhardManager.configPassword
+ enabled: true
+ inputMethodHints: Qt.ImhHiddenText
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Encryption key:")
+ }
+ QGCTextField {
+ id: encryptionKey
+ text: QGroundControl.microhardManager.encryptionKey
+ enabled: true
+ inputMethodHints: Qt.ImhHiddenText
+ Layout.minimumWidth: _valueWidth
+ }
+ }
+ Item {
+ width: 1
+ height: ScreenTools.defaultFontPixelHeight
+ }
+ QGCButton {
+ function validateIPaddress(ipaddress) {
+ if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress))
+ return true
+ return false
+ }
+ function testEnabled() {
+ if(localIP.text === QGroundControl.microhardManager.localIPAddr &&
+ remoteIP.text === QGroundControl.microhardManager.remoteIPAddr &&
+ groundIP.text === QGroundControl.microhardManager.groundIPAddr &&
+ airIP.text === QGroundControl.microhardManager.airIPAddr &&
+ netMask.text === QGroundControl.microhardManager.netMask &&
+ configPassword.text === QGroundControl.microhardManager.configPassword &&
+ encryptionKey.text === QGroundControl.microhardManager.encryptionKey)
+ return false
+ if(!validateIPaddress(localIP.text)) return false
+ if(!validateIPaddress(remoteIP.text)) return false
+ if(!validateIPaddress(groundIP.text)) return false
+ if(!validateIPaddress(airIP.text)) return false
+ if(!validateIPaddress(netMask.text)) return false
+ return true
+ }
+ enabled: testEnabled()
+ text: qsTr("Apply")
+ anchors.horizontalCenter: parent.horizontalCenter
+ onClicked: {
+ QGroundControl.microhardManager.setIPSettings(localIP.text, remoteIP.text, groundIP.text, airIP.text, netMask.text, configPassword.text, encryptionKey.text)
+ }
+
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/QGCToolbox.cc b/src/QGCToolbox.cc
index 4ccde18..f7eca31 100644
--- a/src/QGCToolbox.cc
+++ b/src/QGCToolbox.cc
@@ -38,6 +38,9 @@
#if defined(QGC_GST_TAISYNC_ENABLED)
#include "TaisyncManager.h"
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+#include "MicrohardManager.h"
+#endif
#if defined(QGC_CUSTOM_BUILD)
#include CUSTOMHEADER
@@ -78,6 +81,9 @@ QGCToolbox::QGCToolbox(QGCApplication* app)
#if defined(QGC_GST_TAISYNC_ENABLED)
_taisyncManager = new TaisyncManager (app, this);
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+ _microhardManager = new MicrohardManager (app, this);
+#endif
}
void QGCToolbox::setChildToolboxes(void)
@@ -107,6 +113,9 @@ void QGCToolbox::setChildToolboxes(void)
#if defined(QGC_GST_TAISYNC_ENABLED)
_taisyncManager->setToolbox(this);
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+ _microhardManager->setToolbox(this);
+#endif
}
void QGCToolbox::_scanAndLoadPlugins(QGCApplication* app)
diff --git a/src/QGCToolbox.h b/src/QGCToolbox.h
index 8df5642..4daff94 100644
--- a/src/QGCToolbox.h
+++ b/src/QGCToolbox.h
@@ -36,6 +36,9 @@ class AirspaceManager;
#if defined(QGC_GST_TAISYNC_ENABLED)
class TaisyncManager;
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+class MicrohardManager;
+#endif
/// This is used to manage all of our top level services/tools
class QGCToolbox : public QObject {
@@ -67,6 +70,9 @@ public:
#if defined(QGC_GST_TAISYNC_ENABLED)
TaisyncManager* taisyncManager () { return _taisyncManager; }
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+ MicrohardManager* microhardManager () { return _microhardManager; }
+#endif
private:
void setChildToolboxes(void);
@@ -97,6 +103,9 @@ private:
#if defined(QGC_GST_TAISYNC_ENABLED)
TaisyncManager* _taisyncManager = nullptr;
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+ MicrohardManager* _microhardManager = nullptr;
+#endif
friend class QGCApplication;
};
diff --git a/src/QmlControls/QGroundControlQmlGlobal.cc b/src/QmlControls/QGroundControlQmlGlobal.cc
index b223793..fbf84f2 100644
--- a/src/QmlControls/QGroundControlQmlGlobal.cc
+++ b/src/QmlControls/QGroundControlQmlGlobal.cc
@@ -69,6 +69,9 @@ void QGroundControlQmlGlobal::setToolbox(QGCToolbox* toolbox)
#if defined(QGC_GST_TAISYNC_ENABLED)
_taisyncManager = toolbox->taisyncManager();
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+ _microhardManager = toolbox->microhardManager();
+#endif
}
void QGroundControlQmlGlobal::saveGlobalSetting (const QString& key, const QString& value)
diff --git a/src/QmlControls/QGroundControlQmlGlobal.h b/src/QmlControls/QGroundControlQmlGlobal.h
index 26c3631..0a4fb92 100644
--- a/src/QmlControls/QGroundControlQmlGlobal.h
+++ b/src/QmlControls/QGroundControlQmlGlobal.h
@@ -28,6 +28,11 @@
#else
class TaisyncManager;
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+#include "MicrohardManager.h"
+#else
+class MicrohardManager;
+#endif
#ifdef QT_DEBUG
#include "MockLink.h"
@@ -68,6 +73,8 @@ public:
Q_PROPERTY(bool airmapSupported READ airmapSupported CONSTANT)
Q_PROPERTY(TaisyncManager* taisyncManager READ taisyncManager CONSTANT)
Q_PROPERTY(bool taisyncSupported READ taisyncSupported CONSTANT)
+ Q_PROPERTY(MicrohardManager* microhardManager READ microhardManager CONSTANT)
+ Q_PROPERTY(bool microhardSupported READ microhardSupported CONSTANT)
Q_PROPERTY(int supportedFirmwareCount READ supportedFirmwareCount CONSTANT)
Q_PROPERTY(bool px4ProFirmwareSupported READ px4ProFirmwareSupported CONSTANT)
@@ -170,6 +177,13 @@ public:
bool taisyncSupported () { return false; }
#endif
+ MicrohardManager* microhardManager () { return _microhardManager; }
+#if defined(QGC_GST_TAISYNC_ENABLED)
+ bool microhardSupported () { return true; }
+#else
+ bool microhardSupported () { return false; }
+#endif
+
qreal zOrderTopMost () { return 1000; }
qreal zOrderWidgets () { return 100; }
qreal zOrderMapItems () { return 50; }
@@ -230,6 +244,7 @@ private:
FactGroup* _gpsRtkFactGroup = nullptr;
AirspaceManager* _airspaceManager = nullptr;
TaisyncManager* _taisyncManager = nullptr;
+ MicrohardManager* _microhardManager = nullptr;
bool _skipSetupPage = false;
diff --git a/src/Settings/App.SettingsGroup.json b/src/Settings/App.SettingsGroup.json
index 67ef154..30472a4 100644
--- a/src/Settings/App.SettingsGroup.json
+++ b/src/Settings/App.SettingsGroup.json
@@ -221,4 +221,11 @@
"type": "bool",
"defaultValue": true
}
-]
+,
+{
+ "name": "enableMicrohard",
+ "shortDescription": "Enable Microhard Module Support",
+ "longDescription": "Enable Microhard Module Support",
+ "type": "bool",
+ "defaultValue": false
+}]
diff --git a/src/Settings/AppSettings.cc b/src/Settings/AppSettings.cc
index abfdfb4..ccc5905 100644
--- a/src/Settings/AppSettings.cc
+++ b/src/Settings/AppSettings.cc
@@ -87,6 +87,7 @@ DECLARE_SETTINGSFACT(AppSettings, followTarget)
DECLARE_SETTINGSFACT(AppSettings, apmStartMavlinkStreams)
DECLARE_SETTINGSFACT(AppSettings, enableTaisync)
DECLARE_SETTINGSFACT(AppSettings, enableTaisyncVideo)
+DECLARE_SETTINGSFACT(AppSettings, enableMicrohard)
DECLARE_SETTINGSFACT_NO_FUNC(AppSettings, indoorPalette)
{
diff --git a/src/Settings/AppSettings.h b/src/Settings/AppSettings.h
index 37784b9..bafb8c5 100644
--- a/src/Settings/AppSettings.h
+++ b/src/Settings/AppSettings.h
@@ -45,6 +45,7 @@ public:
DEFINE_SETTINGFACT(followTarget)
DEFINE_SETTINGFACT(enableTaisync)
DEFINE_SETTINGFACT(enableTaisyncVideo)
+ DEFINE_SETTINGFACT(enableMicrohard)
// Although this is a global setting it only affects ArduPilot vehicle since PX4 automatically starts the stream from the vehicle side
DEFINE_SETTINGFACT(apmStartMavlinkStreams)
diff --git a/src/api/QGCCorePlugin.cc b/src/api/QGCCorePlugin.cc
index eeaa267..0a1a6dc 100644
--- a/src/api/QGCCorePlugin.cc
+++ b/src/api/QGCCorePlugin.cc
@@ -48,6 +48,10 @@ public:
if(pTaisync)
delete pTaisync;
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+ if(pMicrohard)
+ delete pMicrohard;
+#endif
#if defined(QGC_AIRMAP_ENABLED)
if(pAirmap)
delete pAirmap;
@@ -72,6 +76,9 @@ public:
#if defined(QGC_GST_TAISYNC_ENABLED)
QmlComponentInfo* pTaisync = nullptr;
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+ QmlComponentInfo* pMicrohard = nullptr;
+#endif
#if defined(QGC_AIRMAP_ENABLED)
QmlComponentInfo* pAirmap = nullptr;
#endif
@@ -140,6 +147,12 @@ QVariantList &QGCCorePlugin::settingsPages()
QUrl::fromUserInput(""));
_p->settingsList.append(QVariant::fromValue(reinterpret_cast(_p->pTaisync)));
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+ _p->pMicrohard = new QmlComponentInfo(tr("Microhard"),
+ QUrl::fromUserInput("qrc:/qml/MicrohardSettings.qml"),
+ QUrl::fromUserInput(""));
+ _p->settingsList.append(QVariant::fromValue(reinterpret_cast(_p->pMicrohard)));
+#endif
#if defined(QGC_AIRMAP_ENABLED)
_p->pAirmap = new QmlComponentInfo(tr("AirMap"),
QUrl::fromUserInput("qrc:/qml/AirmapSettings.qml"),