kopia lustrzana https://github.com/cyoung/stratux
Making uatparse a bit more portable.
rodzic
bd99560a3d
commit
244fa8a544
|
@ -54,12 +54,12 @@ Winds Aloft 12 hours 10 minutes
|
|||
func append_metars(rawUplinkMessage string, curMetars []string) []string {
|
||||
ret := curMetars
|
||||
|
||||
buf, err := uatparse.ParseInput(rawUplinkMessage)
|
||||
uatMsg, err := uatparse.New(rawUplinkMessage)
|
||||
if err != nil {
|
||||
return ret
|
||||
}
|
||||
//fmt.Printf("*************************\n")
|
||||
metars := uatparse.DecodeUplink(buf)
|
||||
metars, _ := uatMsg.GetTextReports()
|
||||
for _, v := range metars {
|
||||
//fmt.Printf("EE: %s\n", v)
|
||||
vSplit := strings.Split(v, " ")
|
||||
|
|
|
@ -26,6 +26,26 @@ const (
|
|||
dlac_alpha = "\x03ABCDEFGHIJKLMNOPQRSTUVWXYZ\x1A\t\x1E\n| !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||
)
|
||||
|
||||
type UATFrame struct {
|
||||
raw_data []byte
|
||||
|
||||
frame_length uint32
|
||||
frame_type uint32
|
||||
|
||||
product_id uint32
|
||||
// Text data, if applicable.
|
||||
text_data []string
|
||||
}
|
||||
|
||||
type UATMsg struct {
|
||||
msg []byte
|
||||
decoded bool
|
||||
// Station location for uplink frames, aircraft position for downlink frames.
|
||||
lat float64
|
||||
lon float64
|
||||
frames []*UATFrame
|
||||
}
|
||||
|
||||
func dlac_decode(data []byte, data_len uint32) string {
|
||||
step := 0
|
||||
tab := false
|
||||
|
@ -59,34 +79,33 @@ func dlac_decode(data []byte, data_len uint32) string {
|
|||
return ret
|
||||
}
|
||||
|
||||
func decodeInfoFrame(frame []byte, frame_start int, frame_len uint32, frame_type uint32) []string {
|
||||
data := frame[frame_start : frame_start+int(frame_len)]
|
||||
func (f *UATFrame) decodeInfoFrame() {
|
||||
|
||||
if frame_type != 0 {
|
||||
return []string{} // Not FIS-B.
|
||||
if f.frame_type != 0 {
|
||||
return // Not FIS-B.
|
||||
}
|
||||
if frame_len < 4 {
|
||||
return []string{} // Too short for FIS-B.
|
||||
if f.frame_length < 4 {
|
||||
return // Too short for FIS-B.
|
||||
}
|
||||
|
||||
t_opt := ((uint32(data[1]) & 0x01) << 1) | (uint32(data[2]) >> 7)
|
||||
product_id := ((uint32(data[0]) & 0x1f) << 6) | (uint32(data[1]) >> 2)
|
||||
t_opt := ((uint32(f.raw_data[1]) & 0x01) << 1) | (uint32(f.raw_data[2]) >> 7)
|
||||
f.product_id = ((uint32(f.raw_data[0]) & 0x1f) << 6) | (uint32(f.raw_data[1]) >> 2)
|
||||
|
||||
if product_id != 413 { // FIXME.
|
||||
return []string{}
|
||||
if f.product_id != 413 { // FIXME.
|
||||
return
|
||||
}
|
||||
|
||||
if t_opt != 0 { //FIXME.
|
||||
// fmt.Printf("don't know time format %d\n", t_opt)
|
||||
// panic("time format")
|
||||
return []string{}
|
||||
return
|
||||
}
|
||||
|
||||
/* fisb_hours := (uint32(data[2]) & 0x7c) >> 2
|
||||
fisb_minutes := ((uint32(data[2]) & 0x03) << 4) | (uint32(data[3]) >> 4)
|
||||
*/
|
||||
fisb_length := frame_len - 4
|
||||
fisb_data := data[4:]
|
||||
fisb_length := f.frame_length - 4
|
||||
fisb_data := f.raw_data[4:]
|
||||
|
||||
p := dlac_decode(fisb_data, fisb_length)
|
||||
ret := make([]string, 0)
|
||||
|
@ -102,13 +121,16 @@ func decodeInfoFrame(frame []byte, frame_start int, frame_len uint32, frame_type
|
|||
ret = append(ret, p[:pos])
|
||||
p = p[pos+1:]
|
||||
}
|
||||
return ret
|
||||
|
||||
f.text_data = ret
|
||||
|
||||
// logger.Printf("pos=%d,len=%d,t_opt=%d,product_id=%d, time=%d:%d\n", frame_start, frame_len, t_opt, product_id, fisb_hours, fisb_minutes)
|
||||
}
|
||||
|
||||
func DecodeUplink(frame []byte) []string {
|
||||
func (u *UATMsg) DecodeUplink() error {
|
||||
// position_valid := (uint32(frame[5]) & 0x01) != 0
|
||||
frame := u.msg
|
||||
|
||||
raw_lat := (uint32(frame[0]) << 15) | (uint32(frame[1]) << 7) | (uint32(frame[2]) >> 1)
|
||||
|
||||
raw_lon := ((uint32(frame[2]) & 0x01) << 23) | (uint32(frame[3]) << 15) | (uint32(frame[4]) << 7) | (uint32(frame[5]) >> 1)
|
||||
|
@ -122,6 +144,9 @@ func DecodeUplink(frame []byte) []string {
|
|||
lon = lon - 360
|
||||
}
|
||||
|
||||
u.lat = lat
|
||||
u.lon = lon
|
||||
|
||||
// utc_coupled := (uint32(frame[6]) & 0x80) != 0
|
||||
app_data_valid := (uint32(frame[6]) & 0x20) != 0
|
||||
// slot_id := uint32(frame[6]) & 0x1f
|
||||
|
@ -129,9 +154,8 @@ func DecodeUplink(frame []byte) []string {
|
|||
|
||||
// logger.Printf("position_valid=%t, %.04f, %.04f, %t, %t, %d, %d\n", position_valid, lat, lon, utc_coupled, app_data_valid, slot_id, tisb_site_id)
|
||||
|
||||
ret := make([]string, 0)
|
||||
if !app_data_valid {
|
||||
return ret // Not sure when this even happens?
|
||||
return nil // Not sure when this even happens?
|
||||
}
|
||||
|
||||
app_data := frame[8:432]
|
||||
|
@ -149,22 +173,58 @@ func DecodeUplink(frame []byte) []string {
|
|||
break // No more frames.
|
||||
}
|
||||
pos = pos + 2
|
||||
infoFrameText := decodeInfoFrame(app_data, pos, frame_length, frame_type)
|
||||
if len(infoFrameText) > 0 {
|
||||
for _, v := range infoFrameText {
|
||||
ret = append(ret, v)
|
||||
}
|
||||
}
|
||||
|
||||
data = data[2:frame_length+2]
|
||||
|
||||
thisFrame := new(UATFrame)
|
||||
thisFrame.raw_data = data
|
||||
thisFrame.frame_length = frame_length
|
||||
thisFrame.frame_type = frame_type
|
||||
|
||||
thisFrame.decodeInfoFrame()
|
||||
|
||||
// Save the decoded frame.
|
||||
u.frames = append(u.frames, thisFrame)
|
||||
|
||||
pos = pos + int(frame_length)
|
||||
}
|
||||
return ret
|
||||
|
||||
u.decoded = true
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Aggregate all of the text rates across the frames in the message and return as an array.
|
||||
*/
|
||||
|
||||
func (u *UATMsg) GetTextReports() ([]string, error) {
|
||||
ret := make([]string, 0)
|
||||
if !u.decoded {
|
||||
err := u.DecodeUplink()
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, f := range u.frames {
|
||||
for _, m := range f.text_data {
|
||||
if len(m) > 0 {
|
||||
ret = append(ret, m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
/*
|
||||
Parse out the message from the "dump978" output format.
|
||||
*/
|
||||
|
||||
func ParseInput(buf string) ([]byte, error) {
|
||||
func New(buf string) (*UATMsg, error) {
|
||||
ret := new(UATMsg)
|
||||
|
||||
buf = strings.Trim(buf, "\r\n") // Remove newlines.
|
||||
x := strings.Split(buf, ";") // We want to discard everything before the first ';'.
|
||||
|
||||
|
@ -172,11 +232,11 @@ func ParseInput(buf string) ([]byte, error) {
|
|||
|
||||
// Only want "long" uplink messages.
|
||||
if (len(s) - 1)%2 != 0 || (len(s)-1)/2 != UPLINK_FRAME_DATA_BYTES {
|
||||
return []byte{}, errors.New(fmt.Sprintf("parseInput: short read (%d).", len(s)))
|
||||
return ret, errors.New(fmt.Sprintf("New UATMsg: short read (%d).", len(s)))
|
||||
}
|
||||
|
||||
if s[0] != '+' { // Only want + ("Uplink") messages currently. - (Downlink) or messages that start with other are discarded.
|
||||
return []byte{}, errors.New("parseInput: expecting uplink frames.")
|
||||
return ret, errors.New("New UATMsg: expecting uplink frames.")
|
||||
}
|
||||
|
||||
s = s[1:]
|
||||
|
@ -184,6 +244,7 @@ func ParseInput(buf string) ([]byte, error) {
|
|||
// Convert the hex string into a byte array.
|
||||
frame := make([]byte, UPLINK_FRAME_DATA_BYTES)
|
||||
hex.Decode(frame, []byte(s))
|
||||
ret.msg = frame
|
||||
|
||||
return frame, nil
|
||||
return ret, nil
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue