93 lines
1.7 KiB
Go
93 lines
1.7 KiB
Go
package aprs
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
"git.maze.io/go/ham/util/maidenhead"
|
|
)
|
|
|
|
type Status struct {
|
|
Time time.Time
|
|
Latitude float64
|
|
Longitude float64
|
|
BeamHeading int
|
|
ERP int
|
|
Symbol string
|
|
Text string
|
|
}
|
|
|
|
func (s Status) String() string {
|
|
return s.Text
|
|
}
|
|
|
|
type statusReportDecoder struct{}
|
|
|
|
func (statusReportDecoder) CanDecode(frame Frame) bool {
|
|
return frame.Raw.Type() == '>'
|
|
}
|
|
|
|
func (statusReportDecoder) Decode(frame Frame) (data Data, err error) {
|
|
var (
|
|
text = string(frame.Raw[1:])
|
|
status = new(Status)
|
|
)
|
|
if hasTimestamp(text) {
|
|
if status.Time, text, err = parseTimestamp(text); err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
if len(text) > 3 && text[len(text)-3] == '^' {
|
|
var (
|
|
h = text[len(text)-2]
|
|
p = text[len(text)-1]
|
|
)
|
|
if h >= '0' && h <= '9' {
|
|
status.BeamHeading = int(h-'0') * 10
|
|
} else if h >= 'A' && h <= 'Z' {
|
|
status.BeamHeading = 100 + int(h-'A')*10
|
|
}
|
|
if p >= '0' && p <= 'Z' {
|
|
status.ERP = int(p-'0') * int(p-'0') * 10
|
|
}
|
|
text = text[:len(text)-3]
|
|
}
|
|
|
|
here := text
|
|
if i := strings.IndexByte(here, ' '); i != -1 {
|
|
here = here[:i]
|
|
}
|
|
switch len(here) {
|
|
case 6:
|
|
var point maidenhead.Point
|
|
if point, err = maidenhead.ParseLocator(here[:4]); err != nil {
|
|
return
|
|
}
|
|
status.Latitude = point.Latitude
|
|
status.Longitude = point.Longitude
|
|
status.Symbol = here[4:]
|
|
if len(text) > 6 {
|
|
text = text[7:]
|
|
} else {
|
|
text = text[6:]
|
|
}
|
|
case 8:
|
|
var point maidenhead.Point
|
|
if point, err = maidenhead.ParseLocator(here[:6]); err != nil {
|
|
return
|
|
}
|
|
status.Latitude = point.Latitude
|
|
status.Longitude = point.Longitude
|
|
status.Symbol = here[6:]
|
|
if len(text) > 8 {
|
|
text = text[9:]
|
|
} else {
|
|
text = text[8:]
|
|
}
|
|
}
|
|
|
|
status.Text = text
|
|
return status, nil
|
|
}
|