aboutsummaryrefslogtreecommitdiff
path: root/examples/mqtt/main.go
blob: 35058d4469526580cab0851f1e57c644708be83e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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)
}