diff options
Diffstat (limited to 'examples/mqtt/main.go')
| -rw-r--r-- | examples/mqtt/main.go | 92 |
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) +} |
