aboutsummaryrefslogtreecommitdiff
path: root/examples/mqtt/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'examples/mqtt/main.go')
-rw-r--r--examples/mqtt/main.go92
1 files changed, 92 insertions, 0 deletions
diff --git a/examples/mqtt/main.go b/examples/mqtt/main.go
new file mode 100644
index 0000000..0ad9c5f
--- /dev/null
+++ b/examples/mqtt/main.go
@@ -0,0 +1,92 @@
+package main
+
+import (
+ "encoding/base64"
+ "encoding/hex"
+ "fmt"
+ "github.com/charmbracelet/log"
+ pb "github.com/meshnet-gophers/meshtastic-go/meshtastic"
+ "github.com/meshnet-gophers/meshtastic-go/mqtt"
+ "github.com/meshnet-gophers/meshtastic-go/radio"
+ "google.golang.org/protobuf/proto"
+ "strings"
+)
+
+func main() {
+ client := mqtt.NewClient("tcp://mqtt.meshtastic.org:1883", "meshdev", "large4cats", "msh")
+ err := client.Connect()
+ if err != nil {
+ log.Fatal(err)
+ }
+ client.Handle("LongFast", channelHandler("LongFast"))
+ log.Info("Started")
+ select {}
+}
+
+func channelHandler(channel string) mqtt.HandlerFunc {
+ return func(m mqtt.Message) {
+ var env pb.ServiceEnvelope
+ err := proto.Unmarshal(m.Payload, &env)
+ if err != nil {
+ log.Fatal("failed unmarshalling to service envelope", "err", err, "payload", hex.EncodeToString(m.Payload))
+ return
+ }
+
+ key, err := generateKey("1PG7OiApB1nwvP+rz05pAQ==")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ decodedMessage, err := radio.XOR(env.Packet.GetEncrypted(), key, env.Packet.Id, env.Packet.From)
+ if err != nil {
+ log.Error(err)
+ }
+ var message pb.Data
+ err = proto.Unmarshal(decodedMessage, &message)
+
+ log.Info(processMessage(message), "topic", m.Topic, "channel", channel, "portnum", message.Portnum.String())
+ }
+}
+
+func processMessage(message pb.Data) string {
+ if message.Portnum == pb.PortNum_NODEINFO_APP {
+ var user = pb.User{}
+ proto.Unmarshal(message.Payload, &user)
+ return user.String()
+ }
+ if message.Portnum == pb.PortNum_POSITION_APP {
+ var pos = pb.Position{}
+ proto.Unmarshal(message.Payload, &pos)
+ return pos.String()
+ }
+ if message.Portnum == pb.PortNum_TELEMETRY_APP {
+ var t = pb.Telemetry{}
+ proto.Unmarshal(message.Payload, &t)
+ return t.String()
+ }
+ if message.Portnum == pb.PortNum_NEIGHBORINFO_APP {
+ var n = pb.NeighborInfo{}
+ proto.Unmarshal(message.Payload, &n)
+ return n.String()
+ }
+ if message.Portnum == pb.PortNum_STORE_FORWARD_APP {
+ var s = pb.StoreAndForward{}
+ proto.Unmarshal(message.Payload, &s)
+ return s.String()
+ }
+
+ return fmt.Sprintf("unknown message type")
+}
+
+func generateKey(key string) ([]byte, error) {
+ // Pad the key with '=' characters to ensure it's a valid base64 string
+ padding := (4 - len(key)%4) % 4
+ paddedKey := key + strings.Repeat("=", padding)
+
+ // Replace '-' with '+' and '_' with '/'
+ replacedKey := strings.ReplaceAll(paddedKey, "-", "+")
+ replacedKey = strings.ReplaceAll(replacedKey, "_", "/")
+
+ // Decode the base64-encoded key
+ return base64.StdEncoding.DecodeString(replacedKey)
+}