Merge pull request #4 from cyoung/master

Merge updates from cyoung master
pull/169/head
AvSquirrel 2015-12-13 23:29:53 -06:00
commit 2d2d64a038
7 zmienionych plików z 214 dodań i 53 usunięć

Wyświetl plik

@ -1,7 +1,9 @@
ifeq "$(CIRCLECI)" "true" ifeq "$(CIRCLECI)" "true"
BUILDINFO= BUILDINFO=
else else
BUILDINFO=-ldflags "-X main.stratuxVersion=`git describe --tags --abbrev=0` -X main.stratuxBuild=`git log -n 1 --pretty=%H`" BUILDINFO=-ldflags "-X main.stratuxVersion=`git describe --tags --abbrev=0` -X main.stratuxBuild=`git log -n 1 --pretty=%H`"
$(if $(GOROOT),,$(error GOROOT is not set!))
endif endif
all: all:
@ -10,8 +12,9 @@ all:
go get -t -d -v ./... go get -t -d -v ./...
go build $(BUILDINFO) main/gen_gdl90.go main/traffic.go main/ry835ai.go main/network.go main/managementinterface.go main/sdr.go main/uibroadcast.go go build $(BUILDINFO) main/gen_gdl90.go main/traffic.go main/ry835ai.go main/network.go main/managementinterface.go main/sdr.go main/uibroadcast.go
.PHONY: test
test: test:
sh -c true make -C test
www: www:
mkdir -p /var/www mkdir -p /var/www

Wyświetl plik

@ -12,6 +12,7 @@ Supported WiFi adapters:
* Edimax EW-7811Un * Edimax EW-7811Un
Tested RTL-SDR: Tested RTL-SDR:
* NooElec NESDR Nano 2 (best)
* NooElec NESDR Mini 2 * NooElec NESDR Mini 2
* Generic R820T (degraded performance) * Generic R820T (degraded performance)

Wyświetl plik

@ -107,7 +107,7 @@ apt-get install -y git cmake libusb-1.0-0.dev build-essential
cd /root cd /root
rm -rf rtl-sdr rm -rf rtl-sdr
git clone git://git.osmocom.org/rtl-sdr.git git clone https://github.com/jpoirier/librtlsdr rtl-sdr
cd rtl-sdr cd rtl-sdr
mkdir build mkdir build
cd build cd build

Wyświetl plik

