2024-10-21 01:38:35 +00:00
package bridge
import (
"context"
2024-10-21 04:17:11 +00:00
"database/sql"
"errors"
2024-10-21 01:38:35 +00:00
"fmt"
2024-10-21 04:17:11 +00:00
"git.janky.solutions/finn/matrix-meshtastic-bridge-go/db"
2024-10-21 01:38:35 +00:00
"git.janky.solutions/finn/matrix-meshtastic-bridge-go/matrix"
"git.janky.solutions/finn/matrix-meshtastic-bridge-go/meshtastic/protobufs"
"github.com/sirupsen/logrus"
)
func RunBridge ( ctx context . Context , fromRadioCh chan * protobufs . FromRadio ) {
for {
2024-10-21 04:17:11 +00:00
var err error
2024-10-21 01:38:35 +00:00
fromRadio := <- fromRadioCh
switch payload := fromRadio . PayloadVariant . ( type ) {
case * protobufs . FromRadio_Channel :
logrus . WithField ( "type" , "channel" ) . Debugf ( "received %+v" , payload )
2024-10-21 04:17:11 +00:00
case * protobufs . FromRadio_NodeInfo :
err = handleNodeInfo ( ctx , payload . NodeInfo )
2024-10-21 01:38:35 +00:00
case * protobufs . FromRadio_Packet :
2024-10-21 04:17:11 +00:00
err = handlePacket ( ctx , payload . Packet )
2024-10-21 01:38:35 +00:00
default :
logrus . Debugf ( "received unknown message type: %+v" , payload )
}
2024-10-21 04:17:11 +00:00
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
2024-10-21 01:38:35 +00:00
}
2024-10-21 04:17:11 +00:00
logrus . WithField ( "node_num" , nodeInfo . Num ) . Debug ( "updated info for node" )
return nil
2024-10-21 01:38:35 +00:00
}
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
}
2024-10-21 04:17:11 +00:00
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 )
}
2024-10-21 01:38:35 +00:00
switch payload . Decoded . Portnum {
case protobufs . PortNum_TEXT_MESSAGE_APP :
2024-10-21 04:44:55 +00:00
logrus . WithField ( "source" , sourceString ) . Info ( "handling incoming meshtastic -> matrix message" )
2024-10-21 04:17:11 +00:00
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 ) )
2024-10-21 01:38:35 +00:00
default :
logrus . WithField ( "type" , protobufs . PortNum_name [ int32 ( payload . Decoded . Portnum ) ] ) . Debug ( "ignoring unknown app payload" )
}
return nil
}