59 lines
1.3 KiB
Go
59 lines
1.3 KiB
Go
package aprs
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
ErrPayloadMarker = errors.New("aprs: can't find payload marker")
|
|
ErrDestinationMarker = errors.New("aprs: can't find destination marker")
|
|
ErrPathLength = errors.New("aprs: invalid path length")
|
|
)
|
|
|
|
// Frame represents a single APRS frame.
|
|
type Frame struct {
|
|
Source Address `json:"source"`
|
|
Destination Address `json:"destination"`
|
|
Path Path `json:"path"`
|
|
Raw Raw `json:"raw"`
|
|
Data Data `json:"data,omitempty"`
|
|
}
|
|
|
|
func Parse(s string) (*Frame, error) {
|
|
i := strings.IndexByte(s, ':')
|
|
if i == -1 {
|
|
return nil, ErrPayloadMarker
|
|
}
|
|
|
|
var (
|
|
route = s[:i]
|
|
frame = &Frame{Raw: Raw(s[i+1:])}
|
|
)
|
|
if i = strings.IndexByte(route, '>'); i == -1 {
|
|
return nil, ErrDestinationMarker
|
|
}
|
|
frame.Source, route = ParseAddress(route[:i]), route[i+1:]
|
|
|
|
path := strings.Split(route, ",")
|
|
if len(path) == 0 || len(path) > 9 {
|
|
return nil, ErrPathLength
|
|
}
|
|
frame.Destination = ParseAddress(path[0])
|
|
for i, l := 1, len(path); i < l; i++ {
|
|
addr := ParseAddress(path[i])
|
|
frame.Path = append(frame.Path, addr)
|
|
}
|
|
|
|
var err error
|
|
for _, d := range decoders {
|
|
if d.CanDecode(frame) {
|
|
if frame.Data, err = d.Decode(frame); err == nil {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
return frame, nil
|
|
}
|