aprs.go
· 3.7 KiB · Go
Surowy
package main
import (
"bufio"
"fmt"
"log"
"net"
"strings"
"time"
)
const server = "euro.aprs2.net"
const port = 14580
const softwareName = "goaprs"
const softwareVersion = "0.1"
const callsign = "PU2NVX"
const passcode = "123456"
const notifyMessage = "HUEBR"
const SendInterval = time.Second * 60 * 5
const ReconnectInterval = time.Minute * 30
var myCoordinate = []float32{-23.640000,-46.650000}
var lastCoordinateSent time.Time
var loggedIn = false
func Degrees2DMS(val float32) (deg int, min float32, n string) {
n = "+"
if val < 0 {
val = -val
n = "-"
}
deg = int(val)
val -= float32(deg)
val *= 60
min = val
return
}
func buildMessage(callsign, passcode, cmd string) string {
return fmt.Sprintf("user %s pass %s vers %s %s %s", callsign, passcode, softwareName, softwareVersion, cmd)
}
func parseAPRS(msg string, conn net.Conn) {
log.Printf("<- APRS: %s\n", msg)
}
func parseServer(msg string, conn net.Conn) {
log.Printf("<- SERVER: %s\n", msg)
if strings.Index(msg, "verified") > -1 {
log.Printf("-- Logged in as %s\n", callsign)
sendPosition(conn)
lastCoordinateSent = time.Now()
loggedIn = true
}
}
func parseMessage(msg string, conn net.Conn) {
if string(msg[0]) == "#" {
// Server Message
parseServer(msg[2:], conn)
return
}
parseAPRS(msg, conn)
}
func formatPosition() string {
lat := myCoordinate[0]
lon := myCoordinate[1]
latDeg, latMin, latV := Degrees2DMS(lat)
lonDeg, lonMin, lonV := Degrees2DMS(lon)
if latV == "-" {
latV = "S"
} else {
latV = "N"
}
if lonV == "-" {
lonV = "W"
} else {
lonV = "E"
}
return fmt.Sprintf("%02d%02.2f%s/%03d%02.2f%s-000/000/A=000000", latDeg, latMin, latV, lonDeg, lonMin, lonV)
}
func sendPosition(conn net.Conn) {
log.Println("-- Sending Position")
sendMessage(conn, buildMessage(callsign, passcode, "")) // First Line
sendMessage(conn, fmt.Sprintf("%s>APDR15,TCPIP*:=%s %s", callsign, formatPosition(), notifyMessage))
}
func sendMessage(conn net.Conn, msg string) {
log.Printf("-> %s\n" ,msg)
_, err := conn.Write([]byte(msg + "\n"))
if err != nil {
panic(err)
}
}
func connect() (net.Conn, *bufio.Reader) {
log.Printf("-- Connecting to %s:%d\n", server, port)
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", server, port))
if err != nil {
panic(err)
}
reader := bufio.NewReader(conn)
time.Sleep(1 * time.Second)
line, _, err := reader.ReadLine()
if err != nil {
panic(err)
}
log.Printf("<- %s\n", string(line))
log.Println("-- Connected. Sending Login")
msg := buildMessage(callsign, passcode, fmt.Sprintf("filter r/%f/%f/%d", myCoordinate[0], myCoordinate[1], 50))
sendMessage(conn, msg)
if err != nil {
panic(err)
}
return conn, reader
}
func main() {
log.Printf("-- Restart Time: %s\n", ReconnectInterval)
log.Printf("-- Send Interval: %s\n", SendInterval)
connectTime := time.Now()
conn, reader := connect()
log.Println("-- Receiving messages")
for {
line, _, err := reader.ReadLine()
if err != nil {
panic(err)
}
parseMessage(string(line), conn)
if time.Since(lastCoordinateSent) > SendInterval && loggedIn {
sendPosition(conn)
lastCoordinateSent = time.Now()
}
if time.Since(connectTime) > ReconnectInterval {
log.Println("-- Reconnect time exceeded. Reconnecting")
_ = conn.Close()
conn, reader = connect()
connectTime = time.Now()
}
}
}
| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "bufio" |
| 5 | "fmt" |
| 6 | "log" |
| 7 | "net" |
| 8 | "strings" |
| 9 | "time" |
| 10 | ) |
| 11 | |
| 12 | const server = "euro.aprs2.net" |
| 13 | const port = 14580 |
| 14 | |
| 15 | const softwareName = "goaprs" |
| 16 | const softwareVersion = "0.1" |
| 17 | |
| 18 | const callsign = "PU2NVX" |
| 19 | const passcode = "123456" |
| 20 | const notifyMessage = "HUEBR" |
| 21 | |
| 22 | const SendInterval = time.Second * 60 * 5 |
| 23 | const ReconnectInterval = time.Minute * 30 |
| 24 | |
| 25 | var myCoordinate = []float32{-23.640000,-46.650000} |
| 26 | |
| 27 | var lastCoordinateSent time.Time |
| 28 | |
| 29 | var loggedIn = false |
| 30 | |
| 31 | func Degrees2DMS(val float32) (deg int, min float32, n string) { |
| 32 | n = "+" |
| 33 | if val < 0 { |
| 34 | val = -val |
| 35 | n = "-" |
| 36 | } |
| 37 | |
| 38 | deg = int(val) |
| 39 | val -= float32(deg) |
| 40 | val *= 60 |
| 41 | min = val |
| 42 | |
| 43 | return |
| 44 | } |
| 45 | |
| 46 | func buildMessage(callsign, passcode, cmd string) string { |
| 47 | return fmt.Sprintf("user %s pass %s vers %s %s %s", callsign, passcode, softwareName, softwareVersion, cmd) |
| 48 | } |
| 49 | |
| 50 | func parseAPRS(msg string, conn net.Conn) { |
| 51 | log.Printf("<- APRS: %s\n", msg) |
| 52 | } |
| 53 | |
| 54 | func parseServer(msg string, conn net.Conn) { |
| 55 | log.Printf("<- SERVER: %s\n", msg) |
| 56 | if strings.Index(msg, "verified") > -1 { |
| 57 | log.Printf("-- Logged in as %s\n", callsign) |
| 58 | |
| 59 | sendPosition(conn) |
| 60 | lastCoordinateSent = time.Now() |
| 61 | |
| 62 | loggedIn = true |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | func parseMessage(msg string, conn net.Conn) { |
| 67 | if string(msg[0]) == "#" { |
| 68 | // Server Message |
| 69 | parseServer(msg[2:], conn) |
| 70 | return |
| 71 | } |
| 72 | |
| 73 | parseAPRS(msg, conn) |
| 74 | } |
| 75 | |
| 76 | func formatPosition() string { |
| 77 | lat := myCoordinate[0] |
| 78 | lon := myCoordinate[1] |
| 79 | |
| 80 | latDeg, latMin, latV := Degrees2DMS(lat) |
| 81 | lonDeg, lonMin, lonV := Degrees2DMS(lon) |
| 82 | |
| 83 | if latV == "-" { |
| 84 | latV = "S" |
| 85 | } else { |
| 86 | latV = "N" |
| 87 | } |
| 88 | if lonV == "-" { |
| 89 | lonV = "W" |
| 90 | } else { |
| 91 | lonV = "E" |
| 92 | } |
| 93 | |
| 94 | return fmt.Sprintf("%02d%02.2f%s/%03d%02.2f%s-000/000/A=000000", latDeg, latMin, latV, lonDeg, lonMin, lonV) |
| 95 | } |
| 96 | |
| 97 | func sendPosition(conn net.Conn) { |
| 98 | log.Println("-- Sending Position") |
| 99 | sendMessage(conn, buildMessage(callsign, passcode, "")) // First Line |
| 100 | sendMessage(conn, fmt.Sprintf("%s>APDR15,TCPIP*:=%s %s", callsign, formatPosition(), notifyMessage)) |
| 101 | } |
| 102 | |
| 103 | func sendMessage(conn net.Conn, msg string) { |
| 104 | log.Printf("-> %s\n" ,msg) |
| 105 | _, err := conn.Write([]byte(msg + "\n")) |
| 106 | if err != nil { |
| 107 | panic(err) |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | func connect() (net.Conn, *bufio.Reader) { |
| 112 | log.Printf("-- Connecting to %s:%d\n", server, port) |
| 113 | conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", server, port)) |
| 114 | |
| 115 | if err != nil { |
| 116 | panic(err) |
| 117 | } |
| 118 | |
| 119 | reader := bufio.NewReader(conn) |
| 120 | time.Sleep(1 * time.Second) |
| 121 | line, _, err := reader.ReadLine() |
| 122 | |
| 123 | if err != nil { |
| 124 | panic(err) |
| 125 | } |
| 126 | log.Printf("<- %s\n", string(line)) |
| 127 | |
| 128 | log.Println("-- Connected. Sending Login") |
| 129 | |
| 130 | msg := buildMessage(callsign, passcode, fmt.Sprintf("filter r/%f/%f/%d", myCoordinate[0], myCoordinate[1], 50)) |
| 131 | sendMessage(conn, msg) |
| 132 | |
| 133 | if err != nil { |
| 134 | panic(err) |
| 135 | } |
| 136 | |
| 137 | return conn, reader |
| 138 | } |
| 139 | |
| 140 | func main() { |
| 141 | log.Printf("-- Restart Time: %s\n", ReconnectInterval) |
| 142 | log.Printf("-- Send Interval: %s\n", SendInterval) |
| 143 | connectTime := time.Now() |
| 144 | conn, reader := connect() |
| 145 | |
| 146 | log.Println("-- Receiving messages") |
| 147 | for { |
| 148 | line, _, err := reader.ReadLine() |
| 149 | if err != nil { |
| 150 | panic(err) |
| 151 | } |
| 152 | parseMessage(string(line), conn) |
| 153 | |
| 154 | if time.Since(lastCoordinateSent) > SendInterval && loggedIn { |
| 155 | sendPosition(conn) |
| 156 | lastCoordinateSent = time.Now() |
| 157 | } |
| 158 | |
| 159 | if time.Since(connectTime) > ReconnectInterval { |
| 160 | log.Println("-- Reconnect time exceeded. Reconnecting") |
| 161 | _ = conn.Close() |
| 162 | conn, reader = connect() |
| 163 | connectTime = time.Now() |
| 164 | } |
| 165 | } |
| 166 | } |