@ -2,6 +2,7 @@ package main
import ( import (
"bufio" "bufio"
"compress/gzip"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
@ -23,15 +24,12 @@ import (
const ( const (
configLocation = "/etc/stratux.conf" configLocation = "/etc/stratux.conf"
indexFilename = "/var/log/stratux/LOGINDEX"
managementAddr = ":80" managementAddr = ":80"
debugLog = "/var/log/stratux.log" debugLog = "/var/log/stratux.log"
maxDatagramSize = 8192 maxDatagramSize = 8192
maxUserMsgQueueSize = 25000 // About 10MB per port per connected client. maxUserMsgQueueSize = 25000 // About 10MB per port per connected client.
uatReplayLog = "/var/log/stratux-uat.log" logDirectory = "/var/log/stratux"
esReplayLog = "/var/log/stratux-es.log"
gpsReplayLog = "/var/log/stratux-gps.log"
ahrsReplayLog = "/var/log/stratux-ahrs.log"
dump1090ReplayLog = "/var/log/stratux-dump1090.log"
UPLINK_BLOCK_DATA_BITS = 576 UPLINK_BLOCK_DATA_BITS = 576
UPLINK_BLOCK_BITS = (UPLINK_BLOCK_DATA_BITS + 160) UPLINK_BLOCK_BITS = (UPLINK_BLOCK_DATA_BITS + 160)
@ -62,6 +60,12 @@ const (
TRACK_RESOLUTION = float32(360.0 / 256.0) TRACK_RESOLUTION = float32(360.0 / 256.0)
) )
var uatReplayLog string
var esReplayLog string
var gpsReplayLog string
var ahrsReplayLog string
var dump1090ReplayLog string
var stratuxBuild string var stratuxBuild string
var stratuxVersion string var stratuxVersion string
@ -72,11 +76,11 @@ var Crc16Table [256]uint16
var mySituation SituationData var mySituation SituationData
// File handles for replay logging. // File handles for replay logging.
var uatReplayfp *os.File var uatReplayWriter *gzip.Writer
var esReplayfp *os.File var esReplayWriter *gzip.Writer
var gpsReplayfp *os.File var gpsReplayWriter *gzip.Writer
var ahrsReplayfp *os.File var ahrsReplayWriter *gzip.Writer
var dump1090Replayfp *os.File var dump1090ReplayWriter *gzip.Writer
type msg struct { type msg struct {
MessageClass uint MessageClass uint
@ -103,8 +107,49 @@ type ADSBTower struct {
Messages_total uint64 Messages_total uint64
} }
var ADSBTowers map[string]ADSBTower // Running list of all towers seen. (lat,lng) -> ADSBTower var ADSBTowers map[string]ADSBTower // Running list of all towers seen. (lat,lng) -> ADSBTower
func constructFilenames() {
// uatReplayLog = "/var/log/stratux-uat.log"
// esReplayLog = "/var/log/stratux-es.log"
// gpsReplayLog = "/var/log/stratux-gps.log"
// ahrsReplayLog = "/var/log/stratux-ahrs.log"
// dump1090ReplayLog = "/var/log/stratux-dump1090.log"
var fileIndexNumber uint
// First, create the log file directory if it does not exist
os.Mkdir(logDirectory,0644)
f, err := os.Open(indexFilename)
if err != nil {
log.Printf("Unable to open index file %s using index of 0\n", indexFilename)
fileIndexNumber=0
} else {
_, err := fmt.Fscanf(f,"%d\n",&fileIndexNumber)
if err != nil {
log.Printf("Unable to read index file %s using index of 0\n", indexFilename)
}
f.Close()
fileIndexNumber++
}
fo, err := os.Create(indexFilename)
if err != nil {
log.Printf("Error creating index file %s\n", indexFilename)
}
_, err2 := fmt.Fprintf(fo,"%d\n",fileIndexNumber)
if err2 != nil {
log.Printf("Error writing to index file %s\n", indexFilename)
}
fo.Sync()
fo.Close()
uatReplayLog = fmt.Sprintf("%s/%04d-uat.log.gz",logDirectory,fileIndexNumber)
esReplayLog = fmt.Sprintf("%s/%04d-es.log.gz",logDirectory,fileIndexNumber)
gpsReplayLog = fmt.Sprintf("%s/%04d-gps.log.gz",logDirectory,fileIndexNumber)
ahrsReplayLog = fmt.Sprintf("%s/%04d-ahrs.log.gz",logDirectory,fileIndexNumber)
dump1090ReplayLog = fmt.Sprintf("%s/%04d-dump1090.log.gz",logDirectory,fileIndexNumber)
}
// Construct the CRC table. Adapted from FAA ref above. // Construct the CRC table. Adapted from FAA ref above.
func crcInit() { func crcInit() {
var i uint16 var i uint16
@ -506,22 +551,22 @@ func replayLog(msg string, msgclass int) {
if len(msg) == 0 { // Blank message. if len(msg) == 0 { // Blank message.
return return
} }
var fp *os.File var wt *gzip.Writer
switch msgclass { switch msgclass {
case MSGCLASS_UAT: case MSGCLASS_UAT:
fp = uatReplayfp wt = uatReplayWriter
case MSGCLASS_ES: case MSGCLASS_ES:
fp = esReplayfp wt = esReplayWriter
case MSGCLASS_GPS: case MSGCLASS_GPS:
fp = gpsReplayfp wt = gpsReplayWriter
case MSGCLASS_AHRS: case MSGCLASS_AHRS:
fp = ahrsReplayfp wt = ahrsReplayWriter
case MSGCLASS_DUMP1090: case MSGCLASS_DUMP1090:
fp = dump1090Replayfp wt = dump1090ReplayWriter
} }
if fp != nil { if wt != nil {
s := makeReplayLogEntry(msg) s := makeReplayLogEntry(msg)
fp.Write([]byte(s)) wt.Write([]byte(s))
} }
} }
@ -816,37 +861,41 @@ func replayMark(active bool) {
t = fmt.Sprintf("UNPAUSE,%d\n", time.Since(timeStarted).Nanoseconds()) t = fmt.Sprintf("UNPAUSE,%d\n", time.Since(timeStarted).Nanoseconds())
} }
if uatReplayfp != nil { if uatReplayWriter != nil {
uatReplayfp.Write([]byte(t)) uatReplayWriter.Write([]byte(t))
} }
if esReplayfp != nil { if esReplayWriter != nil {
esReplayfp.Write([]byte(t)) esReplayWriter.Write([]byte(t))
} }
if gpsReplayfp != nil { if gpsReplayWriter != nil {
gpsReplayfp.Write([]byte(t)) gpsReplayWriter.Write([]byte(t))
} }
if ahrsReplayfp != nil { if ahrsReplayWriter != nil {
ahrsReplayfp.Write([]byte(t)) ahrsReplayWriter.Write([]byte(t))
} }
if dump1090Replayfp != nil { if dump1090ReplayWriter != nil {
dump1090Replayfp.Write([]byte(t)) dump1090ReplayWriter.Write([]byte(t))
} }
} }
func openReplay(fn string) (*os.File, error) { func openReplay(fn string) (*gzip.Writer, error) {
ret, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) fp, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil { if err != nil {
log.Printf("Failed to open log file '%s': %s\n", fn, err.Error()) log.Printf("Failed to open log file '%s': %s\n", fn, err.Error())
} else { return nil, err
timeFmt := "Mon Jan 2 15:04:05 -0700 MST 2006"
fmt.Fprintf(ret, "START,%s,%s\n", timeStarted.Format(timeFmt), time.Now().Format(timeFmt)) // Start time marker.
} }
return ret, err
gzw := gzip.NewWriter(fp) //FIXME: Close() on the gzip.Writer will not close the underlying file.
timeFmt := "Mon Jan 2 15:04:05 -0700 MST 2006"
s := fmt.Sprintf("START,%s,%s\n", timeStarted.Format(timeFmt), time.Now().Format(timeFmt)) // Start time marker.
gzw.Write([]byte(s))
return gzw, err
} }
func printStats() { func printStats() {
@ -879,6 +928,7 @@ func main() {
} }
log.Printf("Stratux %s (%s) starting.\n", stratuxVersion, stratuxBuild) log.Printf("Stratux %s (%s) starting.\n", stratuxVersion, stratuxBuild)
constructFilenames()
ADSBTowers = make(map[string]ADSBTower) ADSBTowers = make(map[string]ADSBTower)
MsgLog = make([]msg, 0) MsgLog = make([]msg, 0)
@ -894,39 +944,39 @@ func main() {
// Set up the replay logs. Keep these files open in any case, even if replay logging is disabled. // Set up the replay logs. Keep these files open in any case, even if replay logging is disabled.
// UAT replay log. // UAT replay log.
if uatfp, err := openReplay(uatReplayLog); err != nil { if uatwt, err := openReplay(uatReplayLog); err != nil {
globalSettings.ReplayLog = false globalSettings.ReplayLog = false
} else { } else {
uatReplayfp = uatfp uatReplayWriter = uatwt
defer uatReplayfp.Close() defer uatReplayWriter.Close()
} }
// 1090ES replay log. // 1090ES replay log.
if esfp, err := openReplay(esReplayLog); err != nil { if eswt, err := openReplay(esReplayLog); err != nil {
globalSettings.ReplayLog = false globalSettings.ReplayLog = false
} else { } else {
esReplayfp = esfp esReplayWriter = eswt
defer esReplayfp.Close() defer esReplayWriter.Close()
} }
// GPS replay log. // GPS replay log.
if gpsfp, err := openReplay(gpsReplayLog); err != nil { if gpswt, err := openReplay(gpsReplayLog); err != nil {
globalSettings.ReplayLog = false globalSettings.ReplayLog = false
} else { } else {
gpsReplayfp = gpsfp gpsReplayWriter = gpswt
defer gpsReplayfp.Close() defer gpsReplayWriter.Close()
} }
// AHRS replay log. // AHRS replay log.
if ahrsfp, err := openReplay(ahrsReplayLog); err != nil { if ahrswt, err := openReplay(ahrsReplayLog); err != nil {
globalSettings.ReplayLog = false globalSettings.ReplayLog = false
} else { } else {
ahrsReplayfp = ahrsfp ahrsReplayWriter = ahrswt
defer ahrsReplayfp.Close() defer ahrsReplayWriter.Close()
} }
// Dump1090 replay log. // Dump1090 replay log.
if dump1090fp, err := openReplay(dump1090ReplayLog); err != nil { if dump1090wt, err := openReplay(dump1090ReplayLog); err != nil {
globalSettings.ReplayLog = false globalSettings.ReplayLog = false
} else { } else {
dump1090Replayfp = dump1090fp dump1090ReplayWriter = dump1090wt
defer dump1090Replayfp.Close() defer dump1090ReplayWriter.Close()
} }
// Mark the files (whether we're logging or not). // Mark the files (whether we're logging or not).

Wyświetl plik

@ -101,6 +101,21 @@ func handleStatusWS(conn *websocket.Conn) {
} }
} }
func handleSituationWS(conn *websocket.Conn) {
timer := time.NewTicker(100 * time.Millisecond)
for {
<-timer.C
situationJSON, _ := json.Marshal(&mySituation)
_, err := conn.Write(situationJSON)
if err != nil {
break
}
}
}
// AJAX call - /getStatus. Responds with current global status // AJAX call - /getStatus. Responds with current global status
// a webservice call for the same data available on the websocket but when only a single update is needed // a webservice call for the same data available on the websocket but when only a single update is needed
func handleStatusRequest(w http.ResponseWriter, r *http.Request) { func handleStatusRequest(w http.ResponseWriter, r *http.Request) {
@ -225,6 +240,12 @@ func managementInterface() {
Handler: websocket.Handler(handleStatusWS)} Handler: websocket.Handler(handleStatusWS)}
s.ServeHTTP(w, req) s.ServeHTTP(w, req)
}) })
http.HandleFunc("/situation",
func(w http.ResponseWriter, req *http.Request) {
s := websocket.Server{
Handler: websocket.Handler(handleSituationWS)}
s.ServeHTTP(w, req)
})
http.HandleFunc("/weather", http.HandleFunc("/weather",
func(w http.ResponseWriter, req *http.Request) { func(w http.ResponseWriter, req *http.Request) {
s := websocket.Server{ s := websocket.Server{

14
test/Makefile 100644
Wyświetl plik

@ -0,0 +1,14 @@
ifeq "$(CIRCLECI)" "true"
#
else
$(if $(GOROOT),,$(error GOROOT is not set!))
endif
SRCS = $(wildcard *.go)
DEST = $(patsubst %.go,%,$(SRCS))
all: $(DEST)
%: %.go
go build $<

Wyświetl plik

@ -0,0 +1,72 @@
package main
import (
"fmt"
"github.com/kidoman/embd"
_ "github.com/kidoman/embd/host/all"
"github.com/kidoman/embd/sensor/bmp180"
)
var i2cbus embd.I2CBus
var myBMP180 *bmp180.BMP180
func readBMP180() (float64, float64, error) { // ºCelsius, Meters
temp, err := myBMP180.Temperature()
if err != nil {
return temp, 0.0, err
}
altitude, err := myBMP180.Altitude()
altitude = float64(1/0.3048) * altitude // Convert meters to feet.
if err != nil {
return temp, altitude, err
}
return temp, altitude, nil
}
func initBMP180() error {
myBMP180 = bmp180.New(i2cbus) //TODO: error checking.
return nil
}
func initI2C() error {
i2cbus = embd.NewI2CBus(1) //TODO: error checking.
return nil
}
// Unused at the moment. 5 second update, since read functions in bmp180 are slow.
func tempAndPressureReader() {
// Read temperature and pressure altitude.
temp, alt, err_bmp180 := readBMP180()
// Process.
if err_bmp180 != nil {
fmt.Printf("readBMP180(): %s\n", err_bmp180.Error())
} else {
fmt.Printf("Temp %f Alt %f\n",temp,alt)
}
}
func initAHRS() error {
if err := initI2C(); err != nil { // I2C bus.
return err
}
if err := initBMP180(); err != nil { // I2C temperature and pressure altitude.
i2cbus.Close()
return err
}
go tempAndPressureReader()
return nil
}
func main() {
fmt.Printf("Hello world!\n")
initAHRS()
for {
tempAndPressureReader()
}
}