From 0ec2808fdde68aa7a4e4cb92f527db0fe8b68a59 Mon Sep 17 00:00:00 2001 From: maze Date: Mon, 23 Feb 2026 15:14:26 +0100 Subject: [PATCH] Initial import --- .gitea/workflows/build.yaml | 74 ++++++++++++++++++++++++ Dockerfile | 8 +++ go.mod | 36 ++++++++++++ go.sum | 110 ++++++++++++++++++++++++++++++++++++ main.go | 49 ++++++++++++++++ run_aprsis.go | 77 +++++++++++++++++++++++++ run_meshcore.go | 79 ++++++++++++++++++++++++++ 7 files changed, 433 insertions(+) create mode 100644 .gitea/workflows/build.yaml create mode 100644 Dockerfile create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 run_aprsis.go create mode 100644 run_meshcore.go diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml new file mode 100644 index 0000000..2010c4f --- /dev/null +++ b/.gitea/workflows/build.yaml @@ -0,0 +1,74 @@ +name: Test and build +on: + push: + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-go@v6 + with: + go-version-file: 'go.mod' + check-latest: false + #- name: golangci-lint + # uses: golangci/golangci-lint-action@v9 + # with: + # go-version: ${{ matrix.go }} + # version: v2.6 + + build: + name: Build + runs-on: ubuntu-latest + strategy: + matrix: + include: + - goos: linux + goarch: amd64 + goarm: "" + - goos: linux + goarch: arm + goarm: "6" + - goos: linux + goarch: arm + goarm: "7" + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-go@v6 + with: + go-version-file: 'go.mod' + check-latest: false + - name: Set target variables + run: | + echo "GOOS=${{ matrix.goos }}" >> $GITHUB_ENV + echo "GOARCH=${{ matrix.goarch }}" >> $GITHUB_ENV + if [ -n "${{ matrix.goarm }}" ]; then + echo "GOARM=${{ matrix.goarm }}" >> $GITHUB_ENV + fi + - name: Download modules + run: go mod download + - name: Make build directory + run: mkdir -p build && readlink -f build + - name: Build + run: go build -o build/hamview-receiver.${{ matrix.goarch }}${{ matrix.goarm }} . && readlink -f build/hamview-receiver.${{ matrix.goarch }}${{ matrix.goarm }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Log into Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ vars.REGISTRY }} + username: ${{ vars.DEPLOY_USER }} + password: ${{ secrets.DEPLOY_TOKEN }} + - name: Build and push receiver container + uses: docker/build-push-action@v6 + with: + push: true + tags: ham/hamview-receiver:latest + context: . + platforms: | + linux/amd64 + linux/arm/v6 + linux/arm/v7 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b882683 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM alpine:3 +ARG TARGETARCH +ARG TARGETVARIANT +COPY ./etc /etc/hamview +COPY ./build/hamview-receiver-${$TARGETARCH}${TARGETVARIANT#v} /opt/hamview/bin/hamview-receiver +WORKDIR /opt/hamview +ENTRYPOINT ["bin/hamview-receiver"] +CMD [ "protocol" ] diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..384eb1a --- /dev/null +++ b/go.mod @@ -0,0 +1,36 @@ +module git.maze.io/ham/hamview-receiver + +go 1.25.6 + +require ( + git.maze.io/go/ham v0.0.0-20260222203006-aabfa853ecb5 + git.maze.io/ham/hamview v0.0.0-20260223131148-03a2fc0e6fa7 + github.com/sirupsen/logrus v1.9.4 + github.com/urfave/cli/v3 v3.6.2 +) + +require ( + filippo.io/edwards25519 v1.1.0 // indirect + github.com/Vaniog/go-postgis v0.0.0-20240619200434-9c2eb8ed621e // indirect + github.com/cemkiy/echo-logrus v0.0.0-20200218141616-06f9cd1dae34 // indirect + github.com/cridenour/go-postgis v1.0.1 // indirect + github.com/eclipse/paho.mqtt.golang v1.5.1 // indirect + github.com/golang-jwt/jwt/v5 v5.3.1 // indirect + github.com/gorilla/websocket v1.5.3 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/labstack/echo/v4 v4.15.0 // indirect + github.com/labstack/gommon v0.4.2 // indirect + github.com/lib/pq v1.11.2 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/time v0.14.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..3e8f09f --- /dev/null +++ b/go.sum @@ -0,0 +1,110 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +git.maze.io/go/ham v0.0.0-20260222203006-aabfa853ecb5 h1:ZVdnXcXv0Hcp/gRNqHQ1zQxvpWPLf9siAjKPzEJa3JU= +git.maze.io/go/ham v0.0.0-20260222203006-aabfa853ecb5/go.mod h1:+WuiawzNBqlWgklVoodUAJc0cV+NDW6RR8Tn+AW8hsU= +git.maze.io/ham/hamview v0.0.0-20260223131148-03a2fc0e6fa7 h1:PrTCaS+wsO4LUIlXUX4mEJKNsvC8wEtCXyWLFL/8Rlw= +git.maze.io/ham/hamview v0.0.0-20260223131148-03a2fc0e6fa7/go.mod h1:0YU3u9Nlqn21Qmdl+J2RjQs7rJRWvDZXZpE2qCCe7bM= +github.com/Vaniog/go-postgis v0.0.0-20240619200434-9c2eb8ed621e h1:Ck+0lNRr62RM/LNKkkD0R1aJ2DvgELqmmuNvyyHL75E= +github.com/Vaniog/go-postgis v0.0.0-20240619200434-9c2eb8ed621e/go.mod h1:o3MIxN5drWoGBTtBGtLqFZlr7RjfdQKnfwYXoUU77vU= +github.com/cemkiy/echo-logrus v0.0.0-20200218141616-06f9cd1dae34 h1:cGxEwqDl+PiqPtJpQNoiJIXcrVEkkSMuMQtb+PPAHL4= +github.com/cemkiy/echo-logrus v0.0.0-20200218141616-06f9cd1dae34/go.mod h1:kvJeauv7Kc2LibOGGom8nEWyjjaN7LIsCdbkrFfU9rE= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cridenour/go-postgis v1.0.1 h1:H8LkcOgoASyxDMej3xzF1OcXtskvsDfcL/gxcb8r0ow= +github.com/cridenour/go-postgis v1.0.1/go.mod h1:KEQNef9ssi7Q0nQFBo5b4l6hjVw7EoFQ5GD8rBYD8kU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/eclipse/paho.mqtt.golang v1.5.1 h1:/VSOv3oDLlpqR2Epjn1Q7b2bSTplJIeV2ISgCl2W7nE= +github.com/eclipse/paho.mqtt.golang v1.5.1/go.mod h1:1/yJCneuyOoCOzKSsOTUc0AJfpsItBGWvYpBLimhArU= +github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY= +github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s= +github.com/labstack/echo/v4 v4.1.13/go.mod h1:3WZNypykZ3tnqpF2Qb4fPg27XDunFqgP3HGDmCMgv7U= +github.com/labstack/echo/v4 v4.15.0 h1:hoRTKWcnR5STXZFe9BmYun9AMTNeSbjHi2vtDuADJ24= +github.com/labstack/echo/v4 v4.15.0/go.mod h1:xmw1clThob0BSVRX1CRQkGQ/vjwcpOMjQZSZa9fKA/c= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= +github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= +github.com/lib/pq v1.11.2 h1:x6gxUeu39V0BHZiugWe8LXZYZ+Utk7hSJGThs8sdzfs= +github.com/lib/pq v1.11.2/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= +github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 h1:UyzmZLoiDWMRywV4DUYb9Fbt8uiOSooupjTq10vpvnU= +github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/urfave/cli/v3 v3.6.2 h1:lQuqiPrZ1cIz8hz+HcrG0TNZFxU70dPZ3Yl+pSrH9A8= +github.com/urfave/cli/v3 v3.6.2/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go new file mode 100644 index 0000000..f1ce96e --- /dev/null +++ b/main.go @@ -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/internal/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") +} diff --git a/run_aprsis.go b/run_aprsis.go new file mode 100644 index 0000000..2a172c3 --- /dev/null +++ b/run_aprsis.go @@ -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/internal/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 client.Close() + + broker, err := hamview.NewBroker(config) + if err != nil { + logger.Errorf("receiver: can't setup to broker: %v", err) + return + } + defer 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.Info("receiver: stopped receiving packets from station: %s", callsign) +} diff --git a/run_meshcore.go b/run_meshcore.go new file mode 100644 index 0000000..d54fa99 --- /dev/null +++ b/run_meshcore.go @@ -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/internal/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 broker.Close() + + receiver, err := hamview.NewMeshCoreReceiver(&config.Receiver) + if err != nil { + return err + } + defer 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() +}