diff --git a/audiostream.go b/audiostream.go index d642006..42b3291 100644 --- a/audiostream.go +++ b/audiostream.go @@ -68,6 +68,7 @@ func (s *audioStream) handleRxSeqBufEntry(e seqBufEntry) { } else { missingPkts = int(gotSeq) + 65536 - int(expectedSeq) } + bandwidth.reportLoss(missingPkts) log.Error("lost ", missingPkts, " audio packets") } } diff --git a/bandwidth.go b/bandwidth.go index 0b5ab18..538ba9b 100644 --- a/bandwidth.go +++ b/bandwidth.go @@ -8,7 +8,10 @@ import ( type bandwidthStruct struct { toRadioBytes int + toRadioPkts int fromRadioBytes int + fromRadioPkts int + lostPkts int lastGet time.Time } @@ -22,24 +25,43 @@ func (b *bandwidthStruct) reset() { bandwidth = bandwidthStruct{} } +// Call this function when a packet is sent or received. func (b *bandwidthStruct) add(toRadioBytes, fromRadioBytes int) { bandwidthMutex.Lock() defer bandwidthMutex.Unlock() b.toRadioBytes += toRadioBytes + if toRadioBytes > 0 { + b.toRadioPkts++ + } b.fromRadioBytes += fromRadioBytes + if fromRadioBytes > 0 { + b.fromRadioPkts++ + } } -func (b *bandwidthStruct) get() (toRadioBytesPerSec, fromRadioBytesPerSec int) { +// Call this function when a packet is sent or received. +func (b *bandwidthStruct) reportLoss(pkts int) { + bandwidthMutex.Lock() + defer bandwidthMutex.Unlock() + + b.lostPkts += pkts +} + +func (b *bandwidthStruct) get() (toRadioBytesPerSec, fromRadioBytesPerSec int, lossPercent float64) { bandwidthMutex.Lock() defer bandwidthMutex.Unlock() secs := time.Since(b.lastGet).Seconds() toRadioBytesPerSec = int(float64(b.toRadioBytes) / secs) fromRadioBytesPerSec = int(float64(b.fromRadioBytes) / secs) + lossPercent = (float64(b.lostPkts) / float64(b.toRadioPkts)) * 100 b.toRadioBytes = 0 + b.toRadioPkts = 0 b.fromRadioBytes = 0 + b.fromRadioPkts = 0 + b.lostPkts = 0 b.lastGet = time.Now() return } diff --git a/controlstream.go b/controlstream.go index 94ffff9..a864cfb 100644 --- a/controlstream.go +++ b/controlstream.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/binary" "errors" + "fmt" "strings" "time" ) @@ -261,10 +262,11 @@ func (s *controlStream) loop() { log.Error("auth timeout, audio/serial stream may stop") case <-statusLogTicker.C: if s.serialAndAudioStreamOpened { - up, down := bandwidth.get() + up, down, loss := bandwidth.get() log.Print("running for ", time.Since(startTime).Round(time.Second), " rtt ", s.common.pkt7.latency.Milliseconds(), "ms up ", - bandwidth.formatByteCount(up), "/s down ", bandwidth.formatByteCount(down), "/s") + bandwidth.formatByteCount(up), "/s down ", + bandwidth.formatByteCount(down), "/s loss ", fmt.Sprintf("%.2f", loss), "%") } case <-s.deinitNeededChan: s.deinitFinishedChan <- true diff --git a/serialstream.go b/serialstream.go index e57a4cd..15963d6 100644 --- a/serialstream.go +++ b/serialstream.go @@ -76,6 +76,7 @@ func (s *serialStream) handleRxSeqBufEntry(e seqBufEntry) { } else { missingPkts = int(gotSeq) + 65536 - int(expectedSeq) } + bandwidth.reportLoss(missingPkts) log.Error("lost ", missingPkts, " packets") } }