Commit 80ccf144 authored by Matej Frančeškin's avatar Matej Frančeškin

Microhard - testing connect / reconnect to local and remote MH modems

parent 8bc0c95c
......@@ -60,16 +60,3 @@ MicrohardHandler::_start(uint16_t port, QHostAddress addr)
return true;
}
//-----------------------------------------------------------------------------
void
MicrohardHandler::_socketDisconnected()
{
if(_tcpSocket) {
qCDebug(MicrohardLog) << "Microhard TCP Connection Closed on port" << _tcpSocket->localPort();
_tcpSocket->close();
_tcpSocket->deleteLater();
_tcpSocket = nullptr;
}
emit disconnected();
}
......@@ -33,12 +33,11 @@ protected:
virtual bool _start (uint16_t port, QHostAddress addr = QHostAddress::AnyIPv4);
protected slots:
virtual void _socketDisconnected ();
virtual void _readBytes () = 0;
signals:
void connected ();
void disconnected ();
void rssiUpdated (int rssi);
protected:
QTcpSocket* _tcpSocket = nullptr;
......
......@@ -15,6 +15,8 @@
#include <QSettings>
#define LONG_TIMEOUT 5000
static const char *kMICROHARD_GROUP = "Microhard";
static const char *kLOCAL_IP = "LocalIP";
static const char *kREMOTE_IP = "RemoteIP";
......@@ -27,6 +29,8 @@ MicrohardManager::MicrohardManager(QGCApplication* app, QGCToolbox* 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();
......@@ -46,10 +50,15 @@ MicrohardManager::~MicrohardManager()
void
MicrohardManager::_close()
{
if(_mhSettings) {
_mhSettings->close();
_mhSettings->deleteLater();
_mhSettings = nullptr;
if(_mhSettingsLoc) {
_mhSettingsLoc->close();
_mhSettingsLoc->deleteLater();
_mhSettingsLoc = nullptr;
}
if(_mhSettingsRem) {
_mhSettingsRem->close();
_mhSettingsRem->deleteLater();
_mhSettingsRem = nullptr;
}
}
......@@ -99,41 +108,28 @@ MicrohardManager::setToolbox(QGCToolbox* toolbox)
//-----------------------------------------------------------------------------
bool
MicrohardManager::setIPSettings(QString localIP_, QString remoteIP_, QString netMask_)
MicrohardManager::setIPSettings(QString localIP_, QString remoteIP_, QString netMask_, QString cfgPassword_)
{
bool res = false;
if(_localIPAddr != localIP_ || _remoteIPAddr != remoteIP_ || _netMask != netMask_) {
//-- If we are connected to the Microhard
if(_isConnected) {
if(_mhSettings) {
//-- Change IP settings
res = _mhSettings->setIPSettings(localIP_, remoteIP_, netMask_);
if(res) {
_needReboot = true;
emit needRebootChanged();
}
}
} else {
//-- We're not connected. Record the change and restart.
_localIPAddr = localIP_;
_remoteIPAddr = remoteIP_;
_netMask = netMask_;
_reset();
res = true;
}
if(res) {
QSettings settings;
settings.beginGroup(kMICROHARD_GROUP);
settings.setValue(kLOCAL_IP, localIP_);
settings.setValue(kREMOTE_IP, remoteIP_);
settings.setValue(kNET_MASK, netMask_);
settings.endGroup();
}
} else {
//-- Nothing to change
res = true;
if (_localIPAddr != localIP_ || _remoteIPAddr != remoteIP_ || _netMask != netMask_ || _configPassword != cfgPassword_) {
_localIPAddr = localIP_;
_remoteIPAddr = remoteIP_;
_netMask = netMask_;
_configPassword = cfgPassword_;
QSettings settings;
settings.beginGroup(kMICROHARD_GROUP);
settings.setValue(kLOCAL_IP, localIP_);
settings.setValue(kREMOTE_IP, remoteIP_);
settings.setValue(kNET_MASK, netMask_);
settings.setValue(kCFG_PASSWORD, cfgPassword_);
settings.endGroup();
_reset();
return true;
}
return res;
return false;
}
//-----------------------------------------------------------------------------
......@@ -142,13 +138,16 @@ MicrohardManager::_setEnabled()
{
bool enable = _appSettings->enableMicrohard()->rawValue().toBool();
if(enable) {
if(!_mhSettings) {
_mhSettings = new MicrohardSettings(this);
connect(_mhSettings, &MicrohardSettings::updateSettings, this, &MicrohardManager::_updateSettings);
connect(_mhSettings, &MicrohardSettings::connected, this, &MicrohardManager::_connected);
connect(_mhSettings, &MicrohardSettings::disconnected, this, &MicrohardManager::_disconnected);
if(!_mhSettingsLoc) {
_mhSettingsLoc = new MicrohardSettings(localIPAddr(), this);
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);
}
_reqMask = static_cast<uint32_t>(REQ_ALL);
_workTimer.start(1000);
} else {
//-- Stop everything
......@@ -160,121 +159,92 @@ MicrohardManager::_setEnabled()
//-----------------------------------------------------------------------------
void
MicrohardManager::_connected()
MicrohardManager::_connectedLoc()
{
qCDebug(MicrohardLog) << "Microhard Settings Connected";
qCDebug(MicrohardLog) << "GND Microhard Settings Connected";
_isConnected = true;
_locTimer.start(LONG_TIMEOUT);
emit connectedChanged();
_needReboot = false;
emit needRebootChanged();
}
//-----------------------------------------------------------------------------
void
MicrohardManager::_disconnected()
MicrohardManager::_connectedRem()
{
qCDebug(MicrohardLog) << "Microhard Settings Disconnected";
_isConnected = false;
emit connectedChanged();
_needReboot = false;
emit needRebootChanged();
_linkConnected = false;
qCDebug(MicrohardLog) << "AIR Microhard Settings Connected";
_linkConnected = true;
_remTimer.start(LONG_TIMEOUT);
emit linkConnectedChanged();
_reset();
}
//-----------------------------------------------------------------------------
void
MicrohardManager::_checkMicrohard()
MicrohardManager::_rssiUpdatedLoc(int rssi)
{
if(_enabled) {
if(!_isConnected) {
if(_mhSettings) {
_mhSettings->start();
}
} else {
//qCDebug(MicrohardVerbose) << bin << _reqMask;
while(true) {
if (_reqMask & REQ_LINK_STATUS) {
_mhSettings->requestLinkStatus();
break;
}
//-- Check link status
if(_timeoutTimer.elapsed() > 3000) {
//-- Give up and restart
_disconnected();
break;
}
//-- If it's been too long since we last heard, ping it.
if(_timeoutTimer.elapsed() > 1000) {
_mhSettings->requestLinkStatus();
break;
}
break;
}
}
_workTimer.start(_isConnected ? 500 : 5000);
_downlinkRSSI = rssi;
_locTimer.stop();
_locTimer.start(LONG_TIMEOUT);
emit linkChanged();
}
//-----------------------------------------------------------------------------
void
MicrohardManager::_rssiUpdatedRem(int rssi)
{
_uplinkRSSI = rssi;
_remTimer.stop();
_remTimer.start(LONG_TIMEOUT);
emit linkChanged();
}
//-----------------------------------------------------------------------------
void
MicrohardManager::_locTimeout()
{
_locTimer.stop();
_isConnected = false;
if(_mhSettingsLoc) {
_mhSettingsLoc->close();
_mhSettingsLoc->deleteLater();
_mhSettingsLoc = nullptr;
}
emit connectedChanged();
}
//-----------------------------------------------------------------------------
void
MicrohardManager::_updateSettings(QByteArray jSonData)
MicrohardManager::_remTimeout()
{
_timeoutTimer.start();
qCDebug(MicrohardVerbose) << jSonData;
QJsonParseError jsonParseError;
QJsonDocument doc = QJsonDocument::fromJson(jSonData, &jsonParseError);
if (jsonParseError.error != QJsonParseError::NoError) {
qWarning() << "Unable to parse Microhard response:" << jsonParseError.errorString() << jsonParseError.offset;
return;
_remTimer.stop();
_linkConnected = false;
if(_mhSettingsRem) {
_mhSettingsRem->close();
_mhSettingsRem->deleteLater();
_mhSettingsRem = nullptr;
}
QJsonObject jObj = doc.object();
//-- Link Status?
if(jSonData.contains("\"flight\":")) {
_reqMask &= ~static_cast<uint32_t>(REQ_LINK_STATUS);
bool tlinkConnected = jObj["flight"].toString("") == "online";
if(tlinkConnected != _linkConnected) {
_linkConnected = tlinkConnected;
emit linkConnectedChanged();
}
int tdownlinkRSSI = jObj["radiorssi"].toInt(_downlinkRSSI);
int tuplinkRSSI = jObj["hdrssi"].toInt(_uplinkRSSI);
if(_downlinkRSSI != tdownlinkRSSI || _uplinkRSSI != tuplinkRSSI) {
_downlinkRSSI = tdownlinkRSSI;
_uplinkRSSI = tuplinkRSSI;
emit linkChanged();
}
//-- IP Address Settings?
} else if(jSonData.contains("\"usbEthIp\":")) {
QString value;
bool changed = false;
value = jObj["ipaddr"].toString(_localIPAddr);
if(value != _localIPAddr) {
_localIPAddr = value;
changed = true;
emit localIPAddrChanged();
}
value = jObj["netmask"].toString(_netMask);
if(value != _netMask) {
_netMask = value;
changed = true;
emit netMaskChanged();
emit linkConnectedChanged();
}
//-----------------------------------------------------------------------------
void
MicrohardManager::_checkMicrohard()
{
if(_enabled) {
if(!_mhSettingsLoc || !_mhSettingsRem) {
_setEnabled();
return;
}
value = jObj["usbEthIp"].toString(_remoteIPAddr);
if(value != _remoteIPAddr) {
_remoteIPAddr = value;
changed = true;
emit remoteIPAddrChanged();
if(!_isConnected) {
_mhSettingsLoc->start();
} else {
_mhSettingsLoc->getStatus();
}
if(changed) {
QSettings settings;
settings.beginGroup(kMICROHARD_GROUP);
settings.setValue(kLOCAL_IP, _localIPAddr);
settings.setValue(kREMOTE_IP, _remoteIPAddr);
settings.setValue(kNET_MASK, _netMask);
settings.setValue(kCFG_PASSWORD, _configPassword);
settings.endGroup();
if(!_linkConnected) {
_mhSettingsRem->start();
} else {
_mhSettingsRem->getStatus();
}
}
_workTimer.start(_isConnected ? 1000 : LONG_TIMEOUT);
}
......@@ -28,7 +28,6 @@ public:
Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
Q_PROPERTY(bool linkConnected READ linkConnected NOTIFY linkConnectedChanged)
Q_PROPERTY(bool needReboot READ needReboot NOTIFY needRebootChanged)
Q_PROPERTY(int uplinkRSSI READ uplinkRSSI NOTIFY linkChanged)
Q_PROPERTY(int downlinkRSSI READ downlinkRSSI NOTIFY linkChanged)
Q_PROPERTY(QString localIPAddr READ localIPAddr NOTIFY localIPAddrChanged)
......@@ -36,7 +35,7 @@ public:
Q_PROPERTY(QString netMask READ netMask NOTIFY netMaskChanged)
Q_PROPERTY(QString configPassword READ configPassword NOTIFY configPasswordChanged)
Q_INVOKABLE bool setIPSettings (QString localIP, QString remoteIP, QString netMask);
Q_INVOKABLE bool setIPSettings (QString localIP, QString remoteIP, QString netMask, QString cfgPassword);
explicit MicrohardManager (QGCApplication* app, QGCToolbox* toolbox);
~MicrohardManager () override;
......@@ -45,7 +44,6 @@ public:
bool connected () { return _isConnected; }
bool linkConnected () { return _linkConnected; }
bool needReboot () { return _needReboot; }
int uplinkRSSI () { return _downlinkRSSI; }
int downlinkRSSI () { return _uplinkRSSI; }
QString localIPAddr () { return _localIPAddr; }
......@@ -63,15 +61,17 @@ signals:
void localIPAddrChanged ();
void remoteIPAddrChanged ();
void netMaskChanged ();
void needRebootChanged ();
void configPasswordChanged ();
private slots:
void _connected ();
void _disconnected ();
void _connectedLoc ();
void _rssiUpdatedLoc (int rssi);
void _connectedRem ();
void _rssiUpdatedRem (int rssi);
void _checkMicrohard ();
void _updateSettings (QByteArray jSonData);
void _setEnabled ();
void _locTimeout ();
void _remTimeout ();
private:
void _close ();
......@@ -79,27 +79,16 @@ private:
FactMetaData *_createMetadata (const char *name, QStringList enums);
private:
enum {
REQ_LINK_STATUS = 1,
REQ_DEV_INFO = 2,
REQ_FREQ_SCAN = 4,
REQ_VIDEO_SETTINGS = 8,
REQ_RADIO_SETTINGS = 16,
REQ_RTSP_SETTINGS = 32,
REQ_IP_SETTINGS = 64,
REQ_ALL = 0xFFFFFFF,
};
uint32_t _reqMask = static_cast<uint32_t>(REQ_ALL);
bool _running = false;
bool _isConnected = false;
AppSettings* _appSettings = nullptr;
MicrohardSettings* _mhSettings = nullptr;
MicrohardSettings* _mhSettingsLoc = nullptr;
MicrohardSettings* _mhSettingsRem = nullptr;
bool _enabled = true;
bool _linkConnected = false;
bool _needReboot = false;
QTimer _workTimer;
QTimer _locTimer;
QTimer _remTimer;
int _downlinkRSSI = 0;
int _uplinkRSSI = 0;
QString _localIPAddr;
......
......@@ -14,9 +14,10 @@
#include "VideoManager.h"
//-----------------------------------------------------------------------------
MicrohardSettings::MicrohardSettings(QObject* parent)
MicrohardSettings::MicrohardSettings(QString address, QObject* parent)
: MicrohardHandler(parent)
{
_address = address;
}
//-----------------------------------------------------------------------------
......@@ -24,54 +25,17 @@ bool
MicrohardSettings::start()
{
qCDebug(MicrohardLog) << "Start Microhard Settings";
return _start(MICROHARD_SETTINGS_PORT, QHostAddress(qgcApp()->toolbox()->microhardManager()->remoteIPAddr()));
_connectionState = 0;
return _start(MICROHARD_SETTINGS_PORT, QHostAddress(_address));
}
//-----------------------------------------------------------------------------
bool
MicrohardSettings::requestLinkStatus()
{
return _request("/v1/baseband.json");
}
//-----------------------------------------------------------------------------
bool
MicrohardSettings::_request(const QString& request)
{
/*
if(_tcpSocket) {
QString req = QString(kGetReq).arg(request);
//qCDebug(MicrohardVerbose) << "Request" << req;
_tcpSocket->write(req.toUtf8());
return true;
}
*/
return false;
}
//-----------------------------------------------------------------------------
bool
MicrohardSettings::_post(const QString& post, const QString &postPayload)
void
MicrohardSettings::getStatus()
{
/*
if(_tcpSocket) {
QString req = QString(kPostReq).arg(post).arg(postPayload.size()).arg(postPayload);
qCDebug(MicrohardVerbose) << "Post" << req;
_tcpSocket->write(req.toUtf8());
return true;
if (_connectionState == 1) {
_tcpSocket->write("AT+MWSTATUS\n");
}
*/
return false;
}
//-----------------------------------------------------------------------------
bool
MicrohardSettings::setIPSettings(const QString& localIP, const QString& remoteIP, const QString& netMask)
{
return false;
// static const char* kRTSPPost = "{\"ipaddr\":\"%1\",\"netmask\":\"%2\",\"usbEthIp\":\"%3\"}";
// QString post = QString(kRTSPPost).arg(localIP).arg(netMask).arg(remoteIP);
// return _post(kIPAddrURI, post);
}
//-----------------------------------------------------------------------------
......@@ -79,20 +43,31 @@ void
MicrohardSettings::_readBytes()
{
QByteArray bytesIn = _tcpSocket->read(_tcpSocket->bytesAvailable());
QString s_data = QString::fromStdString(bytesIn.toStdString());
//-- Go straight to Json payload
int idx = bytesIn.indexOf('{');
//-- We may receive more than one response within one TCP packet.
while(idx >= 0) {
bytesIn = bytesIn.mid(idx);
idx = bytesIn.indexOf('}');
if(idx > 0) {
QByteArray data = bytesIn.left(idx + 1);
emit updateSettings(data);
bytesIn = bytesIn.mid(idx+1);
idx = bytesIn.indexOf('{');
qCDebug(MicrohardVerbose) << "Read bytes: " << bytesIn;
if (_connectionState == 1) {
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>")) {
_connectionState = 1;
}
emit rssiUpdated(_rssiVal);
}
......@@ -15,18 +15,19 @@ class MicrohardSettings : public MicrohardHandler
{
Q_OBJECT
public:
explicit MicrohardSettings (QObject* parent = nullptr);
explicit MicrohardSettings (QString address, QObject* parent = nullptr);
bool start () override;
bool requestLinkStatus ();
bool setIPSettings (const QString& localIP, const QString& remoteIP, const QString& netMask);
void getStatus ();
signals:
void updateSettings (QByteArray jSonData);
protected slots:
void _readBytes () override;
signals:
void updateRSSI (int rssi);
private:
bool _request (const QString& request);
bool _post (const QString& post, const QString& postPayload);
int _connectionState;
int _rssiVal;
QString _address;
};
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
* (c) 2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
......@@ -57,13 +57,6 @@ QGCView {
width: _qgcView.width
spacing: ScreenTools.defaultFontPixelHeight * 0.5
anchors.margins: ScreenTools.defaultFontPixelWidth
QGCLabel {
text: qsTr("Reboot ground unit for changes to take effect.")
color: qgcPal.colorOrange
visible: QGroundControl.microhardManager.needReboot
font.family: ScreenTools.demiboldFontFamily
anchors.horizontalCenter: parent.horizontalCenter
}
//-----------------------------------------------------------------
//-- General
Item {
......@@ -92,7 +85,7 @@ QGCView {
FactCheckBox {
text: qsTr("Enable Microhard")
fact: _microhardEnabledFact
enabled: !QGroundControl.microhardManager.needReboot
enabled: true
visible: _microhardEnabledFact.visible
}
}
......@@ -198,7 +191,7 @@ QGCView {
QGCTextField {
id: localIP
text: QGroundControl.microhardManager.localIPAddr
enabled: !QGroundControl.microhardManager.needReboot
enabled: true
inputMethodHints: Qt.ImhFormattedNumbersOnly
Layout.minimumWidth: _valueWidth
}
......@@ -208,7 +201,7 @@ QGCView {
QGCTextField {
id: remoteIP
text: QGroundControl.microhardManager.remoteIPAddr
enabled: !QGroundControl.microhardManager.needReboot
enabled: true
inputMethodHints: Qt.ImhFormattedNumbersOnly
Layout.minimumWidth: _valueWidth
}
......@@ -218,7 +211,7 @@ QGCView {
QGCTextField {
id: netMask
text: QGroundControl.microhardManager.netMask
enabled: !QGroundControl.microhardManager.needReboot
enabled: true
inputMethodHints: Qt.ImhFormattedNumbersOnly
Layout.minimumWidth: _valueWidth
}
......@@ -228,7 +221,7 @@ QGCView {
QGCTextField {
id: configPassword
text: QGroundControl.microhardManager.configPassword
enabled: !QGroundControl.microhardManager.needReboot
enabled: true
inputMethodHints: Qt.ImhHiddenText
Layout.minimumWidth: _valueWidth
}
......@@ -244,35 +237,19 @@ QGCView {
return false
}
function testEnabled() {
if(localIP.text === QGroundControl.microhardManager.localIPAddr &&
remoteIP.text === QGroundControl.microhardManager.remoteIPAddr &&
netMask.text === QGroundControl.microhardManager.netMask)
if(localIP.text === QGroundControl.microhardManager.localIPAddr &&
remoteIP.text === QGroundControl.microhardManager.remoteIPAddr &&
netMask.text === QGroundControl.microhardManager.netMask &&
configPassword.text === QGroundControl.microhardManager.configPassword)
return false
if(!validateIPaddress(localIP.text)) return false
if(!validateIPaddress(remoteIP.text)) return false
if(!validateIPaddress(netMask.text)) return false
return true
}
enabled: testEnabled() && !QGroundControl.microhardManager.needReboot
enabled: testEnabled()
text: qsTr("Apply")
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
setIPDialog.open()
}
MessageDialog {
id: setIPDialog
icon: StandardIcon.Warning
standardButtons: StandardButton.Yes | StandardButton.No
title: qsTr("Set Network Settings")
text: qsTr("Once changed, you will need to reboot the ground unit for the changes to take effect. The local IP address must match the one entered (%1).\n\nConfirm change?").arg(localIP.text)
onYes: {
QGroundControl.microhardManager.setIPSettings(localIP.text, remoteIP.text, netMask.text)
setIPDialog.close()
}
onNo: {
setIPDialog.close()
}
}
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment