mirror of
https://gitlab.com/eql/lqml.git
synced 2025-12-06 02:30:38 -08:00
example 'meshtastic': minor update (define device to be used)
This commit is contained in:
parent
9ee7030350
commit
c77d993496
11 changed files with 90 additions and 35 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
(defsystem :app
|
(defsystem :app
|
||||||
:serial t
|
:serial t
|
||||||
:depends-on (#-depends-loaded :uiop
|
:depends-on (#-depends-loaded :uiop
|
||||||
|
#-depends-loaded :cl-base64
|
||||||
#-depends-loaded :my-cl-protobufs
|
#-depends-loaded :my-cl-protobufs
|
||||||
#-depends-loaded :trivial-package-local-nicknames)
|
#-depends-loaded :trivial-package-local-nicknames)
|
||||||
:components ((:file "lisp/package")
|
:components ((:file "lisp/package")
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ void BLE::startDeviceDiscovery() {
|
||||||
|
|
||||||
void BLE::addDevice(const QBluetoothDeviceInfo& device) {
|
void BLE::addDevice(const QBluetoothDeviceInfo& device) {
|
||||||
if (deviceFilter(device)) {
|
if (deviceFilter(device)) {
|
||||||
qDebug() << "device added: " << device.name();
|
qDebug() << "device added:" << device.name() << device.address().toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,7 +108,7 @@ void BLE::serviceScanDone() {
|
||||||
|
|
||||||
void BLE::connectToService(const QString& uuid) {
|
void BLE::connectToService(const QString& uuid) {
|
||||||
QLowEnergyService* service = nullptr;
|
QLowEnergyService* service = nullptr;
|
||||||
for (auto s: qAsConst(services)) {
|
for (auto s : qAsConst(services)) {
|
||||||
if (s->serviceUuid().toString() == uuid) {
|
if (s->serviceUuid().toString() == uuid) {
|
||||||
service = s;
|
service = s;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,29 @@ QObject* ini() {
|
||||||
return qt;
|
return qt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QBluetoothDeviceInfo toDeviceInfo(const QVariantMap& map) {
|
||||||
|
return QBluetoothDeviceInfo(QBluetoothAddress(map.value("address").toString()),
|
||||||
|
map.value("name").toString(),
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
QT::QT() : QObject() {
|
QT::QT() : QObject() {
|
||||||
ble = new BLE_ME;
|
ble = new BLE_ME;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant QT::startDeviceDiscovery() {
|
QVariant QT::setDevice(const QVariant& vMap) {
|
||||||
|
auto map = vMap.value<QVariantMap>();
|
||||||
|
ble->setCurrentDevice(toDeviceInfo(map));
|
||||||
|
return vMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant QT::startDeviceDiscovery(const QVariant& vMap) {
|
||||||
|
auto map = vMap.value<QVariantMap>();
|
||||||
|
if (!map.isEmpty()) {
|
||||||
|
ble->currentDevice = toDeviceInfo(map);
|
||||||
|
}
|
||||||
ble->startDeviceDiscovery();
|
ble->startDeviceDiscovery();
|
||||||
return QVariant();
|
return vMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant QT::read2() {
|
QVariant QT::read2() {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,8 @@ class QT : public QObject {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// BLE_ME
|
// BLE_ME
|
||||||
Q_INVOKABLE QVariant startDeviceDiscovery();
|
Q_INVOKABLE QVariant setDevice(const QVariant&);
|
||||||
|
Q_INVOKABLE QVariant startDeviceDiscovery(const QVariant& = QVariant());
|
||||||
Q_INVOKABLE QVariant read2();
|
Q_INVOKABLE QVariant read2();
|
||||||
Q_INVOKABLE QVariant write2(const QVariant&);
|
Q_INVOKABLE QVariant write2(const QVariant&);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,14 @@
|
||||||
(in-package :app)
|
(in-package :app)
|
||||||
|
|
||||||
|
;; set here the name and address of your 2 devices
|
||||||
|
;; (see debug output during device discovery)
|
||||||
|
|
||||||
|
(defvar *device-1* '(:name "Meshtastic_128c" :address "F4:12:FA:9D:12:8D"))
|
||||||
|
(defvar *device-2* '(:name "Meshtastic_1c9c" :address "F4:12:FA:9D:1C:9D"))
|
||||||
|
|
||||||
(defun ini ()
|
(defun ini ()
|
||||||
(qt:ini)
|
(qt:ini)
|
||||||
(qt:start-device-discovery qt:*ble*)
|
(qt:start-device-discovery qt:*ble* *device-1*) ; set device (see above)
|
||||||
(msg:load-messages)
|
(msg:load-messages)
|
||||||
(q> |playing| ui:*loading* nil) ; shown during Lisp startup
|
(q> |playing| ui:*loading* nil) ; shown during Lisp startup
|
||||||
(q> |playing| ui:*busy* t)) ; shown during BLE setup
|
(q> |playing| ui:*busy* t)) ; shown during BLE setup
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
(:local-nicknames (:pr :cl-protobufs)
|
(:local-nicknames (:pr :cl-protobufs)
|
||||||
(:me :cl-protobufs.meshtastic))
|
(:me :cl-protobufs.meshtastic))
|
||||||
(:export
|
(:export
|
||||||
|
#:*channel*
|
||||||
#:*channels*
|
#:*channels*
|
||||||
#:*config-lora*
|
#:*config-lora*
|
||||||
#:*my-node-info*
|
#:*my-node-info*
|
||||||
|
|
@ -17,13 +18,16 @@
|
||||||
#:*received*
|
#:*received*
|
||||||
#:*region*
|
#:*region*
|
||||||
#:*remote-node*
|
#:*remote-node*
|
||||||
|
#:channel-to-url
|
||||||
#:start-config
|
#:start-config
|
||||||
#:read-radio
|
#:read-radio
|
||||||
#:received-from-radio
|
#:received-from-radio
|
||||||
#:receiving-done
|
#:receiving-done
|
||||||
#:send-message
|
#:send-message
|
||||||
#:send-to-radio
|
#:send-to-radio
|
||||||
#:set-ready))
|
#:set-fixed-pin
|
||||||
|
#:set-ready
|
||||||
|
#:url-to-channel))
|
||||||
|
|
||||||
(defpackage :messages
|
(defpackage :messages
|
||||||
(:nicknames :msg)
|
(:nicknames :msg)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
(:export
|
(:export
|
||||||
#:*ble*
|
#:*ble*
|
||||||
#:ini
|
#:ini
|
||||||
|
#:set-device
|
||||||
#:start-device-discovery
|
#:start-device-discovery
|
||||||
#:read*
|
#:read*
|
||||||
#:write*))
|
#:write*))
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
(defvar *region* :eu-868) ; Europe 868 MHz
|
(defvar *region* :eu-868) ; Europe 868 MHz
|
||||||
|
|
||||||
(defvar *primary-channel* nil)
|
(defvar *my-channel* nil)
|
||||||
(defvar *channels* nil)
|
(defvar *channels* nil)
|
||||||
(defvar *my-node-info* nil)
|
(defvar *my-node-info* nil)
|
||||||
(defvar *node-infos* nil)
|
(defvar *node-infos* nil)
|
||||||
(defvar *config-lora* nil)
|
(defvar *config-lora* nil)
|
||||||
|
|
||||||
;;; header
|
;;; header
|
||||||
|
|
||||||
|
|
@ -109,21 +109,22 @@
|
||||||
(dolist (struct *received*)
|
(dolist (struct *received*)
|
||||||
(cond ((me:from-radio.has-packet struct)
|
(cond ((me:from-radio.has-packet struct)
|
||||||
(let* ((packet (me:from-radio.packet struct))
|
(let* ((packet (me:from-radio.packet struct))
|
||||||
(decoded (me:decoded packet))
|
(decoded (me:decoded packet)))
|
||||||
(payload (me:payload decoded)))
|
(when decoded
|
||||||
(case (me:portnum decoded)
|
(let ((payload (me:payload decoded)))
|
||||||
;; text-message
|
(case (me:portnum decoded)
|
||||||
(:text-message-app
|
;; text-message
|
||||||
(msg:add-message
|
(:text-message-app
|
||||||
(list :text (babel:octets-to-string payload)
|
(msg:add-message
|
||||||
:sender (node-to-name (me:from packet))
|
(list :text (babel:octets-to-string payload)
|
||||||
:timestamp (timestamp-to-string))))
|
:sender (node-to-name (me:from packet))
|
||||||
;; for :ack-state (acknowledgement state)
|
:timestamp (timestamp-to-string))))
|
||||||
(:routing-app
|
;; for :ack-state (acknowledgement state)
|
||||||
(msg:change-state (case (me:routing.error-reason
|
(:routing-app
|
||||||
(pr:deserialize-from-bytes 'me:routing payload))
|
(msg:change-state (case (me:routing.error-reason
|
||||||
(:none :received))
|
(pr:deserialize-from-bytes 'me:routing payload))
|
||||||
(me:request-id decoded))))))
|
(:none :received))
|
||||||
|
(me:request-id decoded))))))))
|
||||||
;; my-info
|
;; my-info
|
||||||
((me:from-radio.has-my-info struct)
|
((me:from-radio.has-my-info struct)
|
||||||
(setf *my-node-info* (me:my-node-num (me:my-info struct))))
|
(setf *my-node-info* (me:my-node-num (me:my-info struct))))
|
||||||
|
|
@ -136,9 +137,9 @@
|
||||||
;; channel
|
;; channel
|
||||||
((me:from-radio.has-channel struct)
|
((me:from-radio.has-channel struct)
|
||||||
(let ((channel (me:channel struct)))
|
(let ((channel (me:channel struct)))
|
||||||
(if (eql :primary (me:role channel))
|
(when (eql :primary (me:role channel))
|
||||||
(setf *primary-channel* channel)
|
(setf *my-channel* channel))
|
||||||
(push channel *channels*))))
|
(push channel *channels*)))
|
||||||
;; config lora
|
;; config lora
|
||||||
((me:from-radio.has-config struct)
|
((me:from-radio.has-config struct)
|
||||||
(let ((config (me:config struct)))
|
(let ((config (me:config struct)))
|
||||||
|
|
@ -163,6 +164,10 @@
|
||||||
:payload (pr:serialize-to-bytes admin-message)
|
:payload (pr:serialize-to-bytes admin-message)
|
||||||
:want-response t)))))
|
:want-response t)))))
|
||||||
|
|
||||||
|
(defun set-channel (channel)
|
||||||
|
(send-admin (me:make-admin-message
|
||||||
|
:set-channel (setf *my-channel* channel))))
|
||||||
|
|
||||||
(defun config-device ()
|
(defun config-device ()
|
||||||
"Absolut minimum necessary for sending text messages."
|
"Absolut minimum necessary for sending text messages."
|
||||||
;; lora settings
|
;; lora settings
|
||||||
|
|
@ -175,8 +180,24 @@
|
||||||
:hop-limit 3
|
:hop-limit 3
|
||||||
:tx-enabled t))))
|
:tx-enabled t))))
|
||||||
;; channel settings
|
;; channel settings
|
||||||
(send-admin
|
(set-channel (me:make-channel
|
||||||
(me:make-admin-message
|
:settings (me:make-channel-settings :psk (to-bytes (list 1)))
|
||||||
:set-channel (me:make-channel
|
:role :primary)))
|
||||||
:settings (me:make-channel-settings :psk (to-bytes (list 1)))
|
|
||||||
:role :primary))))
|
(defun channel-to-url (&optional channel)
|
||||||
|
(let ((base64 (base64:usb8-array-to-base64-string
|
||||||
|
(pr:serialize-to-bytes (or channel *my-channel*)))))
|
||||||
|
;; remove padding, substitute characters as by definition
|
||||||
|
(x:cc "https:/meshtastic.org/e/#"
|
||||||
|
(string-right-trim "=" (substitute #\- #\+ (substitute #\_ #\/ base64))))))
|
||||||
|
|
||||||
|
(defun url-to-channel (url &optional (set t))
|
||||||
|
(let ((base64 (+ 2 (subseq "/#" url))))
|
||||||
|
;; re-add padding
|
||||||
|
(setf base64 (x:cc base64
|
||||||
|
(make-string (mod (length base64) 4) :initial-element #\=)))
|
||||||
|
(let ((channel (pr:deserialize-from-bytes
|
||||||
|
(base64:base64-string-to-usb8-array base64))))
|
||||||
|
(if set
|
||||||
|
(set-channel channel)
|
||||||
|
channel))))
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,10 @@ restart the phone.
|
||||||
On Linux you might need to restart the bluetooth service if you want to pair
|
On Linux you might need to restart the bluetooth service if you want to pair
|
||||||
a different device (after already pairing a first one).
|
a different device (after already pairing a first one).
|
||||||
|
|
||||||
|
To choose which app instance will use which device, set both name and address
|
||||||
|
in [main.lisp](lisp/main.lisp), and set one app to `*device-1*` and the other
|
||||||
|
to `*device-2*`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Run
|
Run
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
asdf:*central-registry*)
|
asdf:*central-registry*)
|
||||||
|
|
||||||
(asdf:load-system :uiop)
|
(asdf:load-system :uiop)
|
||||||
|
(asdf:load-system :cl-base64)
|
||||||
(asdf:load-system :trivial-package-local-nicknames)
|
(asdf:load-system :trivial-package-local-nicknames)
|
||||||
|
|
||||||
;; may take very long on mobile devices
|
;; may take very long on mobile devices
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 216 KiB After Width: | Height: | Size: 201 KiB |
Loading…
Add table
Add a link
Reference in a new issue