Skip to content

Commit

Permalink
Bug: use a copy of the data rather than the address of the loop var (…
Browse files Browse the repository at this point in the history
…which is always the same)

A few yoda to not yoda changes
increasing CPR max time diff to 10s from 1.5s
  • Loading branch information
bluntelk committed Nov 6, 2023
1 parent f25becd commit 8f12b07
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 74 deletions.
122 changes: 57 additions & 65 deletions lib/producer/beast.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const tokenBufLen = 50
func (p *Producer) beastScanner(scan *bufio.Scanner) error {
lastTimeStamp := time.Duration(0)
for scan.Scan() {
msg := scan.Bytes()
msg := bytes.Clone(scan.Bytes())
frame, err := beast.NewFrame(msg, false)
if nil != err {
continue
Expand All @@ -39,77 +39,69 @@ func (p *Producer) beastScanner(scan *bufio.Scanner) error {
}

// ScanBeast is a splitter for BEAST format messages
func ScanBeast() func(data []byte, atEOF bool) (int, []byte, error) {
// slices are pointers in themselves
// let GoLang's garbage collection collect old buffers when they are no longer referenced
//var tokenBuf []byte
//var tokenBufIdx uint
//var l sync.Mutex

return func(data []byte, atEOF bool) (int, []byte, error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}

// skip until we get our first 0x1A (message start)
i := bytes.IndexByte(data, 0x1A)
if -1 == i || len(data) < i+11 {
// we do not even have the smallest message, let's get some more data
return 0, nil, nil
}
// byte 2 is our message type, so it tells us how long this message is
msgLen := 0
switch data[i+1] {
case 0x31:
// mode-ac 11 bytes (2+8)
// 1(esc), 1(type), 6(mlat), 1(signal), 2(mode-ac)
msgLen = 11
case 0x32:
// mode-s short 16 bytes
// 1(esc), 1(type), 6(mlat), 1(signal), 7(mode-s short)
msgLen = 16
case 0x33:
// mode-s long 23 bytes
// 1(esc), 1(type), 6(mlat), 1(signal), 14(mode-s extended squitter)
msgLen = 23
case 0x34:
// Config Settings and Stats
// 1(esc), 1(type), 6(mlat), 1(unused), (1)DIP Config, (1)timestamp error ticks
msgLen = 11
case 0x1A:
// found an escaped 0x1A, skip that too
return i + 2, nil, nil
func ScanBeast(data []byte, atEOF bool) (int, []byte, error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}

default:
// unknown? assume we got an out of sequence and skip
return i + 1, nil, nil
}
bufLen := len(data) - i
//println("type", data[i+1], "input len", bufLen, "msg len",msgLen)
if bufLen >= tokenBufLen {
// we have enough in our buffer
// account for double escapes
bufferAdvance := i + msgLen
// skip until we get our first 0x1A (message start)
i := bytes.IndexByte(data, 0x1A)
if -1 == i || len(data) < i+11 {
// we do not even have the smallest message, let's get some more data
return 0, nil, nil
}
// byte 2 is our message type, so it tells us how long this message is
msgLen := 0
switch data[i+1] {
case 0x31:
// mode-ac 11 bytes (2+8)
// 1(esc), 1(type), 6(mlat), 1(signal), 2(mode-ac)
msgLen = 11
case 0x32:
// mode-s short 16 bytes
// 1(esc), 1(type), 6(mlat), 1(signal), 7(mode-s short)
msgLen = 16
case 0x33:
// mode-s long 23 bytes
// 1(esc), 1(type), 6(mlat), 1(signal), 14(mode-s extended squitter)
msgLen = 23
case 0x34:
// Config Settings and Stats
// 1(esc), 1(type), 6(mlat), 1(unused), (1)DIP Config, (1)timestamp error ticks
msgLen = 11
case 0x1A:
// found an escaped 0x1A, skip that too
return i + 2, nil, nil

token := [tokenBufLen]byte{}
default:
// unknown? assume we got an out of sequence and skip
return i + 1, nil, nil
}
bufLen := len(data) - i
//println("type", data[i+1], "input len", bufLen, "msg len",msgLen)
if bufLen >= tokenBufLen {
// we have enough in our buffer
// account for double escapes
bufferAdvance := i + msgLen

dataIndex := i // start at the <esc>/0x1a
tokenIndex := 0
for tokenIndex < msgLen && dataIndex < i+tokenBufLen {
token[tokenIndex] = data[dataIndex]
token := [tokenBufLen]byte{}

// if the next byte is an escaped 0x1A, jump it
if data[dataIndex] == 0x1A && data[dataIndex+1] == 0x1A { // skip over the second <esc>
bufferAdvance++
dataIndex++
}
dataIndex := i // start at the <esc>/0x1a
tokenIndex := 0
for tokenIndex < msgLen && dataIndex < i+tokenBufLen {
token[tokenIndex] = data[dataIndex]

// if the next byte is an escaped 0x1A, jump it
if data[dataIndex] == 0x1A && data[dataIndex+1] == 0x1A { // skip over the second <esc>
bufferAdvance++
dataIndex++
tokenIndex++
}
return bufferAdvance, token[0:msgLen], nil

dataIndex++
tokenIndex++
}
// we want more data!
return 0, nil, nil
return bufferAdvance, token[0:msgLen], nil
}
// we want more data!
return 0, nil, nil
}
2 changes: 1 addition & 1 deletion lib/producer/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func WithType(producerType int) Option {
p.splitter = bufio.ScanLines
case Beast:
p.producerType = producerType
p.splitter = ScanBeast()
p.splitter = ScanBeast
default:
p.log.Error().Msgf("Unknown Producer Type")
}
Expand Down
5 changes: 2 additions & 3 deletions lib/tracker/beast/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,9 @@ func (f *Frame) Decode() error {
f.hasDecoded = true
}
return err
} else {
f.hasDecoded = true
return mode_s.ErrNoOp
}
f.hasDecoded = true
return mode_s.ErrNoOp
}

func (f *Frame) TimeStamp() time.Time {
Expand Down
2 changes: 1 addition & 1 deletion lib/tracker/cpr.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ func (cpr *CprLocation) computeLongitudeZone() error {
func (cpr *CprLocation) checkFrameTiming() error {
d := cpr.time1.Sub(cpr.time0)
tt := math.Abs(float64(d.Milliseconds()))
if tt > 1500 { // allow for some network jitter + time of flight jitter
if tt > 10_000 { // allow for some network jitter + time of flight jitter
return errors.New("unable to decode this CPR Pair. they are too far apart in time")
}
return nil
Expand Down
6 changes: 4 additions & 2 deletions lib/tracker/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@ func (t *Tracker) Finish() {
}

func (t *Tracker) EventListener(eventSource EventMaker, waiter *sync.WaitGroup) {
// todo: remove this level of indirection!
for e := range eventSource.Listen() {
t.decodingQueue <- &e
foobar := *(&e)
t.decodingQueue <- &foobar
}
waiter.Done()
t.log.Debug().Msg("Done with Event Source")
Expand Down Expand Up @@ -208,6 +210,7 @@ func (t *Tracker) decodeQueue() {
if nil != t.stats.decodedFrames {
t.stats.decodedFrames.Inc()
}

frame := f.Frame()
err := frame.Decode()
if nil != err {
Expand All @@ -232,7 +235,6 @@ func (t *Tracker) decodeQueue() {

switch typeFrame := frame.(type) {
case *beast.Frame:

plane.HandleModeSFrame(typeFrame.AvrFrame(), f.Source().RefLat, f.Source().RefLon)
plane.setSignalLevel(typeFrame.SignalRssi())
case *mode_s.Frame:
Expand Down
2 changes: 1 addition & 1 deletion lib/tracker/mode_s/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ func (f *Frame) parseRawToMessage() error {
frameLen := len(f.raw)

// cheap bitwise even number check!
if 0 != (frameLen & 1) {
if (frameLen & 1) != 0 {
return fmt.Errorf("frame is an odd length (%d), cannot decode unless length is even", frameLen)
}

Expand Down
2 changes: 1 addition & 1 deletion lib/tracker/mode_s/frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ func (f *Frame) RawString() string {
if nil == f {
return ""
}
if f.fromBytes && "" == f.raw {
if f.fromBytes && f.raw == "" {
// we need to convert
f.raw = fmt.Sprintf("%X", f.message)
}
Expand Down

0 comments on commit 8f12b07

Please sign in to comment.