mirror of
https://gitlab.com/eql/lqml.git
synced 2025-12-30 05:41:27 -08:00
example 'meshtastic': refactor connection part
This commit is contained in:
parent
679fca2d25
commit
013a75d3f5
22 changed files with 432 additions and 285 deletions
|
|
@ -163,14 +163,16 @@ SOURCES += \
|
||||||
|
|
||||||
!android {
|
!android {
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
cpp/ble/ble.h \
|
cpp/connection/connection.h \
|
||||||
cpp/ble/ble_meshtastic.h \
|
cpp/connection/ble/ble.h \
|
||||||
cpp/usb/usb_meshtastic.h
|
cpp/connection/ble/ble_meshtastic.h \
|
||||||
|
cpp/connection/usb/usb_meshtastic.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
cpp/ble/ble.cpp \
|
cpp/connection/connection.cpp \
|
||||||
cpp/ble/ble_meshtastic.cpp \
|
cpp/convention/ble/ble.cpp \
|
||||||
cpp/usb/usb_meshtastic.cpp
|
cpp/convention/ble/ble_meshtastic.cpp \
|
||||||
|
cpp/convention/usb/usb_meshtastic.cpp
|
||||||
}
|
}
|
||||||
|
|
||||||
RESOURCES += $$files(qml/*)
|
RESOURCES += $$files(qml/*)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
#include "qtandroidservice_ro.h"
|
#include "qtandroidservice_ro.h"
|
||||||
#include "../ble/ble_meshtastic.h"
|
|
||||||
|
|
||||||
#if (QT_VERSION < 0x060000)
|
#if (QT_VERSION < 0x060000)
|
||||||
#include <QAndroidService>
|
#include <QAndroidService>
|
||||||
|
|
@ -14,7 +13,5 @@ int main(int argc, char* argv[]) {
|
||||||
QtAndroidService qtAndroidService;
|
QtAndroidService qtAndroidService;
|
||||||
srcNode.enableRemoting(&qtAndroidService);
|
srcNode.enableRemoting(&qtAndroidService);
|
||||||
|
|
||||||
BLE_ME ble(&qtAndroidService);
|
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
class QtAndroidService {
|
class QtAndroidService {
|
||||||
SLOT(void startDeviceDiscovery(const QString&));
|
SLOT(void setConnectionType(const QVariant&));
|
||||||
SLOT(void setDeviceFilter(const QString&));
|
SLOT(void startDeviceDiscovery(const QVariant&));
|
||||||
SLOT(void read());
|
SLOT(void stopDeviceDiscovery());
|
||||||
SLOT(void write(const QByteArray&));
|
SLOT(void setDeviceFilter(const QVariant&));
|
||||||
|
SLOT(void read2());
|
||||||
|
SLOT(void write2(const QVariant&));
|
||||||
SLOT(void setBackgroundMode(bool));
|
SLOT(void setBackgroundMode(bool));
|
||||||
SIGNAL(deviceDiscovered(const QString&));
|
|
||||||
|
SIGNAL(deviceDiscovered(const QVariant&));
|
||||||
SIGNAL(bleError());
|
SIGNAL(bleError());
|
||||||
SIGNAL(setReady(bool, const QString&, const QStringList&));
|
SIGNAL(setReady(const QVariant&));
|
||||||
SIGNAL(receivedFromRadio(const QByteArray&, const QString&));
|
SIGNAL(receivedFromRadio(const QVariant&));
|
||||||
SIGNAL(receivingDone());
|
SIGNAL(receivingDone());
|
||||||
SIGNAL(sendSavedPackets(const QVariant&));
|
SIGNAL(sendSavedPackets(const QVariant&));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
#include "rep_qtandroidservice_source.h"
|
#include "rep_qtandroidservice_source.h"
|
||||||
#include "../ble/ble_meshtastic.h"
|
#include "../connection/connection.h"
|
||||||
|
|
||||||
class QtAndroidService : public QtAndroidServiceSource {
|
class QtAndroidService : public QtAndroidServiceSource {
|
||||||
public:
|
public:
|
||||||
BLE_ME* ble = nullptr;
|
QtAndroidService() { con = new Connection(this); }
|
||||||
|
Connection* con;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void startDeviceDiscovery(const QString& a1) override { ble->startDeviceDiscovery(a1); }
|
void setConnectionType(const QVariant& a1) override { con->setConnectionType(a1); }
|
||||||
void setDeviceFilter(const QString& a1) override { ble->setDeviceFilter(a1); }
|
void startDeviceDiscovery(const QVariant& a1) override { con->startDeviceDiscovery(a1); }
|
||||||
void read() override { ble->read(); }
|
void stopDeviceDiscovery() override { con->stopDeviceDiscovery(); }
|
||||||
void write(const QByteArray& a1) override { ble->write(a1); }
|
void setDeviceFilter(const QVariant& a1) override { con->setDeviceFilter(a1); }
|
||||||
void setBackgroundMode(bool a1) override { ble->setBackgroundMode(a1); }
|
void read2() override { con->read2(); }
|
||||||
|
void write2(const QVariant& a1) override { con->write2(a1); }
|
||||||
|
void setBackgroundMode(bool a1) override { con->setBackgroundMode(a1); }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
QT += core bluetooth remoteobjects
|
QT += core bluetooth serialport remoteobjects
|
||||||
TEMPLATE = lib
|
TEMPLATE = lib
|
||||||
CONFIG += c++17 dll
|
CONFIG += c++17 dll
|
||||||
INCLUDEPATH += $$PWD
|
INCLUDEPATH += $$PWD
|
||||||
|
|
@ -15,13 +15,17 @@ lessThan(QT_MAJOR_VERSION, 6) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
../ble/ble.h \
|
../connection/connection.h \
|
||||||
../ble/ble_meshtastic.h \
|
../connection/ble/ble.h \
|
||||||
|
../connection/ble/ble_meshtastic.h \
|
||||||
|
../connection/usb/usb_meshtastic.h \
|
||||||
qtandroidservice_ro.h
|
qtandroidservice_ro.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
../ble/ble.cpp \
|
../connection/connection.cpp \
|
||||||
../ble/ble_meshtastic.cpp \
|
../connection/ble/ble.cpp \
|
||||||
|
../connection/ble/ble_meshtastic.cpp \
|
||||||
|
../connection/usb/usb_meshtastic.cpp \
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|
||||||
REPC_SOURCE += qtandroidservice.rep
|
REPC_SOURCE += qtandroidservice.rep
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,9 @@
|
||||||
#include "ble_meshtastic.h"
|
#include "ble_meshtastic.h"
|
||||||
|
#include "../connection.h"
|
||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
#include <QStandardPaths>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QDataStream>
|
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
#include "../android_service/qtandroidservice_ro.h"
|
#include "../../android_service/qtandroidservice_ro.h"
|
||||||
#if (QT_VERSION < 0x060000)
|
|
||||||
#include <QAndroidService>
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// service
|
// service
|
||||||
|
|
@ -20,13 +15,12 @@ const UID BLE_ME::uuid_fromRadio = UID(STR("{2c55e69e-4993-11ed-b878-0242ac12000
|
||||||
const UID BLE_ME::uuid_fromNum = UID(STR("{ed9da18c-a800-4f66-a670-aa7547e34453}"));
|
const UID BLE_ME::uuid_fromNum = UID(STR("{ed9da18c-a800-4f66-a670-aa7547e34453}"));
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
BLE_ME::BLE_ME(QtAndroidService* service) : BLE(uuid_service), emitter(service) {
|
BLE_ME::BLE_ME(QtAndroidService* service, Connection* _con) : BLE(uuid_service), emitter(service), con(_con) {
|
||||||
service->ble = this;
|
|
||||||
// forward signals defined in class BLE
|
// forward signals defined in class BLE
|
||||||
connect(this, &BLE::deviceDiscovered, emitter, &QtAndroidService::deviceDiscovered);
|
connect(this, &BLE::deviceDiscovered, service, &QtAndroidService::deviceDiscovered);
|
||||||
connect(this, &BLE::bleError, emitter, &QtAndroidService::bleError);
|
connect(this, &BLE::bleError, service, &QtAndroidService::bleError);
|
||||||
#else
|
#else
|
||||||
BLE_ME::BLE_ME() : BLE(uuid_service), emitter(this) {
|
BLE_ME::BLE_ME(Connection* _con) : BLE(uuid_service), emitter(_con), con(_con) {
|
||||||
#endif
|
#endif
|
||||||
connect(this, &BLE::mainServiceReady, this, &BLE_ME::ini);
|
connect(this, &BLE::mainServiceReady, this, &BLE_ME::ini);
|
||||||
connect(this, &BLE::deviceDisconnecting, this, &BLE_ME::disconnecting);
|
connect(this, &BLE::deviceDisconnecting, this, &BLE_ME::disconnecting);
|
||||||
|
|
@ -111,8 +105,10 @@ void BLE_ME::searchCharacteristics() {
|
||||||
for (auto device : qAsConst(devices)) {
|
for (auto device : qAsConst(devices)) {
|
||||||
names << device.name().right(4);
|
names << device.name().right(4);
|
||||||
}
|
}
|
||||||
if (!backgroundMode) {
|
if (!con->backgroundMode) {
|
||||||
emitter->setReady(true, currentDevice.name().right(4), names);
|
QVariantList vNames;
|
||||||
|
for (auto name : qAsConst(names)) { vNames << name; }
|
||||||
|
emitter->setReady(QVariant(QVariantList() << true << currentDevice.name().right(4) << vNames));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -120,10 +116,10 @@ void BLE_ME::searchCharacteristics() {
|
||||||
void BLE_ME::characteristicChanged(const QLowEnergyCharacteristic&,
|
void BLE_ME::characteristicChanged(const QLowEnergyCharacteristic&,
|
||||||
const QByteArray& data) {
|
const QByteArray& data) {
|
||||||
if (!data.isEmpty()) {
|
if (!data.isEmpty()) {
|
||||||
if (backgroundMode) {
|
if (con->backgroundMode) {
|
||||||
read();
|
read();
|
||||||
} else {
|
} else {
|
||||||
emitter->receivedFromRadio(data, "notified");
|
emitter->receivedFromRadio(QVariant(QVariantList() << data << QString("notified")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -131,20 +127,20 @@ void BLE_ME::characteristicChanged(const QLowEnergyCharacteristic&,
|
||||||
void BLE_ME::characteristicRead(const QLowEnergyCharacteristic&,
|
void BLE_ME::characteristicRead(const QLowEnergyCharacteristic&,
|
||||||
const QByteArray& data) {
|
const QByteArray& data) {
|
||||||
if (data.isEmpty()) {
|
if (data.isEmpty()) {
|
||||||
if (!backgroundMode) {
|
if (!con->backgroundMode) {
|
||||||
emitter->receivingDone();
|
emitter->receivingDone();
|
||||||
static bool startup = true;
|
static bool startup = true;
|
||||||
if (startup) {
|
if (startup) {
|
||||||
sendSavedBytes(); // for eventual, saved but not sent packets
|
con->sendSavedBytes(); // for eventual, saved but not sent packets
|
||||||
} else {
|
} else {
|
||||||
startup = false;
|
startup = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (backgroundMode) {
|
if (con->backgroundMode) {
|
||||||
saveBytes(data);
|
con->saveBytes(data);
|
||||||
} else {
|
} else {
|
||||||
emitter->receivedFromRadio(data, QString());
|
emitter->receivedFromRadio(QVariant(QVariantList() << data));
|
||||||
}
|
}
|
||||||
read();
|
read();
|
||||||
}
|
}
|
||||||
|
|
@ -188,57 +184,9 @@ void BLE_ME::disconnecting() {
|
||||||
// disable notifications
|
// disable notifications
|
||||||
mainService->writeDescriptor(notifications, QByteArray::fromHex("0000"));
|
mainService->writeDescriptor(notifications, QByteArray::fromHex("0000"));
|
||||||
}
|
}
|
||||||
if (!backgroundMode) {
|
if (!con->backgroundMode) {
|
||||||
emitter->setReady(false, QString(), QStringList());
|
emitter->setReady(QVariant(QVariantList()));
|
||||||
}
|
}
|
||||||
delete mainService; mainService = nullptr;
|
delete mainService; mainService = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// background mode
|
|
||||||
|
|
||||||
void BLE_ME::setBackgroundMode(bool background) {
|
|
||||||
#if (defined Q_OS_ANDROID) || (defined Q_OS_IOS)
|
|
||||||
backgroundMode = background;
|
|
||||||
qDebug() << "background mode:" << backgroundMode;
|
|
||||||
if (!backgroundMode) {
|
|
||||||
sendSavedBytes();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static QString packetsFile() {
|
|
||||||
// choose already existing directory
|
|
||||||
QStandardPaths::StandardLocation location = QStandardPaths::AppDataLocation;
|
|
||||||
#ifdef Q_OS_IOS
|
|
||||||
location = QStandardPaths::DocumentsLocation;
|
|
||||||
#endif
|
|
||||||
return QStandardPaths::writableLocation(location) + QStringLiteral("/meshtastic-packets.bin");
|
|
||||||
}
|
|
||||||
|
|
||||||
void BLE_ME::saveBytes(const QByteArray& packet) {
|
|
||||||
QFile file(packetsFile());
|
|
||||||
if (file.open(QIODevice::WriteOnly | QIODevice::Append)) {
|
|
||||||
QDataStream ds(&file);
|
|
||||||
ds << packet;
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BLE_ME::sendSavedBytes() {
|
|
||||||
QVariantList packets;
|
|
||||||
QString fileName(packetsFile());
|
|
||||||
QFile file(fileName);
|
|
||||||
if (file.open(QIODevice::ReadOnly)) {
|
|
||||||
QDataStream ds(&file);
|
|
||||||
while (!ds.atEnd()) {
|
|
||||||
QByteArray packet;
|
|
||||||
ds >> packet;
|
|
||||||
packets.append(packet);
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
if (!packets.isEmpty()) {
|
|
||||||
emitter->sendSavedPackets(QVariant(packets));
|
|
||||||
QFile::remove(fileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -6,8 +6,9 @@
|
||||||
#define STR QStringLiteral
|
#define STR QStringLiteral
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
class QtAndroidService;
|
class QtAndroidService;
|
||||||
#endif
|
#endif
|
||||||
|
class Connection;
|
||||||
|
|
||||||
class BLE_ME : public BLE {
|
class BLE_ME : public BLE {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -16,16 +17,15 @@ class BLE_ME : public BLE {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
BLE_ME(QtAndroidService*);
|
BLE_ME(QtAndroidService*, Connection*);
|
||||||
#else
|
#else
|
||||||
BLE_ME();
|
BLE_ME(Connection*);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void setDeviceFilter(const QString& s) { filter = s; }
|
void setDeviceFilter(const QString& s) { filter = s; }
|
||||||
void read();
|
void read();
|
||||||
void write(const QByteArray&);
|
void write(const QByteArray&);
|
||||||
void setBackgroundMode(bool);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void setReady(bool, const QString&, const QStringList&);
|
void setReady(bool, const QString&, const QStringList&);
|
||||||
|
|
@ -48,9 +48,9 @@ public:
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
QtAndroidService* emitter = nullptr;
|
QtAndroidService* emitter = nullptr;
|
||||||
#else
|
#else
|
||||||
BLE_ME* emitter = nullptr;
|
Connection* emitter = nullptr;
|
||||||
#endif
|
#endif
|
||||||
bool backgroundMode = false;
|
Connection* con = nullptr;
|
||||||
QString filter = "meshtastic";
|
QString filter = "meshtastic";
|
||||||
QLowEnergyDescriptor notifications;
|
QLowEnergyDescriptor notifications;
|
||||||
|
|
||||||
|
|
@ -66,8 +66,4 @@ private Q_SLOTS:
|
||||||
void characteristicWritten(const QLowEnergyCharacteristic&, const QByteArray&);
|
void characteristicWritten(const QLowEnergyCharacteristic&, const QByteArray&);
|
||||||
void serviceError(QLowEnergyService::ServiceError);
|
void serviceError(QLowEnergyService::ServiceError);
|
||||||
void disconnecting();
|
void disconnecting();
|
||||||
|
|
||||||
private:
|
|
||||||
void saveBytes(const QByteArray&);
|
|
||||||
void sendSavedBytes();
|
|
||||||
};
|
};
|
||||||
122
examples/meshtastic/cpp/connection/connection.cpp
Normal file
122
examples/meshtastic/cpp/connection/connection.cpp
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
#include "connection.h"
|
||||||
|
#include "ble/ble_meshtastic.h"
|
||||||
|
#include "usb/usb_meshtastic.h"
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDataStream>
|
||||||
|
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
#include "../android_service/qtandroidservice_ro.h"
|
||||||
|
#if (QT_VERSION < 0x060000)
|
||||||
|
#include <QAndroidService>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
Connection::Connection(QtAndroidService* service) {
|
||||||
|
// forward signal
|
||||||
|
connect(this, &Connection::sendSavedPackets, service, &QtAndroidService::sendSavedPackets);
|
||||||
|
ble = new BLE_ME(service, service->con);
|
||||||
|
usb = new USB_ME(service, service->con);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
Connection::Connection() {
|
||||||
|
ble = new BLE_ME(this);
|
||||||
|
usb = new USB_ME(this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Connection::setConnectionType(const QVariant& vType) {
|
||||||
|
QByteArray t = vType.toByteArray();
|
||||||
|
if (t == "USB") {
|
||||||
|
type = USB;
|
||||||
|
} else {
|
||||||
|
type = BLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Connection::startDeviceDiscovery(const QVariant& vName) {
|
||||||
|
switch (type) {
|
||||||
|
case BLE:
|
||||||
|
usb->disconnect();
|
||||||
|
ble->startDeviceDiscovery(vName.toString());
|
||||||
|
break;
|
||||||
|
case USB:
|
||||||
|
ble->disconnect();
|
||||||
|
usb->connectToRadio();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Connection::stopDeviceDiscovery() {
|
||||||
|
ble->stopDeviceDiscovery();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Connection::setDeviceFilter(const QVariant& vName) {
|
||||||
|
ble->setDeviceFilter(vName.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Connection::read2() {
|
||||||
|
ble->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Connection::write2(const QVariant& vBytes) {
|
||||||
|
QByteArray bytes = vBytes.toByteArray();
|
||||||
|
switch (type) {
|
||||||
|
case BLE:
|
||||||
|
ble->write(bytes);
|
||||||
|
break;
|
||||||
|
case USB:
|
||||||
|
usb->write2(bytes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// background mode
|
||||||
|
|
||||||
|
void Connection::setBackgroundMode(bool background) {
|
||||||
|
#if (defined Q_OS_ANDROID) || (defined Q_OS_IOS)
|
||||||
|
backgroundMode = background;
|
||||||
|
qDebug() << "background mode:" << backgroundMode;
|
||||||
|
if (!backgroundMode) {
|
||||||
|
sendSavedBytes();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString packetsFile() {
|
||||||
|
// choose already existing directory
|
||||||
|
QStandardPaths::StandardLocation location = QStandardPaths::AppDataLocation;
|
||||||
|
#ifdef Q_OS_IOS
|
||||||
|
location = QStandardPaths::DocumentsLocation;
|
||||||
|
#endif
|
||||||
|
return QStandardPaths::writableLocation(location) + QStringLiteral("/meshtastic-packets.bin");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Connection::saveBytes(const QByteArray& packet) {
|
||||||
|
QFile file(packetsFile());
|
||||||
|
if (file.open(QIODevice::WriteOnly | QIODevice::Append)) {
|
||||||
|
QDataStream ds(&file);
|
||||||
|
ds << packet;
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Connection::sendSavedBytes() {
|
||||||
|
QVariantList packets;
|
||||||
|
QString fileName(packetsFile());
|
||||||
|
QFile file(fileName);
|
||||||
|
if (file.open(QIODevice::ReadOnly)) {
|
||||||
|
QDataStream ds(&file);
|
||||||
|
while (!ds.atEnd()) {
|
||||||
|
QByteArray packet;
|
||||||
|
ds >> packet;
|
||||||
|
packets.append(packet);
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
if (!packets.isEmpty()) {
|
||||||
|
Q_EMIT sendSavedPackets(QVariant(packets));
|
||||||
|
QFile::remove(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
49
examples/meshtastic/cpp/connection/connection.h
Normal file
49
examples/meshtastic/cpp/connection/connection.h
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
class BLE_ME;
|
||||||
|
class USB_ME;
|
||||||
|
class QtAndroidService;
|
||||||
|
|
||||||
|
class Connection : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
Connection(QtAndroidService*);
|
||||||
|
#else
|
||||||
|
Connection();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
BLE, USB
|
||||||
|
};
|
||||||
|
|
||||||
|
Type type = BLE;
|
||||||
|
BLE_ME* ble = nullptr;
|
||||||
|
USB_ME* usb = nullptr;
|
||||||
|
bool backgroundMode = false;
|
||||||
|
|
||||||
|
void setConnectionType(const QVariant&);
|
||||||
|
void startDeviceDiscovery(const QVariant&);
|
||||||
|
void stopDeviceDiscovery();
|
||||||
|
void setDeviceFilter(const QVariant&);
|
||||||
|
void read2();
|
||||||
|
void write2(const QVariant&);
|
||||||
|
void setBackgroundMode(bool);
|
||||||
|
|
||||||
|
// background mode
|
||||||
|
void saveBytes(const QByteArray&);
|
||||||
|
void sendSavedBytes();
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void deviceDiscovered(const QVariant&);
|
||||||
|
void bleError();
|
||||||
|
void setReady(const QVariant&);
|
||||||
|
void receivedFromRadio(const QVariant&);
|
||||||
|
void receivingDone();
|
||||||
|
void sendSavedPackets(const QVariant&);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -1,10 +1,19 @@
|
||||||
#include "usb_meshtastic.h"
|
#include "usb_meshtastic.h"
|
||||||
|
#include "../connection.h"
|
||||||
#include <QSerialPortInfo>
|
#include <QSerialPortInfo>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
|
|
||||||
USB_ME::USB_ME() {
|
#ifdef Q_OS_ANDROID
|
||||||
|
#include "../../android_service/qtandroidservice_ro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
USB_ME::USB_ME(QtAndroidService* service, Connection* _con) : emitter(service), con(_con) {
|
||||||
|
#else
|
||||||
|
USB_ME::USB_ME(Connection* _con) : emitter(_con), con(_con) {
|
||||||
|
#endif
|
||||||
connect(this, &QSerialPort::readyRead, this, &USB_ME::read2);
|
connect(this, &QSerialPort::readyRead, this, &USB_ME::read2);
|
||||||
connect(this, &QSerialPort::errorOccurred,
|
connect(this, &QSerialPort::errorOccurred,
|
||||||
[](QSerialPort::SerialPortError error) {
|
[](QSerialPort::SerialPortError error) {
|
||||||
|
|
@ -16,14 +25,16 @@ USB_ME::USB_ME() {
|
||||||
|
|
||||||
void USB_ME::connectToRadio() {
|
void USB_ME::connectToRadio() {
|
||||||
if (isOpen()) {
|
if (isOpen()) {
|
||||||
Q_EMIT setReady(portName());
|
if (!con->backgroundMode) {
|
||||||
|
emitter->setReady(QVariant(QVariantList() << portName()));
|
||||||
|
}
|
||||||
qDebug() << "USB already open;" << portName();
|
qDebug() << "USB already open;" << portName();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto infos = QSerialPortInfo::availablePorts();
|
const auto infos = QSerialPortInfo::availablePorts();
|
||||||
const QStringList supported = { "RAK" }; // TODO: currently RAK only
|
const QStringList supported = { "RAK" }; // TODO: currently RAK only
|
||||||
for (const QSerialPortInfo& info : infos) {
|
for (auto info : infos) {
|
||||||
QString name(info.description() + " " + info.manufacturer());
|
QString name(info.description() + " " + info.manufacturer());
|
||||||
QString port(info.portName());
|
QString port(info.portName());
|
||||||
if (port.startsWith("tty") &&
|
if (port.startsWith("tty") &&
|
||||||
|
|
@ -38,13 +49,15 @@ void USB_ME::connectToRadio() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
done:
|
|
||||||
|
|
||||||
|
done:
|
||||||
if (!open(QIODevice::ReadWrite)) {
|
if (!open(QIODevice::ReadWrite)) {
|
||||||
qDebug() << "USB: unable to open port" << portName();
|
qDebug() << "USB: unable to open port" << portName();
|
||||||
} else {
|
} else {
|
||||||
ready = true;
|
ready = true;
|
||||||
Q_EMIT setReady(portName());
|
if (!con->backgroundMode) {
|
||||||
|
emitter->setReady(QVariant(QVariantList() << portName()));
|
||||||
|
}
|
||||||
qDebug() << "USB open";
|
qDebug() << "USB open";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -72,18 +85,38 @@ void USB_ME::read2() {
|
||||||
int end = 0;
|
int end = 0;
|
||||||
int start = LEN;
|
int start = LEN;
|
||||||
while ((end = data.indexOf(HEADER, start)) != -1) {
|
while ((end = data.indexOf(HEADER, start)) != -1) {
|
||||||
Q_EMIT receivedFromRadio(data.mid(start, end - start));
|
received(data.mid(start, end - start));
|
||||||
start = end + LEN;
|
start = end + LEN;
|
||||||
}
|
}
|
||||||
Q_EMIT receivedFromRadio(data.mid(start));
|
received(data.mid(start));
|
||||||
|
|
||||||
static QTimer* timer = nullptr;
|
static QTimer* timer = nullptr;
|
||||||
if (!timer) {
|
if (timer == nullptr) {
|
||||||
timer = new QTimer;
|
timer = new QTimer;
|
||||||
timer->setSingleShot(true);
|
timer->setSingleShot(true);
|
||||||
connect(timer, &QTimer::timeout, this, &USB_ME::receivingDone);
|
connect(timer, &QTimer::timeout, this, &USB_ME::done);
|
||||||
}
|
}
|
||||||
timer->start(1000); // assume receiving done after pause of 1 sec
|
timer->start(1000); // assume receiving done after pause of 1 sec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USB_ME::received(const QByteArray& data) {
|
||||||
|
if (con->backgroundMode) {
|
||||||
|
con->saveBytes(data);
|
||||||
|
} else {
|
||||||
|
emitter->receivedFromRadio(QVariant(QVariantList() << data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void USB_ME::done() {
|
||||||
|
if (!con->backgroundMode) {
|
||||||
|
emitter->receivingDone();
|
||||||
|
static bool startup = true;
|
||||||
|
if (startup) {
|
||||||
|
con->sendSavedBytes(); // for eventual, saved but not sent packets
|
||||||
|
} else {
|
||||||
|
startup = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
49
examples/meshtastic/cpp/connection/usb/usb_meshtastic.h
Normal file
49
examples/meshtastic/cpp/connection/usb/usb_meshtastic.h
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QSerialPort>
|
||||||
|
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
class QtAndroidService;
|
||||||
|
#endif
|
||||||
|
class Connection;
|
||||||
|
|
||||||
|
class USB_ME : public QSerialPort {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
/*** <INTERFACE> ****************************************/
|
||||||
|
|
||||||
|
public:
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
USB_ME(QtAndroidService*, Connection*);
|
||||||
|
#else
|
||||||
|
USB_ME(Connection*);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void connectToRadio();
|
||||||
|
void disconnect();
|
||||||
|
void read2();
|
||||||
|
void write2(const QByteArray&);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void setReady(const QString&);
|
||||||
|
void receivedFromRadio(const QByteArray&);
|
||||||
|
void receivingDone();
|
||||||
|
|
||||||
|
/*** </INTERFACE> ***************************************/
|
||||||
|
|
||||||
|
public:
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
QtAndroidService* emitter = nullptr;
|
||||||
|
#else
|
||||||
|
Connection* emitter = nullptr;
|
||||||
|
#endif
|
||||||
|
Connection* con = nullptr;
|
||||||
|
bool ready = false;
|
||||||
|
|
||||||
|
void received(const QByteArray&);
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void done();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -21,8 +21,7 @@
|
||||||
#include <QtCore/private/qandroidextras_p.h>
|
#include <QtCore/private/qandroidextras_p.h>
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#include "ble/ble_meshtastic.h"
|
#include "connection/connection.h"
|
||||||
#include "usb/usb_meshtastic.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
@ -35,92 +34,72 @@ QObject* ini() {
|
||||||
return qt;
|
return qt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// connection
|
||||||
|
|
||||||
QT::QT() : QObject() {
|
QT::QT() : QObject() {
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
// remote object for android service
|
// remote object for android service
|
||||||
QRemoteObjectNode* repNode = new QRemoteObjectNode;
|
QRemoteObjectNode* repNode = new QRemoteObjectNode;
|
||||||
repNode->connectToNode(QUrl(QStringLiteral("local:replica")));
|
repNode->connectToNode(QUrl(QStringLiteral("local:replica")));
|
||||||
QSharedPointer<QtAndroidServiceReplica> rep(repNode->acquire<QtAndroidServiceReplica>());
|
con = repNode->acquire<QtAndroidServiceReplica>();
|
||||||
bool res = rep->waitForSource();
|
bool res = con->waitForSource();
|
||||||
Q_ASSERT(res);
|
Q_ASSERT(res);
|
||||||
|
|
||||||
ble = rep;
|
|
||||||
#else
|
#else
|
||||||
ble = new BLE_ME;
|
con = new Connection;
|
||||||
#endif
|
#endif
|
||||||
usb = new USB_ME;
|
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
QObject::connect(ble.data(), &QtAndroidServiceReplica::deviceDiscovered,
|
QObject::connect(con, &QtAndroidServiceReplica::deviceDiscovered,
|
||||||
#else
|
#else
|
||||||
QObject::connect(ble, &BLE::deviceDiscovered,
|
QObject::connect(con, &Connection::deviceDiscovered,
|
||||||
#endif
|
#endif
|
||||||
[](const QString& fullName) {
|
[](const QVariant& vFullName) {
|
||||||
ecl_fun("radios:device-discovered", fullName.right(4));
|
ecl_fun("radios:device-discovered", vFullName.toString().right(4));
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
QObject::connect(ble.data(), &QtAndroidServiceReplica::bleError,
|
QObject::connect(con, &QtAndroidServiceReplica::bleError,
|
||||||
#else
|
#else
|
||||||
QObject::connect(ble, &BLE::bleError,
|
QObject::connect(con, &Connection::bleError,
|
||||||
#endif
|
#endif
|
||||||
[]() {
|
[]() {
|
||||||
ecl_fun("radios:reset");
|
ecl_fun("radios:reset");
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
QObject::connect(ble.data(), &QtAndroidServiceReplica::setReady,
|
QObject::connect(con, &QtAndroidServiceReplica::setReady,
|
||||||
#else
|
#else
|
||||||
QObject::connect(ble, &BLE_ME::setReady,
|
QObject::connect(con, &Connection::setReady,
|
||||||
#endif
|
#endif
|
||||||
[](bool ready, const QString& current, const QStringList& names) {
|
[](const QVariant& vArg) {
|
||||||
QVariantList vNames; // Lisp doesn't know 'QStringList'
|
ecl_fun("lora:set-ready", vArg);
|
||||||
for (auto name : names) {
|
|
||||||
vNames << name;
|
|
||||||
}
|
|
||||||
ecl_fun("lora:set-ready-ble", ready, current, vNames);
|
|
||||||
});
|
|
||||||
|
|
||||||
QObject::connect(usb, &USB_ME::setReady,
|
|
||||||
[](const QString& port) {
|
|
||||||
ecl_fun("lora:set-ready-usb", port);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
QObject::connect(ble.data(), &QtAndroidServiceReplica::receivedFromRadio,
|
QObject::connect(con, &QtAndroidServiceReplica::receivedFromRadio,
|
||||||
#else
|
#else
|
||||||
QObject::connect(ble, &BLE_ME::receivedFromRadio,
|
QObject::connect(con, &Connection::receivedFromRadio,
|
||||||
#endif
|
#endif
|
||||||
[](const QByteArray& data, const QString& notified) {
|
[](const QVariant& vArg) {
|
||||||
ecl_fun("lora:received-from-radio", data, notified.isEmpty() ? QVariant() : notified);
|
ecl_fun("lora:received-from-radio", vArg);
|
||||||
});
|
|
||||||
|
|
||||||
QObject::connect(usb, &USB_ME::receivedFromRadio,
|
|
||||||
[](const QByteArray& data) {
|
|
||||||
ecl_fun("lora:received-from-radio", data);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
QObject::connect(ble.data(), &QtAndroidServiceReplica::receivingDone,
|
QObject::connect(con, &QtAndroidServiceReplica::receivingDone,
|
||||||
#else
|
#else
|
||||||
QObject::connect(ble, &BLE_ME::receivingDone,
|
QObject::connect(con, &Connection::receivingDone,
|
||||||
#endif
|
#endif
|
||||||
[]() {
|
[]() {
|
||||||
ecl_fun("lora:receiving-done");
|
ecl_fun("lora:receiving-done");
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(usb, &USB_ME::receivingDone,
|
|
||||||
[]() {
|
|
||||||
ecl_fun("lora:receiving-done");
|
|
||||||
});
|
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
QObject::connect(ble.data(), &QtAndroidServiceReplica::sendSavedPackets,
|
QObject::connect(con, &QtAndroidServiceReplica::sendSavedPackets,
|
||||||
#else
|
#else
|
||||||
QObject::connect(ble, &BLE_ME::sendSavedPackets,
|
QObject::connect(con, &Connection::sendSavedPackets,
|
||||||
#endif
|
#endif
|
||||||
[](const QVariant& packets) {
|
[](const QVariant& vPackets) {
|
||||||
ecl_fun("lora:process-saved-packets", packets);
|
ecl_fun("lora:process-saved-packets", vPackets);
|
||||||
});
|
});
|
||||||
|
|
||||||
#if (defined Q_OS_ANDROID) || (defined Q_OS_IOS)
|
#if (defined Q_OS_ANDROID) || (defined Q_OS_IOS)
|
||||||
|
|
@ -128,14 +107,14 @@ QT::QT() : QObject() {
|
||||||
QObject::connect(qGuiApp, &QGuiApplication::applicationStateChanged,
|
QObject::connect(qGuiApp, &QGuiApplication::applicationStateChanged,
|
||||||
[&](Qt::ApplicationState state) {
|
[&](Qt::ApplicationState state) {
|
||||||
if (state == Qt::ApplicationInactive) {
|
if (state == Qt::ApplicationInactive) {
|
||||||
ble->setBackgroundMode(true);
|
con->setBackgroundMode(true);
|
||||||
ecl_fun("app:background-mode-changed", true);
|
ecl_fun("app:background-mode-changed", true);
|
||||||
} else if (state == Qt::ApplicationActive) {
|
} else if (state == Qt::ApplicationActive) {
|
||||||
static bool startup = true;
|
static bool startup = true;
|
||||||
if (startup) {
|
if (startup) {
|
||||||
startup = false;
|
startup = false;
|
||||||
} else {
|
} else {
|
||||||
ble->setBackgroundMode(false);
|
con->setBackgroundMode(false);
|
||||||
ecl_fun("app:background-mode-changed", false);
|
ecl_fun("app:background-mode-changed", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -143,50 +122,33 @@ QT::QT() : QObject() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// BLE
|
QVariant QT::setConnectionType(const QVariant& vType) {
|
||||||
|
con->setConnectionType(vType);
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
QVariant QT::startDeviceDiscovery(const QVariant& vName) {
|
QVariant QT::startDeviceDiscovery(const QVariant& vName) {
|
||||||
QByteArray connection(ecl_fun("radios:connection").toString().toLatin1());
|
con->startDeviceDiscovery(vName);
|
||||||
if (connection == "BLE") {
|
return QVariant();
|
||||||
usb->disconnect();
|
|
||||||
ble->startDeviceDiscovery(vName.toString());
|
|
||||||
} else if (connection == "USB") {
|
|
||||||
ble->disconnect();
|
|
||||||
usb->connectToRadio();
|
|
||||||
}
|
|
||||||
return vName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant QT::stopDeviceDiscovery() {
|
QVariant QT::stopDeviceDiscovery() {
|
||||||
ble->stopDeviceDiscovery();
|
con->stopDeviceDiscovery();
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant QT::setDeviceFilter(const QVariant& vName) {
|
QVariant QT::setDeviceFilter(const QVariant& vName) {
|
||||||
ble->setDeviceFilter(vName.toString());
|
con->setDeviceFilter(vName);
|
||||||
return vName;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant QT::readBle() {
|
|
||||||
ble->read();
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant QT::writeBle(const QVariant& vBytes) {
|
QVariant QT::read2() {
|
||||||
ble->write(vBytes.toByteArray());
|
con->read2();
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant QT::setBackgroundMode(const QVariant& vBackground) {
|
QVariant QT::write2(const QVariant& vBytes) {
|
||||||
// for testing
|
con->write2(vBytes);
|
||||||
ble->setBackgroundMode(vBackground.toBool());
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
// USB
|
|
||||||
|
|
||||||
QVariant QT::writeUsb(const QVariant& vBytes) {
|
|
||||||
usb->write2(vBytes.toByteArray());
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -312,7 +274,7 @@ QVariant QT::dataPath(const QVariant& prefix) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant QT::localIp() {
|
QVariant QT::localIp() {
|
||||||
// Returns the local IP string. Private networks may use:
|
// returns the local IP string; private networks may use:
|
||||||
// 10.*.*.*
|
// 10.*.*.*
|
||||||
// 172.16.*.*
|
// 172.16.*.*
|
||||||
// 192.168.*.*
|
// 192.168.*.*
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,7 @@
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
class QtAndroidServiceReplica;
|
class QtAndroidServiceReplica;
|
||||||
#else
|
#else
|
||||||
class BLE_ME;
|
class Connection;
|
||||||
class USB_ME;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
@ -24,16 +23,13 @@ class QT : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// BLE
|
// connection
|
||||||
|
Q_INVOKABLE QVariant setConnectionType(const QVariant&);
|
||||||
Q_INVOKABLE QVariant startDeviceDiscovery(const QVariant&);
|
Q_INVOKABLE QVariant startDeviceDiscovery(const QVariant&);
|
||||||
Q_INVOKABLE QVariant stopDeviceDiscovery();
|
Q_INVOKABLE QVariant stopDeviceDiscovery();
|
||||||
Q_INVOKABLE QVariant setDeviceFilter(const QVariant&);
|
Q_INVOKABLE QVariant setDeviceFilter(const QVariant&);
|
||||||
Q_INVOKABLE QVariant readBle();
|
Q_INVOKABLE QVariant read2();
|
||||||
Q_INVOKABLE QVariant writeBle(const QVariant&);
|
Q_INVOKABLE QVariant write2(const QVariant&);
|
||||||
Q_INVOKABLE QVariant setBackgroundMode(const QVariant&);
|
|
||||||
|
|
||||||
// USB
|
|
||||||
Q_INVOKABLE QVariant writeUsb(const QVariant&);
|
|
||||||
|
|
||||||
// GPS
|
// GPS
|
||||||
Q_INVOKABLE QVariant iniPositioning();
|
Q_INVOKABLE QVariant iniPositioning();
|
||||||
|
|
@ -54,10 +50,9 @@ public:
|
||||||
|
|
||||||
QSqlDatabase db;
|
QSqlDatabase db;
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
QSharedPointer<QtAndroidServiceReplica> ble;
|
QtAndroidServiceReplica* con = nullptr;
|
||||||
#else
|
#else
|
||||||
BLE_ME* ble = nullptr;
|
Connection* con = nullptr;
|
||||||
USB_ME* usb = nullptr;
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,15 +10,17 @@ OBJECTS_DIR = ./tmp/
|
||||||
MOC_DIR = ./tmp/
|
MOC_DIR = ./tmp/
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
ble/ble.h \
|
connection/connection.h \
|
||||||
ble/ble_meshtastic.h \
|
connection/ble/ble.h \
|
||||||
usb/usb_meshtastic.h \
|
connection/ble/ble_meshtastic.h \
|
||||||
|
connection/usb/usb_meshtastic.h \
|
||||||
qt.h
|
qt.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
ble/ble.cpp \
|
connection/connection.cpp \
|
||||||
ble/ble_meshtastic.cpp \
|
connection/ble/ble.cpp \
|
||||||
usb/usb_meshtastic.cpp \
|
connection/ble/ble_meshtastic.cpp \
|
||||||
|
connection/usb/usb_meshtastic.cpp \
|
||||||
qt.cpp
|
qt.cpp
|
||||||
|
|
||||||
linux {
|
linux {
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QSerialPort>
|
|
||||||
|
|
||||||
class USB_ME : public QSerialPort {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
USB_ME();
|
|
||||||
|
|
||||||
bool ready = false;
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
void connectToRadio();
|
|
||||||
void disconnect();
|
|
||||||
void write2(const QByteArray&);
|
|
||||||
void read2();
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void setReady(const QString&);
|
|
||||||
void receivedFromRadio(const QByteArray&);
|
|
||||||
void receivingDone();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
@ -68,18 +68,22 @@
|
||||||
(me:make-to-radio :want-config-id *config-id*))
|
(me:make-to-radio :want-config-id *config-id*))
|
||||||
(q> |playing| ui:*busy* t)))
|
(q> |playing| ui:*busy* t)))
|
||||||
|
|
||||||
(defun set-ready-ble (&optional ready name ble-names) ; see Qt
|
(defun set-ready (args) ; see Qt
|
||||||
(setf *ready* ready)
|
(case radios:*connection*
|
||||||
(when ready
|
(:ble
|
||||||
(setf *ble-names* ble-names)
|
(destructuring-bind (ready name ble-names)
|
||||||
(app:toast (x:cc (tr "radio") ": " name) 2)
|
args
|
||||||
(get-node-config))
|
(setf *ready* ready)
|
||||||
(values))
|
(when ready
|
||||||
|
(setf *ble-names* ble-names)
|
||||||
(defun set-ready-usb (port) ; see Qt
|
(app:toast (x:cc (tr "radio") ": " name) 2)
|
||||||
(setf *ready* t)
|
(get-node-config))))
|
||||||
(app:toast (x:cc "USB: " port) 2)
|
(:usb
|
||||||
(get-node-config)
|
(destructuring-bind (port)
|
||||||
|
args
|
||||||
|
(setf *ready* t)
|
||||||
|
(app:toast (x:cc "USB: " port) 2)
|
||||||
|
(get-node-config))))
|
||||||
(values))
|
(values))
|
||||||
|
|
||||||
(defun add-line-breaks (text)
|
(defun add-line-breaks (text)
|
||||||
|
|
@ -140,7 +144,7 @@
|
||||||
|
|
||||||
(defun read-radio ()
|
(defun read-radio ()
|
||||||
"Triggers a read on the radio. Will call RECEIVED-FROM-RADIO on success."
|
"Triggers a read on the radio. Will call RECEIVED-FROM-RADIO on success."
|
||||||
(qrun* (qt:read-ble qt:*cpp*)))
|
(qrun* (qt:read* qt:*cpp*)))
|
||||||
|
|
||||||
(defun send-to-radio (to-radio)
|
(defun send-to-radio (to-radio)
|
||||||
"Sends passed TO-RADIO, preceded by a header."
|
"Sends passed TO-RADIO, preceded by a header."
|
||||||
|
|
@ -150,27 +154,29 @@
|
||||||
(header (header (length bytes))))
|
(header (header (length bytes))))
|
||||||
(case radios:*connection*
|
(case radios:*connection*
|
||||||
(:ble (qrun*
|
(:ble (qrun*
|
||||||
(qt:write-ble qt:*cpp* header)
|
(qt:write* qt:*cpp* header)
|
||||||
(qt:write-ble qt:*cpp* bytes)))
|
(qt:write* qt:*cpp* bytes)))
|
||||||
(:usb (qrun*
|
(:usb (qrun*
|
||||||
(qt:write-usb qt:*cpp* (concatenate 'vector header bytes)))))))
|
(qt:write* qt:*cpp* (concatenate 'vector header bytes)))))))
|
||||||
|
|
||||||
(defun received-from-radio (bytes &optional notified) ; see Qt
|
(defun received-from-radio (args) ; see Qt
|
||||||
(if notified
|
(destructuring-bind (bytes &optional notified)
|
||||||
(progn
|
args
|
||||||
(setf *notify-id* bytes)
|
(if notified
|
||||||
(read-radio))
|
(progn
|
||||||
(multiple-value-bind (from-radio error)
|
(setf *notify-id* bytes)
|
||||||
(ignore-errors (pr:deserialize-from-bytes 'me:from-radio bytes))
|
(read-radio))
|
||||||
(setf *reading* t)
|
(multiple-value-bind (from-radio error)
|
||||||
(if from-radio
|
(ignore-errors (pr:deserialize-from-bytes 'me:from-radio bytes))
|
||||||
(progn
|
(setf *reading* t)
|
||||||
(when *print-json*
|
(if from-radio
|
||||||
(pr:print-json from-radio))
|
(progn
|
||||||
(push from-radio *received*))
|
(when *print-json*
|
||||||
(progn
|
(pr:print-json from-radio))
|
||||||
(qlog "received faulty bytes: ~A" error)
|
(push from-radio *received*))
|
||||||
(push bytes *received-faulty*)))))
|
(progn
|
||||||
|
(qlog "received faulty bytes: ~A" error)
|
||||||
|
(push bytes *received-faulty*))))))
|
||||||
(values))
|
(values))
|
||||||
|
|
||||||
(defun receiving-done () ; see Qt
|
(defun receiving-done () ; see Qt
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,11 @@
|
||||||
#:local-ip
|
#:local-ip
|
||||||
#:start-device-discovery
|
#:start-device-discovery
|
||||||
#:stop-device-discovery
|
#:stop-device-discovery
|
||||||
#:read-ble
|
#:read*
|
||||||
#:set-background-mode ; for testing
|
#:set-connection-type
|
||||||
#:set-device-filter
|
#:set-device-filter
|
||||||
#:sql-query
|
#:sql-query
|
||||||
#:write-ble
|
#:write*))
|
||||||
#:write-usb))
|
|
||||||
|
|
||||||
(in-package :qt)
|
(in-package :qt)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
(defun ini ()
|
(defun ini ()
|
||||||
(setf *connection* (or (app:setting :connection)
|
(setf *connection* (or (app:setting :connection)
|
||||||
:ble))
|
:ble))
|
||||||
|
(set-connection-type)
|
||||||
(q> |checked| (symbol-name *connection*) t)
|
(q> |checked| (symbol-name *connection*) t)
|
||||||
(q> |model| ui:*region*
|
(q> |model| ui:*region*
|
||||||
(cons "-" (mapcar 'symbol-name (rest (lora:keywords :region-code)))))
|
(cons "-" (mapcar 'symbol-name (rest (lora:keywords :region-code)))))
|
||||||
|
|
@ -13,17 +14,18 @@
|
||||||
(x:when-it (app:setting :device-filter)
|
(x:when-it (app:setting :device-filter)
|
||||||
(qt:set-device-filter qt:*cpp* x:it)))
|
(qt:set-device-filter qt:*cpp* x:it)))
|
||||||
|
|
||||||
(defun connection () ; see Qt
|
|
||||||
(symbol-name *connection*))
|
|
||||||
|
|
||||||
(defun connection-changed (name)
|
(defun connection-changed (name)
|
||||||
(when (eql *connection* :ble)
|
(when (eql *connection* :ble)
|
||||||
(qt:stop-device-discovery qt:*cpp*))
|
(qt:stop-device-discovery qt:*cpp*))
|
||||||
(let ((con (app:kw name)))
|
(let ((con (app:kw name)))
|
||||||
(setf *connection* con)
|
(setf *connection* con)
|
||||||
(app:change-setting :connection con))
|
(app:change-setting :connection con))
|
||||||
|
(set-connection-type)
|
||||||
(lora:start-device-discovery))
|
(lora:start-device-discovery))
|
||||||
|
|
||||||
|
(defun set-connection-type ()
|
||||||
|
(qt:set-connection-type qt:*cpp* (symbol-name *connection*)))
|
||||||
|
|
||||||
(defun saved-region ()
|
(defun saved-region ()
|
||||||
(let ((region (app:setting :region)))
|
(let ((region (app:setting :region)))
|
||||||
(unless (find region '(nil :unset))
|
(unless (find region '(nil :unset))
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ Item {
|
||||||
text: "USB"
|
text: "USB"
|
||||||
autoExclusive: true
|
autoExclusive: true
|
||||||
checkable: true
|
checkable: true
|
||||||
|
enabled: (Qt.platform.os !== "android") && (Qt.platform.os !== "ios")
|
||||||
onTriggered: connection.changed(objectName)
|
onTriggered: connection.changed(objectName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,14 +66,12 @@ they are 64 bit and run at least iOS 12.
|
||||||
How to use cl-meshtastic
|
How to use cl-meshtastic
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
If you have your radio connected via USB to your PC, you can choose 'USB' as
|
If you have your radio connected to your PC via USB, you can choose 'USB' as
|
||||||
connection type from the main menu (see 'Radios' icon). This currently only
|
connection type from the main menu (see 'Radios' icon). This only works on
|
||||||
works on Linux and macOS, and only with RAK devices (which don't need any
|
Linux and macOS (Windows not tested), and only with RAK devices (which don't
|
||||||
driver, just permission to e.g. `/dev/ttyACM0` on Linux).
|
need any driver, just permission to e.g. `/dev/ttyACM0` on Linux).
|
||||||
|
|
||||||
Android is currently WIP.
|
For mobile there is BLE (Bluetooth Low Energy).
|
||||||
|
|
||||||
The next best option is BLE (Bluetooth Low Energy).
|
|
||||||
|
|
||||||
Your radio needs to be turned on and bluetooth needs to be enabled before you
|
Your radio needs to be turned on and bluetooth needs to be enabled before you
|
||||||
start the app.
|
start the app.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue