2020-10-26 14:59:49 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"sync"
|
|
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type bandwidthStruct struct {
|
|
|
|
|
toRadioBytes int
|
2020-10-26 15:17:16 +01:00
|
|
|
toRadioPkts int
|
2020-10-26 14:59:49 +01:00
|
|
|
fromRadioBytes int
|
2020-10-26 15:17:16 +01:00
|
|
|
fromRadioPkts int
|
2020-10-26 14:59:49 +01:00
|
|
|
lastGet time.Time
|
2020-10-28 10:15:13 +01:00
|
|
|
|
|
|
|
|
lostPkts int
|
|
|
|
|
lastLostReset time.Time
|
|
|
|
|
retransmits int
|
|
|
|
|
lastRetransmitReset time.Time
|
2020-10-26 14:59:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bandwidth bandwidthStruct
|
|
|
|
|
var bandwidthMutex sync.Mutex
|
|
|
|
|
|
|
|
|
|
func (b *bandwidthStruct) reset() {
|
|
|
|
|
bandwidthMutex.Lock()
|
|
|
|
|
defer bandwidthMutex.Unlock()
|
|
|
|
|
|
|
|
|
|
bandwidth = bandwidthStruct{}
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-26 15:17:16 +01:00
|
|
|
// Call this function when a packet is sent or received.
|
2020-10-26 14:59:49 +01:00
|
|
|
func (b *bandwidthStruct) add(toRadioBytes, fromRadioBytes int) {
|
|
|
|
|
bandwidthMutex.Lock()
|
|
|
|
|
defer bandwidthMutex.Unlock()
|
|
|
|
|
|
|
|
|
|
b.toRadioBytes += toRadioBytes
|
2020-10-26 15:17:16 +01:00
|
|
|
if toRadioBytes > 0 {
|
|
|
|
|
b.toRadioPkts++
|
|
|
|
|
}
|
2020-10-26 14:59:49 +01:00
|
|
|
b.fromRadioBytes += fromRadioBytes
|
2020-10-26 15:17:16 +01:00
|
|
|
if fromRadioBytes > 0 {
|
|
|
|
|
b.fromRadioPkts++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (b *bandwidthStruct) reportLoss(pkts int) {
|
|
|
|
|
bandwidthMutex.Lock()
|
|
|
|
|
defer bandwidthMutex.Unlock()
|
|
|
|
|
|
2020-10-28 10:15:13 +01:00
|
|
|
if b.lostPkts == 0 {
|
|
|
|
|
b.lastLostReset = time.Now()
|
|
|
|
|
}
|
2020-10-26 15:17:16 +01:00
|
|
|
b.lostPkts += pkts
|
2020-10-26 14:59:49 +01:00
|
|
|
}
|
|
|
|
|
|
2020-10-28 10:15:13 +01:00
|
|
|
func (b *bandwidthStruct) reportRetransmit(pkts int) {
|
|
|
|
|
bandwidthMutex.Lock()
|
|
|
|
|
defer bandwidthMutex.Unlock()
|
|
|
|
|
|
|
|
|
|
if b.retransmits == 0 {
|
|
|
|
|
b.lastRetransmitReset = time.Now()
|
|
|
|
|
}
|
|
|
|
|
b.retransmits += pkts
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (b *bandwidthStruct) get() (toRadioBytesPerSec, fromRadioBytesPerSec int, lost int, retransmits int) {
|
2020-10-26 14:59:49 +01:00
|
|
|
bandwidthMutex.Lock()
|
|
|
|
|
defer bandwidthMutex.Unlock()
|
|
|
|
|
|
|
|
|
|
secs := time.Since(b.lastGet).Seconds()
|
|
|
|
|
toRadioBytesPerSec = int(float64(b.toRadioBytes) / secs)
|
|
|
|
|
fromRadioBytesPerSec = int(float64(b.fromRadioBytes) / secs)
|
|
|
|
|
|
|
|
|
|
b.toRadioBytes = 0
|
2020-10-26 15:17:16 +01:00
|
|
|
b.toRadioPkts = 0
|
2020-10-26 14:59:49 +01:00
|
|
|
b.fromRadioBytes = 0
|
2020-10-26 15:17:16 +01:00
|
|
|
b.fromRadioPkts = 0
|
2020-10-26 14:59:49 +01:00
|
|
|
b.lastGet = time.Now()
|
2020-10-28 10:15:13 +01:00
|
|
|
|
|
|
|
|
secs = time.Since(b.lastLostReset).Seconds()
|
|
|
|
|
lost = b.lostPkts
|
|
|
|
|
// Only resetting error reports in a longer timeframe.
|
|
|
|
|
if secs >= 60 {
|
|
|
|
|
b.lostPkts = 0
|
|
|
|
|
b.lastLostReset = time.Now()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
secs = time.Since(b.lastRetransmitReset).Seconds()
|
|
|
|
|
retransmits = b.retransmits
|
|
|
|
|
// Only resetting error reports in a longer timeframe.
|
|
|
|
|
if secs >= 60 {
|
|
|
|
|
b.retransmits = 0
|
|
|
|
|
b.lastRetransmitReset = time.Now()
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-26 14:59:49 +01:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (b *bandwidthStruct) formatByteCount(c int) string {
|
|
|
|
|
const unit = 1000
|
|
|
|
|
if c < unit {
|
|
|
|
|
return fmt.Sprintf("%d B", c)
|
|
|
|
|
}
|
|
|
|
|
div, exp := int(unit), 0
|
|
|
|
|
for n := c / unit; n >= unit; n /= unit {
|
|
|
|
|
div *= unit
|
|
|
|
|
exp++
|
|
|
|
|
}
|
|
|
|
|
return fmt.Sprintf("%.1f %cB", float64(c)/float64(div), "kMGTPE"[exp])
|
|
|
|
|
}
|