Store nodes in db, use their name when posting to matrix
This commit is contained in:
parent
e147f8a5ed
commit
7362eb4546
6 changed files with 91 additions and 14 deletions
|
@ -2,8 +2,11 @@ package bridge
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"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/matrix"
|
||||||
"git.janky.solutions/finn/matrix-meshtastic-bridge-go/meshtastic/protobufs"
|
"git.janky.solutions/finn/matrix-meshtastic-bridge-go/meshtastic/protobufs"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
@ -11,29 +14,86 @@ import (
|
||||||
|
|
||||||
func RunBridge(ctx context.Context, fromRadioCh chan *protobufs.FromRadio) {
|
func RunBridge(ctx context.Context, fromRadioCh chan *protobufs.FromRadio) {
|
||||||
for {
|
for {
|
||||||
|
var err error
|
||||||
fromRadio := <-fromRadioCh
|
fromRadio := <-fromRadioCh
|
||||||
switch payload := fromRadio.PayloadVariant.(type) {
|
switch payload := fromRadio.PayloadVariant.(type) {
|
||||||
case *protobufs.FromRadio_Channel:
|
case *protobufs.FromRadio_Channel:
|
||||||
logrus.WithField("type", "channel").Debugf("received %+v", payload)
|
logrus.WithField("type", "channel").Debugf("received %+v", payload)
|
||||||
|
case *protobufs.FromRadio_NodeInfo:
|
||||||
|
err = handleNodeInfo(ctx, payload.NodeInfo)
|
||||||
case *protobufs.FromRadio_Packet:
|
case *protobufs.FromRadio_Packet:
|
||||||
if err := handlePacket(ctx, payload.Packet); err != nil {
|
err = handlePacket(ctx, payload.Packet)
|
||||||
logrus.WithError(err).Error("error handling meshtastic packet")
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
logrus.Debugf("received unknown message type: %+v", payload)
|
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 {
|
func handlePacket(ctx context.Context, packet *protobufs.MeshPacket) error {
|
||||||
payload, ok := packet.PayloadVariant.(*protobufs.MeshPacket_Decoded)
|
payload, ok := packet.PayloadVariant.(*protobufs.MeshPacket_Decoded)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil // ignore encrypted packets for now
|
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 {
|
switch payload.Decoded.Portnum {
|
||||||
case protobufs.PortNum_TEXT_MESSAGE_APP:
|
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:
|
default:
|
||||||
logrus.WithField("type", protobufs.PortNum_name[int32(payload.Decoded.Portnum)]).Debug("ignoring unknown app payload")
|
logrus.WithField("type", protobufs.PortNum_name[int32(payload.Decoded.Portnum)]).Debug("ignoring unknown app payload")
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,31 @@ import (
|
||||||
"database/sql"
|
"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
|
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,
|
meshtastic_id = excluded.meshtastic_id,
|
||||||
long_name = excluded.long_name,
|
long_name = excluded.long_name,
|
||||||
short_name = excluded.short_name,
|
short_name = excluded.short_name,
|
||||||
mac = excluded.mac,
|
|
||||||
hw_model = excluded.hw_model,
|
hw_model = excluded.hw_model,
|
||||||
public_key = excluded.public_key
|
public_key = excluded.public_key
|
||||||
`
|
`
|
||||||
|
@ -25,7 +44,6 @@ type MeshtasticNodeUpdateParams struct {
|
||||||
MeshtasticID string
|
MeshtasticID string
|
||||||
LongName sql.NullString
|
LongName sql.NullString
|
||||||
ShortName sql.NullString
|
ShortName sql.NullString
|
||||||
Mac sql.NullString
|
|
||||||
HwModel sql.NullString
|
HwModel sql.NullString
|
||||||
PublicKey []byte
|
PublicKey []byte
|
||||||
}
|
}
|
||||||
|
@ -36,7 +54,6 @@ func (q *Queries) MeshtasticNodeUpdate(ctx context.Context, arg MeshtasticNodeUp
|
||||||
arg.MeshtasticID,
|
arg.MeshtasticID,
|
||||||
arg.LongName,
|
arg.LongName,
|
||||||
arg.ShortName,
|
arg.ShortName,
|
||||||
arg.Mac,
|
|
||||||
arg.HwModel,
|
arg.HwModel,
|
||||||
arg.PublicKey,
|
arg.PublicKey,
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,11 +4,10 @@ PRAGMA foreign_keys = ON;
|
||||||
|
|
||||||
CREATE TABLE meshtastic_nodes (
|
CREATE TABLE meshtastic_nodes (
|
||||||
id INTEGER PRIMARY KEY NOT NULL,
|
id INTEGER PRIMARY KEY NOT NULL,
|
||||||
node_num INTEGER NOT NULL,
|
node_num INTEGER UNIQUE NOT NULL,
|
||||||
meshtastic_id TEXT NOT NULL,
|
meshtastic_id TEXT NOT NULL,
|
||||||
long_name TEXT,
|
long_name TEXT,
|
||||||
short_name TEXT,
|
short_name TEXT,
|
||||||
mac TEXT,
|
|
||||||
hw_model TEXT,
|
hw_model TEXT,
|
||||||
public_key BLOB,
|
public_key BLOB,
|
||||||
matrix_id TEXT
|
matrix_id TEXT
|
||||||
|
|
|
@ -32,7 +32,6 @@ type MeshtasticNode struct {
|
||||||
MeshtasticID string
|
MeshtasticID string
|
||||||
LongName sql.NullString
|
LongName sql.NullString
|
||||||
ShortName sql.NullString
|
ShortName sql.NullString
|
||||||
Mac sql.NullString
|
|
||||||
HwModel sql.NullString
|
HwModel sql.NullString
|
||||||
PublicKey []byte
|
PublicKey []byte
|
||||||
MatrixID sql.NullString
|
MatrixID sql.NullString
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
-- name: MeshtasticNodeUpdate :exec
|
-- 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,
|
meshtastic_id = excluded.meshtastic_id,
|
||||||
long_name = excluded.long_name,
|
long_name = excluded.long_name,
|
||||||
short_name = excluded.short_name,
|
short_name = excluded.short_name,
|
||||||
mac = excluded.mac,
|
|
||||||
hw_model = excluded.hw_model,
|
hw_model = excluded.hw_model,
|
||||||
public_key = excluded.public_key;
|
public_key = excluded.public_key;
|
||||||
|
|
||||||
|
-- name: MeshtasticNodeGet :one
|
||||||
|
SELECT * FROM meshtastic_nodes WHERE node_num = ? LIMIT 1;
|
||||||
|
|
|
@ -31,7 +31,7 @@ func Setup(ctx context.Context) error {
|
||||||
UserAgent: "matrix-meshtastic-bridge-go/unversioned",
|
UserAgent: "matrix-meshtastic-bridge-go/unversioned",
|
||||||
Client: &http.Client{Timeout: 180 * time.Second},
|
Client: &http.Client{Timeout: 180 * time.Second},
|
||||||
Syncer: mautrix.NewDefaultSyncer(),
|
Syncer: mautrix.NewDefaultSyncer(),
|
||||||
Log: zerolog.New(logrus.New().Out),
|
Log: zerolog.Nop(),
|
||||||
Store: dbSyncStore{},
|
Store: dbSyncStore{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue