Re-added hamview-receiver
Some checks failed
Test and build / Build receiver (push) Failing after 45s
Test and build / test (push) Successful in 59s
Test and build / Build collector (push) Failing after 1m16s

This commit is contained in:
2026-02-23 21:15:48 +01:00
parent d8715eaaaa
commit 227477d17f
11 changed files with 333 additions and 36 deletions

View File

@@ -0,0 +1,12 @@
FROM alpine:3
RUN apk add --no-cache dumb-init=1.2.5-r3
WORKDIR /app
ARG TARGETARCH
ARG TARGETVARIANT
COPY ./etc /app/config
COPY ./build/hamview-receiver-${TARGETARCH}${TARGETVARIANT#v} /app/hamview-receiver
COPY ./entrypoint.sh /entrypoint.sh
ENTRYPOINT ["dumb-init", "/entrypoint.sh"]

View File

@@ -0,0 +1,17 @@
#!/bin/sh
run() {
case "${PROTOCOL}" in
"") exec "/app/hamview-receiver" help ;;
*) exec "/app/hamview-receiver" --config "/app/config/hamview-${PROTOCOL}.yaml" "${PROTOCOL}" ;;
esac
}
case "$@" in
"")
run
;;
*)
exec "/bin/sh" -c "$@"
;;
esac

View File

@@ -0,0 +1,49 @@
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v3"
"git.maze.io/ham/hamview/cmd"
)
var logger *logrus.Logger
func main() {
cmd := &cli.Command{
Name: "hamview-receiver",
Usage: "Receiver for HAM radio protocols",
Action: func(context.Context, *cli.Command) error {
fmt.Println("boom! I say!")
return nil
},
Flags: cmd.AllFlags("hamview-receiver.yaml"),
Commands: []*cli.Command{
{
Name: "aprsis",
Usage: "Start an APRS-IS proxy",
Before: cmd.ConfigureLogging(&logger),
Action: runAPRSIS,
},
{
Name: "meshcore",
Usage: "Start a MeshCore receiver",
Before: cmd.ConfigureLogging(&logger),
Action: runMeshCore,
},
},
}
if err := cmd.Run(context.Background(), os.Args); err != nil {
log.Fatal(err)
}
}
func waitForInterrupt() error {
return cmd.WaitForInterrupt(logger, "receiver")
}

View File

@@ -0,0 +1,77 @@
package main
import (
"context"
"github.com/urfave/cli/v3"
"git.maze.io/go/ham/protocol/aprs/aprsis"
"git.maze.io/ham/hamview"
"git.maze.io/ham/hamview/cmd"
)
type aprsisConfig struct {
Broker hamview.BrokerConfig `yaml:"broker"`
Receiver hamview.APRSISConfig `yaml:"receiver"`
Include []string `yaml:"include"`
}
func (config *aprsisConfig) Includes() []string {
includes := config.Include
config.Include = nil
return includes
}
func runAPRSIS(ctx context.Context, command *cli.Command) error {
var config = aprsisConfig{
Receiver: hamview.APRSISConfig{
Listen: hamview.DefaultAPRSISListen,
Server: hamview.DefaultAPRSISServer,
},
}
if err := cmd.Load(logger, command.String(cmd.FlagConfig), &config); err != nil {
return err
}
logger.Infof("receiver: starting APRS-IS proxy on tcp://%s to tcp://%s",
config.Receiver.Listen,
config.Receiver.Server)
proxy, err := aprsis.NewProxy(config.Receiver.Listen, config.Receiver.Server)
if err != nil {
return err
}
proxy.OnClient = func(callsign string, client *aprsis.ProxyClient) {
go receiveAPRSIS(&config.Broker, callsign, client)
}
return waitForInterrupt()
}
func receiveAPRSIS(config *hamview.BrokerConfig, callsign string, client *aprsis.ProxyClient) {
defer func() { _ = client.Close() }()
broker, err := hamview.NewBroker(config)
if err != nil {
logger.Errorf("receiver: can't setup to broker: %v", err)
return
}
defer func() { _ = broker.Close() }()
info := client.Info() // TODO: enrich info from config?
if err = broker.StartRadio("aprs", info); err != nil {
logger.Fatalf("receiver: can't start broker: %v", err)
return
}
logger.Infof("receiver: start receiving packets from station: %s", callsign)
for packet := range client.RawPackets() {
logger.Debugf("aprs packet: %#+v", packet)
if err := broker.PublishPacket("aprs/packet", packet); err != nil {
logger.Error(err)
}
}
logger.Infof("receiver: stopped receiving packets from station: %s", callsign)
}

View File

@@ -0,0 +1,79 @@
package main
import (
"context"
"github.com/urfave/cli/v3"
"git.maze.io/go/ham/protocol"
"git.maze.io/go/ham/protocol/meshcore"
"git.maze.io/ham/hamview"
"git.maze.io/ham/hamview/cmd"
)
type meshCoreConfig struct {
Broker hamview.BrokerConfig `yaml:"broker"`
Receiver hamview.MeshCoreConfig `yaml:"receiver"`
Include []string `yaml:"include"`
}
func (config *meshCoreConfig) Includes() []string {
includes := config.Include
config.Include = nil
return includes
}
func runMeshCore(ctx context.Context, command *cli.Command) error {
var config meshCoreConfig
if err := cmd.Load(logger, command.String(cmd.FlagConfig), &config); err != nil {
return err
}
broker, err := hamview.NewBroker(&config.Broker)
if err != nil {
return err
}
defer func() { _ = broker.Close() }()
receiver, err := hamview.NewMeshCoreReceiver(&config.Receiver)
if err != nil {
return err
}
defer func() { _ = receiver.Close() }()
info := receiver.Info() // TODO: enrich info from config?
if err = broker.StartRadio(protocol.MeshCore, info); err != nil {
logger.Fatalf("receiver: can't start broker: %v", err)
return err
}
// Trace scheduler
//go receiver.RunTraces()
// Packet decoder
go func() {
logger.Info("receiver: start receiving packets")
for packet := range receiver.RawPackets() {
if len(packet.Raw) >= 1 {
var (
header = packet.Raw[0]
version = (header >> 6) & 0x03
routeType = meshcore.RouteType(header & 0x03)
payloadType = meshcore.PayloadType((header >> 2) & 0x0F)
)
logger.Debugf("meshcore packet: %d %s %s: %d bytes",
version,
routeType,
payloadType,
len(packet.Raw))
}
if err = broker.PublishPacket("meshcore/packet", packet); err != nil {
logger.Errorf("receiver: failed to publish packet: %v", err)
}
}
logger.Warn("receiver: closing")
}()
return waitForInterrupt()
}