UAT and ES mode/hardware handling

pull/101/head
Joseph Poirier 2015-10-25 22:16:19 -05:00
rodzic 7bfb0067b4
commit 595f50cc2f
1 zmienionych plików z 258 dodań i 67 usunięć

Wyświetl plik

@ -1,133 +1,200 @@
package main package main
import ( import (
"log"
"os/exec"
"strconv"
"strings"
"sync"
"time"
"../godump978" "../godump978"
rtl "github.com/jpoirier/gortlsdr" rtl "github.com/jpoirier/gortlsdr"
"log"
"time"
) )
var uatSDR int // Index. type UAT struct {
var esSDR int // Index. dev *rtl.Context
indexID int
}
type ES struct {
dev *rtl.Context
indexID int
}
var UATDev *UAT
var ESDev *ES
var uat_shutdown chan int
var uat_wg *sync.WaitGroup = &sync.WaitGroup{}
var es_shutdown chan int
var es_wg *sync.WaitGroup = &sync.WaitGroup{}
var maxSignalStrength int var maxSignalStrength int
// Read 978MHz from SDR. func (e *ES) read() {
func sdrReader() { defer es_wg.Done()
var err error log.Println("Entered ES read() ...")
var dev *rtl.Context cmd := exec.Command("/usr/bin/dump1090", "--net", "--device-index", strconv.Itoa(e.indexID))
err := cmd.Start()
log.Printf("===== UAT Device name: %s =====\n", rtl.GetDeviceName(uatSDR)) if err != nil {
if dev, err = rtl.Open(uatSDR); err != nil { log.Printf("Error executing /usr/bin/dump1090: %s\n", err.Error())
log.Printf("\tOpen Failed, exiting\n")
uatSDR = -1
return return
} }
defer dev.Close() log.Println("Executed /usr/bin/dump1090 successfully...")
m, p, s, err := dev.GetUsbStrings() for {
if err != nil { select {
log.Printf("\tGetUsbStrings Failed - error: %s\n", err) default:
} else { time.Sleep(1 * time.Second)
log.Printf("\tGetUsbStrings - %s %s %s\n", m, p, s) case _ = <-es_shutdown:
log.Println("ES read(): shutdown msg received, calling cmd.Process.Kill() ...")
cmd.Process.Kill()
log.Println("\t kill successful...")
return
}
} }
log.Printf("\tGetTunerType: %s\n", dev.GetTunerType()) }
func (u *UAT) read() {
defer uat_wg.Done()
// defer u.dev.Close()
log.Println("Entered UAT read() ...")
var buffer = make([]uint8, rtl.DefaultBufLength)
for {
select {
default:
nRead, err := u.dev.ReadSync(buffer, rtl.DefaultBufLength)
if err != nil {
log.Printf("\tReadSync Failed - error: %s\n", err)
break
}
// log.Printf("\tReadSync %d\n", nRead)
if nRead > 0 {
buf := buffer[:nRead]
godump978.InChan <- buf
}
case _ = <-uat_shutdown:
log.Println("UAT read(): shutdown msg received...")
return
}
}
}
func (e *ES) sdrConfig() (err error) {
return
}
// Read 978MHz from SDR.
func (u *UAT) sdrConfig() (err error) {
log.Printf("===== UAT Device name: %s =====\n", rtl.GetDeviceName(u.indexID))
if u.dev, err = rtl.Open(u.indexID); err != nil {
log.Printf("\tUAT Open Failed...\n")
return
}
log.Printf("\tGetTunerType: %s\n", u.dev.GetTunerType())
//---------- Set Tuner Gain ---------- //---------- Set Tuner Gain ----------
tgain := 480 err = u.dev.SetTunerGainMode(true)
err = dev.SetTunerGainMode(true)
if err != nil { if err != nil {
u.dev.Close()
log.Printf("\tSetTunerGainMode Failed - error: %s\n", err) log.Printf("\tSetTunerGainMode Failed - error: %s\n", err)
return
} else { } else {
log.Printf("\tSetTunerGainMode Successful\n") log.Printf("\tSetTunerGainMode Successful\n")
} }
err = dev.SetTunerGain(tgain) tgain := 480
err = u.dev.SetTunerGain(tgain)
if err != nil { if err != nil {
u.dev.Close()
log.Printf("\tSetTunerGain Failed - error: %s\n", err) log.Printf("\tSetTunerGain Failed - error: %s\n", err)
return
} else { } else {
log.Printf("\tSetTunerGain Successful\n") log.Printf("\tSetTunerGain Successful\n")
} }
//---------- Get/Set Sample Rate ---------- //---------- Get/Set Sample Rate ----------
samplerate := 2083334 samplerate := 2083334
err = dev.SetSampleRate(samplerate) err = u.dev.SetSampleRate(samplerate)
if err != nil { if err != nil {
u.dev.Close()
log.Printf("\tSetSampleRate Failed - error: %s\n", err) log.Printf("\tSetSampleRate Failed - error: %s\n", err)
return
} else { } else {
log.Printf("\tSetSampleRate - rate: %d\n", samplerate) log.Printf("\tSetSampleRate - rate: %d\n", samplerate)
} }
log.Printf("\tGetSampleRate: %d\n", dev.GetSampleRate()) log.Printf("\tGetSampleRate: %d\n", u.dev.GetSampleRate())
//---------- Get/Set Xtal Freq ---------- //---------- Get/Set Xtal Freq ----------
rtlFreq, tunerFreq, err := dev.GetXtalFreq() rtlFreq, tunerFreq, err := u.dev.GetXtalFreq()
if err != nil { if err != nil {
u.dev.Close()
log.Printf("\tGetXtalFreq Failed - error: %s\n", err) log.Printf("\tGetXtalFreq Failed - error: %s\n", err)
return
} else { } else {
log.Printf("\tGetXtalFreq - Rtl: %d, Tuner: %d\n", rtlFreq, tunerFreq) log.Printf("\tGetXtalFreq - Rtl: %d, Tuner: %d\n", rtlFreq, tunerFreq)
} }
newRTLFreq := 28800000 newRTLFreq := 28800000
newTunerFreq := 28800000 newTunerFreq := 28800000
err = dev.SetXtalFreq(newRTLFreq, newTunerFreq) err = u.dev.SetXtalFreq(newRTLFreq, newTunerFreq)
if err != nil { if err != nil {
u.dev.Close()
log.Printf("\tSetXtalFreq Failed - error: %s\n", err) log.Printf("\tSetXtalFreq Failed - error: %s\n", err)
return
} else { } else {
log.Printf("\tSetXtalFreq - Center freq: %d, Tuner freq: %d\n", log.Printf("\tSetXtalFreq - Center freq: %d, Tuner freq: %d\n",
newRTLFreq, newTunerFreq) newRTLFreq, newTunerFreq)
} }
//---------- Get/Set Center Freq ---------- //---------- Get/Set Center Freq ----------
err = dev.SetCenterFreq(978000000) err = u.dev.SetCenterFreq(978000000)
if err != nil { if err != nil {
u.dev.Close()
log.Printf("\tSetCenterFreq 978MHz Failed, error: %s\n", err) log.Printf("\tSetCenterFreq 978MHz Failed, error: %s\n", err)
return
} else { } else {
log.Printf("\tSetCenterFreq 978MHz Successful\n") log.Printf("\tSetCenterFreq 978MHz Successful\n")
} }
log.Printf("\tGetCenterFreq: %d\n", dev.GetCenterFreq()) log.Printf("\tGetCenterFreq: %d\n", u.dev.GetCenterFreq())
//---------- Set Bandwidth ---------- //---------- Set Bandwidth ----------
bw := 1000000 bw := 1000000
log.Printf("\tSetting Bandwidth: %d\n", bw) log.Printf("\tSetting Bandwidth: %d\n", bw)
if err = dev.SetTunerBw(bw); err != nil { if err = u.dev.SetTunerBw(bw); err != nil {
u.dev.Close()
log.Printf("\tSetTunerBw %d Failed, error: %s\n", bw, err) log.Printf("\tSetTunerBw %d Failed, error: %s\n", bw, err)
return
} else { } else {
log.Printf("\tSetTunerBw %d Successful\n", bw) log.Printf("\tSetTunerBw %d Successful\n", bw)
} }
if err = dev.ResetBuffer(); err == nil { if err = u.dev.ResetBuffer(); err != nil {
log.Printf("\tResetBuffer Successful\n") u.dev.Close()
} else {
log.Printf("\tResetBuffer Failed - error: %s\n", err) log.Printf("\tResetBuffer Failed - error: %s\n", err)
return
} else {
log.Printf("\tResetBuffer Successful\n")
} }
//---------- Get/Set Freq Correction ---------- //---------- Get/Set Freq Correction ----------
freqCorr := dev.GetFreqCorrection() freqCorr := u.dev.GetFreqCorrection()
log.Printf("\tGetFreqCorrection: %d\n", freqCorr) log.Printf("\tGetFreqCorrection: %d\n", freqCorr)
err = dev.SetFreqCorrection(globalSettings.PPM) err = u.dev.SetFreqCorrection(globalSettings.PPM)
if err != nil { if err != nil {
u.dev.Close()
log.Printf("\tSetFreqCorrection %d Failed, error: %s\n", globalSettings.PPM, err) log.Printf("\tSetFreqCorrection %d Failed, error: %s\n", globalSettings.PPM, err)
return
} else { } else {
log.Printf("\tSetFreqCorrection %d Successful\n", globalSettings.PPM) log.Printf("\tSetFreqCorrection %d Successful\n", globalSettings.PPM)
} }
return
for uatSDR != -1 {
var buffer = make([]uint8, rtl.DefaultBufLength)
nRead, err := dev.ReadSync(buffer, rtl.DefaultBufLength)
if err != nil {
log.Printf("\tReadSync Failed - error: %s\n", err)
uatSDR = -1
break
} else {
// log.Printf("\tReadSync %d\n", nRead)
buf := buffer[:nRead]
godump978.InChan <- buf
}
}
} }
// Read from the godump978 channel - on or off. // Read from the godump978 channel - on or off.
func uatReader() { func uatReader() {
log.Println("Entered uatReader() ...")
for { for {
uat := <-godump978.OutChan uat := <-godump978.OutChan
o, msgtype := parseInput(uat) o, msgtype := parseInput(uat)
@ -137,34 +204,158 @@ func uatReader() {
} }
} }
func (u *UAT) shutdown() {
log.Println("Entered UAT shutdown() ...")
close(uat_shutdown) // signal to shutdown
log.Println("UAT shutdown(): closing device ...")
// XXX: how to preempt ReadSync?
// the assumption is that calling Close()
// causes ReadSync to return immediately
u.dev.Close()
log.Println("UAT shutdown(): calling uat_wg.Wait() ...")
uat_wg.Wait() // Wait for the goroutine to shutdown
log.Println("UAT shutdown(): uat_wg.Wait() returned...")
}
func (e *ES) shutdown() {
log.Println("Entered ES shutdown() ...")
close(es_shutdown) // signal to shutdown
log.Println("ES shutdown(): calling es_wg.Wait() ...")
es_wg.Wait() // Wait for the goroutine to shutdown
log.Println("ES shutdown(): es_wg.Wait() returned...")
}
var devMap = map[int]string{0: "", 1: ""}
// Watch for config/device changes. // Watch for config/device changes.
func sdrWatcher() { func sdrWatcher() {
timer := time.NewTicker(1 * time.Second)
for { for {
<-timer.C time.Sleep(1 * time.Second)
// Update device count. count := rtl.GetDeviceCount()
globalStatus.Devices = uint(rtl.GetDeviceCount()) log.Println("DeviceCount...", count)
if uatSDR == -1 && globalSettings.UAT_Enabled { // support two and only two dongles
if globalStatus.Devices == 0 { if count > 2 {
log.Printf("No RTL-SDR devices.\n") count = 2
continue
}
uatSDR = 0
go sdrReader()
} }
if esSDR == -1 && globalSettings.ES_Enabled {
if globalStatus.Devices == 0 || (globalStatus.Devices == 1 && globalSettings.UAT_Enabled) { // cleanup if necessary
log.Printf("Not enough RTL-SDR devices.\n") if count < 1 || (!globalSettings.UAT_Enabled && !globalSettings.ES_Enabled) {
log.Println("doing cleanup...")
if UATDev != nil {
UATDev.shutdown()
UATDev = nil
} }
esSDR = 1 if ESDev != nil {
ESDev.shutdown()
ESDev = nil
}
continue
} }
if count == 1 {
if UATDev != nil && ESDev == nil {
UATDev.indexID = 0
} else if UATDev == nil && ESDev != nil {
ESDev.indexID = 0
}
}
ids := []string{"", ""}
for i := 0; i < count; i++ {
// manufact, product, serial, err
_, _, s, _ := rtl.GetDeviceUsbStrings(i)
ids[i] = s
}
// UAT specific handling
// When count is one, favor UAT in the case where the user
// has enabled both UAT and ES via the web interface.
id := 0
if globalSettings.UAT_Enabled {
if count == 1 {
if ESDev != nil {
ESDev.shutdown()
ESDev = nil
}
} else { // count == 2
if UATDev == nil && ESDev != nil {
if ESDev.indexID == 0 {
id = 1
}
}
}
if UATDev == nil {
// preference check based on stratux
// hardware serial when it exists
serial := ids[id]
if strings.HasPrefix(serial, "stratux:1090") {
log.Println("Settings conflict: 978UAT set via WebUI but hardware serial says stratux:1090")
} else {
UATDev = &UAT{indexID: id}
if err := UATDev.sdrConfig(); err != nil {
UATDev = nil
} else {
uat_shutdown = make(chan int)
uat_wg.Add(1)
go UATDev.read()
}
}
}
} else if UATDev != nil {
UATDev.shutdown()
UATDev = nil
if count == 1 && ESDev != nil {
ESDev.indexID = 0
}
}
// ES specific handling
id = 0
if globalSettings.ES_Enabled {
if count == 1 {
if globalSettings.UAT_Enabled {
// defer to the UAT handler
goto End
}
} else { // count == 2
if ESDev == nil && UATDev != nil {
if UATDev.indexID == 0 {
id = 1
}
}
}
if ESDev == nil {
// preference check based on stratux
// hardware serial when it exists
serial := ids[id]
if strings.HasPrefix(serial, "stratux:978") {
log.Println("Settings conflict: 1090ES set via WebUI but hardware serial says stratux:978")
} else {
ESDev = &ES{indexID: id}
if err := ESDev.sdrConfig(); err != nil {
ESDev = nil
} else {
es_shutdown = make(chan int)
es_wg.Add(1)
go ESDev.read()
}
}
}
} else if ESDev != nil {
ESDev.shutdown()
ESDev = nil
if count == 1 && UATDev != nil {
UATDev.indexID = 0
}
}
End:
} }
} }
func sdrInit() { func sdrInit() {
uatSDR = -1
esSDR = -1
go sdrWatcher() go sdrWatcher()
go uatReader() go uatReader()
godump978.Dump978Init() godump978.Dump978Init()