Store nodes in db, use their name when posting to matrix

This commit is contained in:
Finn 2024-10-20 21:17:11 -07:00
parent e147f8a5ed
commit 7362eb4546
6 changed files with 91 additions and 14 deletions

View file

@ -2,8 +2,11 @@ package bridge
import (
"context"
"database/sql"
"errors"
"fmt"
"git.janky.solutions/finn/matrix-meshtastic-bridge-go/db"
"git.janky.solutions/finn/matrix-meshtastic-bridge-go/matrix"
"git.janky.solutions/finn/matrix-meshtastic-bridge-go/meshtastic/protobufs"
"github.com/sirupsen/logrus"
@ -11,29 +14,86 @@ import (
func RunBridge(ctx context.Context, fromRadioCh chan *protobufs.FromRadio) {
for {
var err error
fromRadio := <-fromRadioCh
switch payload := fromRadio.PayloadVariant.(type) {
case *protobufs.FromRadio_Channel:
logrus.WithField("type", "channel").Debugf("received %+v", payload)
case *protobufs.FromRadio_NodeInfo:
err = handleNodeInfo(ctx, payload.NodeInfo)
case *protobufs.FromRadio_Packet:
if err := handlePacket(ctx, payload.Packet); err != nil {
logrus.WithError(err).Error("error handling meshtastic packet")
}
err = handlePacket(ctx, payload.Packet)
default:
logrus.Debugf("received unknown message type: %+v", payload)
}
if err != nil {
logrus.WithError(err).Error("error handling meshtastic message")
}
}
}
func handleNodeInfo(ctx context.Context, nodeInfo *protobufs.NodeInfo) error {
if nodeInfo == nil {
logrus.Warn("handleNodeInfo called with null nodeInfo")
return nil
}
queries, dbconn, err := db.Get()
if err != nil {
return err
}
defer dbconn.Close()
params := db.MeshtasticNodeUpdateParams{NodeNum: int64(nodeInfo.Num)}
if nodeInfo.User != nil { // sometimes this is null, it seems
params.MeshtasticID = nodeInfo.User.Id
params.LongName = db.NullableString(nodeInfo.User.LongName)
params.ShortName = db.NullableString(nodeInfo.User.ShortName)
params.HwModel = db.NullableString(nodeInfo.User.HwModel.String())
params.PublicKey = nodeInfo.User.PublicKey
}
err = queries.MeshtasticNodeUpdate(ctx, params)
if err != nil {
return err
}
logrus.WithField("node_num", nodeInfo.Num).Debug("updated info for node")
return nil
}
func handlePacket(ctx context.Context, packet *protobufs.MeshPacket) error {
payload, ok := packet.PayloadVariant.(*protobufs.MeshPacket_Decoded)
if !ok {
return nil // ignore encrypted packets for now
}
queries, dbconn, err := db.Get()
if err != nil {
return err
}
defer dbconn.Close()
sourceNode, err := queries.MeshtasticNodeGet(ctx, int64(packet.From))
if err != nil && !errors.Is(err, sql.ErrNoRows) {
logrus.WithError(err).Error("error getting packet source node from database")
}
var sourceString string
if sourceNode.LongName.Valid {
sourceString = fmt.Sprintf("%s (%s/%x)", sourceNode.LongName.String, sourceNode.ShortName.String, packet.From)
} else {
sourceString = fmt.Sprintf("%x", packet.From)
}
logrus.WithField("source", sourceString).Debug("handling incoming meshtastic node")
switch payload.Decoded.Portnum {
case protobufs.PortNum_TEXT_MESSAGE_APP:
matrix.SendMessage(ctx, fmt.Sprintf("text from %x: %s (snr: %f, rssi: %d, hop limit: %d, hop start: %d)", packet.From, payload.Decoded.Payload, packet.RxSnr, packet.RxRssi, packet.HopLimit, packet.HopStart))
return matrix.SendMessage(ctx, fmt.Sprintf("text from %s: %s (snr: %f, rssi: %d, hop limit: %d, hop start: %d)", sourceString, payload.Decoded.Payload, packet.RxSnr, packet.RxRssi, packet.HopLimit, packet.HopStart))
default:
logrus.WithField("type", protobufs.PortNum_name[int32(payload.Decoded.Portnum)]).Debug("ignoring unknown app payload")
}

View file

@ -10,12 +10,31 @@ import (
"database/sql"
)
const meshtasticNodeGet = `-- name: MeshtasticNodeGet :one
SELECT id, node_num, meshtastic_id, long_name, short_name, hw_model, public_key, matrix_id FROM meshtastic_nodes WHERE node_num = ? LIMIT 1
`
func (q *Queries) MeshtasticNodeGet(ctx context.Context, nodeNum int64) (MeshtasticNode, error) {
row := q.db.QueryRowContext(ctx, meshtasticNodeGet, nodeNum)
var i MeshtasticNode
err := row.Scan(
&i.ID,
&i.NodeNum,
&i.MeshtasticID,
&i.LongName,
&i.ShortName,
&i.HwModel,
&i.PublicKey,
&i.MatrixID,
)
return i, err
}
const meshtasticNodeUpdate = `-- name: MeshtasticNodeUpdate :exec
INSERT INTO meshtastic_nodes (node_num, meshtastic_id, long_name, short_name, mac, hw_model, public_key) VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT (node_num) DO UPDATE SET
INSERT INTO meshtastic_nodes (node_num, meshtastic_id, long_name, short_name, hw_model, public_key) VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT (node_num) DO UPDATE SET
meshtastic_id = excluded.meshtastic_id,
long_name = excluded.long_name,
short_name = excluded.short_name,
mac = excluded.mac,
hw_model = excluded.hw_model,
public_key = excluded.public_key
`
@ -25,7 +44,6 @@ type MeshtasticNodeUpdateParams struct {
MeshtasticID string
LongName sql.NullString
ShortName sql.NullString
Mac sql.NullString
HwModel sql.NullString
PublicKey []byte
}
@ -36,7 +54,6 @@ func (q *Queries) MeshtasticNodeUpdate(ctx context.Context, arg MeshtasticNodeUp
arg.MeshtasticID,
arg.LongName,
arg.ShortName,
arg.Mac,
arg.HwModel,
arg.PublicKey,
)

View file

@ -4,11 +4,10 @@ PRAGMA foreign_keys = ON;
CREATE TABLE meshtastic_nodes (
id INTEGER PRIMARY KEY NOT NULL,
node_num INTEGER NOT NULL,
node_num INTEGER UNIQUE NOT NULL,
meshtastic_id TEXT NOT NULL,
long_name TEXT,
short_name TEXT,
mac TEXT,
hw_model TEXT,
public_key BLOB,
matrix_id TEXT

View file

@ -32,7 +32,6 @@ type MeshtasticNode struct {
MeshtasticID string
LongName sql.NullString
ShortName sql.NullString
Mac sql.NullString
HwModel sql.NullString
PublicKey []byte
MatrixID sql.NullString

View file

@ -1,8 +1,10 @@
-- name: MeshtasticNodeUpdate :exec
INSERT INTO meshtastic_nodes (node_num, meshtastic_id, long_name, short_name, mac, hw_model, public_key) VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT (node_num) DO UPDATE SET
INSERT INTO meshtastic_nodes (node_num, meshtastic_id, long_name, short_name, hw_model, public_key) VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT (node_num) DO UPDATE SET
meshtastic_id = excluded.meshtastic_id,
long_name = excluded.long_name,
short_name = excluded.short_name,
mac = excluded.mac,
hw_model = excluded.hw_model,
public_key = excluded.public_key;
-- name: MeshtasticNodeGet :one
SELECT * FROM meshtastic_nodes WHERE node_num = ? LIMIT 1;

View file

@ -31,7 +31,7 @@ func Setup(ctx context.Context) error {
UserAgent: "matrix-meshtastic-bridge-go/unversioned",
Client: &http.Client{Timeout: 180 * time.Second},
Syncer: mautrix.NewDefaultSyncer(),
Log: zerolog.New(logrus.New().Out),
Log: zerolog.Nop(),
Store: dbSyncStore{},
}