protobuf
Source github.com/meshtastic/protobufs converted to golang using protoc with protoc-gen-go
from pkg.go.dev/google.golang.org/protobuf.
Intallation and fully working example usage
go get gitplac.si/gomeshtastic/protobuf/v2@v2.5.5
package main
import (
"bytes"
"log"
"math/rand"
pb "gitplac.si/gomeshtastic/protobuf/v2"
"go.bug.st/serial"
"google.golang.org/protobuf/proto"
)
func main() {
serialPort, err := serial.Open("/dev/ttyACM0", &serial.Mode{
BaudRate: 115200,
DataBits: 8,
Parity: serial.MarkParity,
})
if err != nil {
panic(err)
}
//
// Create protobuf packet requesting radio configuration
//
rndConfigCompleteId := uint32(rand.Intn(100))
getConfigPacket, err := proto.Marshal(&pb.ToRadio{PayloadVariant: &pb.ToRadio_WantConfigId{WantConfigId: rndConfigCompleteId}})
if err != nil {
panic(nil)
}
packageLength := len(string(getConfigPacket))
writePacket := []byte{0x94, 0xc3, byte(packageLength>>8) & 0xff, byte(packageLength) & 0xff}
writePacket = append(writePacket, getConfigPacket...)
//
// Write the packet to the serial device
//
_, err = serialPort.Write(writePacket)
if err != nil {
panic(err)
}
//
// Read packets from serial device and log them
// until a packet with the same ID (uint32) that
// we generated above is returned
//
for {
buffer_bytes := []byte{}
for {
p := make([]byte, 128)
n, err := serialPort.Read(p)
if err != nil {
panic(err)
}
buffer_bytes = append(buffer_bytes, p[:n]...)
// In search of packet start
for i := 0; i+3 < len(buffer_bytes); i++ {
if !bytes.Equal(buffer_bytes[i:i+2], []byte{0x94, 0xc3}) {
continue
}
packetLength := int((buffer_bytes[i+2] << 8) + buffer_bytes[i+3])
potential_packet_bytes := buffer_bytes[i+4 : min(len(buffer_bytes), i+4+packetLength)]
for {
bytesMissing := packetLength - len(potential_packet_bytes)
if bytesMissing <= 0 {
break
}
p := make([]byte, bytesMissing)
n, err := serialPort.Read(p)
if err != nil {
panic(err)
}
buffer_bytes = append(buffer_bytes, p[:n]...)
potential_packet_bytes = buffer_bytes[i+4:]
}
fromRadio := pb.FromRadio{}
if errUnMarshal := proto.Unmarshal(potential_packet_bytes, &fromRadio); errUnMarshal != nil {
continue
}
log.Print(&fromRadio)
if configCompletePacket, ok := fromRadio.GetPayloadVariant().(*pb.FromRadio_ConfigCompleteId); ok {
if configCompletePacket.ConfigCompleteId == rndConfigCompleteId {
log.Print("Got valid ConfigCompleteId packet")
return
}
}
}
// Always keep at most last 4 bytes between runs
// discard everything in front of those bytes
buffer_bytes = buffer_bytes[max(len(buffer_bytes), 4)-4:]
}
}
}
Update protobufs
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
rm *.go # remove all protobuf definitions
git clone https://github.com/meshtastic/protobufs/
cd protobufs/
git checkout v2.5.3 # change the version of protobuf definitions you want to commit
PATH=$PATH:~/go/bin/ protoc --proto_path=./ --go_out=../ --go_opt=Mnanopb.proto=./ meshtastic/*.proto
cd ..
mv github.com/meshtastic/go/generated/*.pb.go .
rm -r protobufs github.com
# Remove possible dynamic import from generated source files
# REMOVE THIS if it exists: _ "./"
go mod tidy