protocol/aprs: refactored
This commit is contained in:
99
protocol/aprs/message.go
Normal file
99
protocol/aprs/message.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package aprs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
ID int `json::"id"`
|
||||
IsAcknowledge bool `json:"is_ack"`
|
||||
IsRejection bool `json:"is_rejection"`
|
||||
IsBulletin bool `json:"is_bulletin"`
|
||||
Recipient string `json:"recipient"`
|
||||
AnnoucementID byte `json:"announcement_id,omitempty"`
|
||||
Group string `json:"group,omitempty"`
|
||||
Severity string `json:"severity,omitempty"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
func (msg *Message) String() string {
|
||||
return fmt.Sprintf("%s: %q", msg.Recipient, msg.Text)
|
||||
}
|
||||
|
||||
type messageDecoder struct{}
|
||||
|
||||
func (messageDecoder) CanDecode(frame *Frame) bool {
|
||||
var (
|
||||
maybeMessage = len(frame.Raw) >= 11 && frame.Raw[10] == ':'
|
||||
maybeBulletin = len(frame.Raw) >= 10 && frame.Raw[9] == ':'
|
||||
)
|
||||
return frame.Raw.Type() == ':' && (maybeMessage || maybeBulletin)
|
||||
}
|
||||
|
||||
func (messageDecoder) Decode(frame *Frame) (data Data, err error) {
|
||||
var (
|
||||
msg = new(Message)
|
||||
text string
|
||||
size = len(text)
|
||||
)
|
||||
if len(frame.Raw) >= 10 && frame.Raw[9] == ':' {
|
||||
msg.Recipient, text = strings.TrimSpace(string(frame.Raw[1:9])), string(frame.Raw[9:])
|
||||
} else {
|
||||
msg.Recipient, text = strings.TrimSpace(string(frame.Raw[1:10])), string(frame.Raw[10:])
|
||||
}
|
||||
|
||||
switch {
|
||||
case strings.HasPrefix(msg.Recipient, "BLN"):
|
||||
// Bulletin
|
||||
kind := msg.Recipient[3:]
|
||||
if id, err := strconv.Atoi(kind); err == nil {
|
||||
// General bulletin
|
||||
msg.IsBulletin = true
|
||||
msg.ID = id
|
||||
} else if len(kind) >= 2 && isDigit(kind[0]) {
|
||||
// Group Bulletin Format
|
||||
msg.IsBulletin = true
|
||||
msg.ID = int(kind[0] - '0')
|
||||
msg.Group = kind[1:]
|
||||
} else if len(kind) == 1 {
|
||||
// Announcement
|
||||
msg.IsBulletin = true
|
||||
msg.AnnoucementID = kind[0]
|
||||
}
|
||||
|
||||
case strings.HasPrefix(msg.Recipient, "NWS-"):
|
||||
// National Weather Service Bulletins
|
||||
msg.IsBulletin = true
|
||||
msg.Severity = msg.Recipient[4:]
|
||||
|
||||
default:
|
||||
if i := strings.LastIndexByte(text, '{'); i != -1 && i > (size-6) {
|
||||
// Plain message ID: {XXXXX (where there are 1-5 X)
|
||||
msg.ID, _ = strconv.Atoi(text[i+1:])
|
||||
text = text[:i]
|
||||
}
|
||||
|
||||
if i := strings.LastIndex(text, ":ack"); i != -1 && i > (size-9) {
|
||||
// Message acknowledgement: :ackXXXXX (where there are 1-5 X)
|
||||
msg.IsAcknowledge = true
|
||||
msg.ID, _ = strconv.Atoi(text[i+4:])
|
||||
text = text[:i]
|
||||
}
|
||||
|
||||
if i := strings.LastIndex(text, ":rej"); i != -1 && i > (size-9) {
|
||||
// Message acknowledgement: :rejXXXXX (where there are 1-5 X)
|
||||
msg.IsRejection = true
|
||||
msg.ID, _ = strconv.Atoi(text[i+4:])
|
||||
text = text[:i]
|
||||
}
|
||||
}
|
||||
|
||||
if len(text) > 0 && text[0] == ':' {
|
||||
text = text[1:]
|
||||
}
|
||||
|
||||
msg.Text = text
|
||||
return msg, nil
|
||||
}
|
||||
Reference in New Issue
Block a user