#59
pull/62/head
Christopher Young 2015-09-24 17:18:21 -04:00
rodzic 3e972b3753
commit 0dc32f23e1
2 zmienionych plików z 79 dodań i 6 usunięć

Wyświetl plik

@ -1,6 +1,7 @@
package main
import (
"../uatparse"
"bufio"
"encoding/hex"
"encoding/json"
@ -73,10 +74,12 @@ var gpsReplayfp *os.File
var ahrsReplayfp *os.File
type msg struct {
MessageClass uint
TimeReceived time.Time
Data []byte
Product uint32
MessageClass uint
TimeReceived time.Time
Data []byte
Product uint32
Signal_strength int
ADSBTowerID string // Index in the 'ADSBTowers' map, if this is a parseable uplink message.
}
// Raw inputs.
@ -85,6 +88,18 @@ var MsgLog []msg
// Time gen_gdl90 was started.
var timeStarted time.Time
type ADSBTower struct {
Lat float64
Lng float64
Signal_strength_last_minute int
signal_power_last_minute int64 // Over total messages.
Signal_strength_max int
Messages_last_minute uint64
Messages_total uint64
}
var ADSBTowers map[string]ADSBTower // Running list of all towers seen. (lat,lng) -> ADSBTower
// Construct the CRC table. Adapted from FAA ref above.
func crcInit() {
var i uint16
@ -315,12 +330,30 @@ func updateMessageStats() {
UAT_messages_last_minute := uint(0)
ES_messages_last_minute := uint(0)
products_last_minute := make(map[string]uint32)
// Clear out ADSBTowers stats.
for t, tinf := range ADSBTowers {
tinf.Messages_last_minute = 0
tinf.Signal_strength_last_minute = 0
ADSBTowers[t] = tinf
}
for i := 0; i < m; i++ {
if time.Now().Sub(MsgLog[i].TimeReceived).Minutes() < 1 {
t = append(t, MsgLog[i])
if MsgLog[i].MessageClass == MSGCLASS_UAT {
UAT_messages_last_minute++
products_last_minute[getProductNameFromId(int(MsgLog[i].Product))]++
if len(MsgLog[i].ADSBTowerID) > 0 { // Update tower stats.
tid := MsgLog[i].ADSBTowerID
twr := ADSBTowers[tid]
twr.Messages_last_minute++
twr.signal_power_last_minute += int64(MsgLog[i].Signal_strength)
if MsgLog[i].Signal_strength > twr.Signal_strength_max { // Update alltime max signal strength.
twr.Signal_strength_max = MsgLog[i].Signal_strength
}
ADSBTowers[tid] = twr
}
} else if MsgLog[i].MessageClass == MSGCLASS_ES {
ES_messages_last_minute++
}
@ -339,6 +372,16 @@ func updateMessageStats() {
globalStatus.ES_messages_max = ES_messages_last_minute
}
// Update average signal strength over last minute for all ADSB towers.
for t, tinf := range ADSBTowers {
if tinf.Messages_last_minute == 0 {
tinf.Signal_strength_last_minute = 0
} else {
tinf.Signal_strength_last_minute = int(tinf.signal_power_last_minute / int64(tinf.Messages_last_minute))
}
ADSBTowers[t] = tinf
}
}
func updateStatus() {
@ -407,12 +450,15 @@ func parseInput(buf string) ([]byte, uint16) {
parseDownlinkReport(s)
}
var thisSignalStrength int
if isUplink && len(x) >= 3 {
// See if we can parse out the signal strength.
ss := x[2]
if strings.HasPrefix(ss, "ss=") {
ssStr := ss[3:]
if ssInt, err := strconv.Atoi(ssStr); err == nil {
thisSignalStrength = ssInt
if ssInt > maxSignalStrength {
maxSignalStrength = ssInt
}
@ -427,7 +473,7 @@ func parseInput(buf string) ([]byte, uint16) {
return nil, 0
}
if msglen == UPLINK_FRAME_DATA_BYTES {
if isUplink && msglen == UPLINK_FRAME_DATA_BYTES {
msgtype = MSGTYPE_UPLINK
} else if msglen == 34 {
msgtype = MSGTYPE_LONG_REPORT
@ -449,7 +495,26 @@ func parseInput(buf string) ([]byte, uint16) {
thisMsg.MessageClass = MSGCLASS_UAT
thisMsg.TimeReceived = time.Now()
thisMsg.Data = frame
thisMsg.Product = 9999
thisMsg.Product = 9999 //FIXME.
thisMsg.Signal_strength = thisSignalStrength
if msgtype == MSGTYPE_UPLINK {
// Parse the UAT message.
uatMsg, err := uatparse.New(buf)
if err == nil {
uatMsg.DecodeUplink()
towerid := fmt.Sprintf("(%f,%f)", uatMsg.Lat, uatMsg.Lon)
thisMsg.ADSBTowerID = towerid
if _, ok := ADSBTowers[towerid]; !ok { // First time we've seen the tower. Start tracking.
var newTower ADSBTower
newTower.Lat = uatMsg.Lat
newTower.Lng = uatMsg.Lon
ADSBTowers[towerid] = newTower
}
twr := ADSBTowers[towerid]
twr.Messages_total++
ADSBTowers[towerid] = twr
}
}
if isUplink && msgtype == MSGTYPE_UPLINK && len(x) > 11 { //FIXME: Need to pull out FIS-B frames from within the uplink packet.
thisMsg.Product = ((uint32(frame[10]) & 0x1f) << 6) | (uint32(frame[11]) >> 2)
}
@ -647,6 +712,7 @@ func main() {
log.Printf("Stratux %s (%s) starting.\n", stratuxVersion, stratuxBuild)
ADSBTowers = make(map[string]ADSBTower)
MsgLog = make([]msg, 0)
crcInit() // Initialize CRC16 table.

Wyświetl plik

@ -92,6 +92,12 @@ func handleSituationRequest(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "%s\n", situationJSON)
}
// AJAX call - /getTowers. Responds with all ADS-B ground towers that have sent messages that we were able to parse, along with its stats.
func handleTowersRequest(w http.ResponseWriter, r *http.Request) {
towersJSON, _ := json.Marshal(&ADSBTowers)
fmt.Fprintf(w, "%s\n", towersJSON)
}
func managementInterface() {
http.Handle("/", http.FileServer(http.Dir("/var/www")))
http.Handle("/logs/", http.StripPrefix("/logs/", http.FileServer(http.Dir("/var/log"))))
@ -104,6 +110,7 @@ func managementInterface() {
http.HandleFunc("/getTraffic", handleTrafficRequest)
http.HandleFunc("/getSituation", handleSituationRequest)
http.HandleFunc("/getTowers", handleTowersRequest)
err := http.ListenAndServe(managementAddr, nil)