#include "qt.h" #include #include #include #include #include #include #ifdef PLUGIN #include #else #include #endif #ifdef Q_OS_ANDROID QT* QT::_this = nullptr; #include "rep_qtandroidservice_replica.h" #if (QT_VERSION < 0x060000) #include #include #else #include #endif #else #include "connection/connection.h" #endif QT_BEGIN_NAMESPACE QObject* ini() { static QObject* qt = nullptr; if (qt == nullptr) { qt = new QT; } return qt; } // connection QT::QT() : QObject() { #ifdef Q_OS_ANDROID _this = this; iniJni(); // remote object for android service QRemoteObjectNode* repNode = new QRemoteObjectNode; repNode->connectToNode(QUrl(QStringLiteral("local:replica"))); con = repNode->acquire(); bool res = con->waitForSource(); Q_ASSERT(res); #else con = new Connection; #endif #ifdef Q_OS_ANDROID QObject::connect(con, &QtAndroidServiceReplica::deviceDiscovered, #else QObject::connect(con, &Connection::deviceDiscovered, #endif [](const QVariant& vName) { ecl_fun("radios:device-discovered", vName.toString().right(4)); // short name }); #ifdef Q_OS_ANDROID QObject::connect(con, &QtAndroidServiceReplica::bleError, #else QObject::connect(con, &Connection::bleError, #endif []() { ecl_fun("radios:reset"); }); #ifdef Q_OS_ANDROID QObject::connect(con, &QtAndroidServiceReplica::setReady, #else QObject::connect(con, &Connection::setReady, #endif [](const QVariant& vArg) { ecl_fun("lora:set-ready", vArg); }); #ifdef Q_OS_ANDROID QObject::connect(con, &QtAndroidServiceReplica::receivedFromRadio, #else QObject::connect(con, &Connection::receivedFromRadio, #endif [](const QVariant& vArg) { ecl_fun("lora:received-from-radio", vArg); }); #ifdef Q_OS_ANDROID QObject::connect(con, &QtAndroidServiceReplica::receivingDone, #else QObject::connect(con, &Connection::receivingDone, #endif []() { ecl_fun("lora:receiving-done"); }); #ifdef Q_OS_ANDROID QObject::connect(con, &QtAndroidServiceReplica::sendSavedPackets, #else QObject::connect(con, &Connection::sendSavedPackets, #endif [](const QVariant& vPackets) { ecl_fun("lora:process-saved-packets", vPackets); }); #if (defined Q_OS_ANDROID) || (defined Q_OS_IOS) // background mode QObject::connect(qGuiApp, &QGuiApplication::applicationStateChanged, [&](Qt::ApplicationState state) { static bool ok = false; // for startup if (state == Qt::ApplicationInactive) { ok = true; con->setBackgroundMode(true); ecl_fun("app:background-mode-changed", true); } else if (state == Qt::ApplicationActive) { if (ok) { con->setBackgroundMode(false); ecl_fun("app:background-mode-changed", false); } } }); #endif } QVariant QT::setConnectionType(const QVariant& vType) { con->setConnectionType(vType); return QVariant(); } QVariant QT::startDeviceDiscovery(const QVariant& vName) { con->startDeviceDiscovery(vName); return QVariant(); } QVariant QT::stopDeviceDiscovery() { con->stopDeviceDiscovery(); return QVariant(); } QVariant QT::disconnect() { con->disconnect(); return QVariant(); } QVariant QT::setDeviceFilter(const QVariant& vName) { con->setDeviceFilter(vName); return QVariant(); } QVariant QT::read2() { con->read2(); return QVariant(); } QVariant QT::write2(const QVariant& vBytes) { con->write2(vBytes); return QVariant(); } QVariant QT::wifiConnectable(const QVariant& vIP) { if (tcp.state() == QTcpSocket::ConnectedState) { return true; } tcp.connectToHost(vIP.toString(), 4403); if (tcp.waitForConnected(1000)) { return true; } return QVariant(); } // SQLite QVariant QT::iniDb(const QVariant& name) { db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName(name.toString()); return name; } QVariant QT::sqlQuery(const QVariant& vQuery, const QVariant& vValues, const QVariant& vRows) { QVariantList results; QSqlQuery sqlQuery(db); if (db.open()) { QString query = vQuery.toString(); sqlQuery.prepare(vQuery.toString()); const QVariantList values = vValues.value(); for (auto value : values) { sqlQuery.addBindValue(value); } if (sqlQuery.exec()) { auto rows = vRows.toInt(); while (sqlQuery.next()) { if (rows > 1) { QVariantList list; for (auto r = 0; r < rows; r++) { list << sqlQuery.value(r); } results << QVariant(list); } else { results << sqlQuery.value(0); } } if (!rows && query.startsWith("insert", Qt::CaseInsensitive)) { results << sqlQuery.lastInsertId(); } db.close(); return results; } db.close(); } QString text; if (sqlQuery.lastError().isValid()) { text = sqlQuery.lastError().text(); } else { text = db.lastError().text(); } qDebug() << "SQL error:" << text; return QVariant(); } // etc QVariant QT::dataPath(const QVariant& prefix) { // for desktop QString path = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); path.truncate(path.lastIndexOf(QChar('/'))); path.append(QStringLiteral("/cl-meshtastic/") + prefix.toString()); return path; } QVariant QT::localIp() { // returns the local IP string; private networks may use: // 10.*.*.* // 172.16.*.* // 192.168.*.* const auto addresses = QNetworkInterface::allAddresses(); QStringList ips; for (QHostAddress adr : addresses) { if (adr.protocol() == QAbstractSocket::IPv4Protocol) { QString ip(adr.toString()); if (ip.startsWith("10.") || ip.startsWith("172.16.") || ip.startsWith("192.168.")) { ips << ip; } } } if (!ips.isEmpty()) { // hack for rare, ambiguous cases ips.sort(); return ips.first(); } return QVariant(); } QT_END_NAMESPACE