From 9ee3c257009afd60aa61eec39f5d2055355a3d96 Mon Sep 17 00:00:00 2001 From: Jason McNew Date: Sat, 3 Dec 2016 22:24:04 +0000 Subject: [PATCH 1/3] Add function to change gpsd connections. Reconnect if disconnected. --- main/gpsd.go | 52 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/main/gpsd.go b/main/gpsd.go index fc6f0255..acb6a546 100644 --- a/main/gpsd.go +++ b/main/gpsd.go @@ -6,8 +6,13 @@ import ( "log" "math" "sync" + "time" ) +// Channel to disconnect current gpsd connection +var disconnectGpsd chan struct{} +var gps *gpsd.Session + // Determine type of satellite based on PRN number. func satelliteType(prnId int) uint8 { // TODO: Galileo @@ -196,18 +201,45 @@ func initGpsd() { satelliteMutex = &sync.Mutex{} Satellites = make(map[string]SatelliteInfo) - var gps *gpsd.Session - var err error + disconnectGpsd = make(chan struct{}) - if gps, err = gpsd.Dial(gpsd.DefaultAddress); err != nil { - log.Printf("Failed to connect to gpsd: %s", err) + setGpsdHost(gpsd.DefaultAddress) +} + +func setGpsdHost(address string) { + // kill existing monitor goroutine if it exists + if gps != nil { + log.Printf("Stopping previous gpsd session") + disconnectGpsd <- struct{}{} } - gps.AddFilter("DEVICES", processDEVICES) - gps.AddFilter("TPV", processTPV) - gps.AddFilter("SKY", processSKY) - gps.AddFilter("ATT", processATT) + go func() { + for { + var err error + if gps, err = gpsd.Dial(address); err != nil { + log.Printf("Failed to connect to gpsd: %s", err) + time.Sleep(time.Second) + continue + } - gps.SendCommand("DEVICES") - gps.Watch() + log.Printf("Gpsd %s Connected.", address) + + gps.AddFilter("DEVICES", processDEVICES) + gps.AddFilter("TPV", processTPV) + gps.AddFilter("SKY", processSKY) + gps.AddFilter("ATT", processATT) + + reconnect := gps.Watch() + + select { + case <-disconnectGpsd: + log.Printf("Gpsd %s disconnecting", address) + gps.Close() + return + case <-reconnect: + log.Printf("Gpsd %s disconnected. Reconnecting..", address) + time.Sleep(time.Second) + } + } + }() } From f572d91fc6b6086ec7aa060c3da4651486500468 Mon Sep 17 00:00:00 2001 From: Jason McNew Date: Sun, 4 Dec 2016 14:24:56 +0000 Subject: [PATCH 2/3] Integrate gpsd connection management with managment interface. Disabling GPS on the management interface will close the gpsd connection. Add internal function for disconnecting. --- main/gen_gdl90.go | 2 ++ main/gpsd.go | 30 +++++++++++++++++++++++------- main/managementinterface.go | 6 ++++++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/main/gen_gdl90.go b/main/gen_gdl90.go index 0fb6751f..aaa790f5 100755 --- a/main/gen_gdl90.go +++ b/main/gen_gdl90.go @@ -984,6 +984,7 @@ type settings struct { ES_Enabled bool Ping_Enabled bool GPS_Enabled bool + GpsdAddress string NetworkOutputs []networkConnection SerialOutputs map[string]serialConnection AHRS_Enabled bool @@ -1046,6 +1047,7 @@ func defaultSettings() { globalSettings.UAT_Enabled = true globalSettings.ES_Enabled = true globalSettings.GPS_Enabled = true + globalSettings.GpsdAddress = "localhost:2947" //FIXME: Need to change format below. globalSettings.NetworkOutputs = []networkConnection{ {Conn: nil, Ip: "", Port: 4000, Capability: NETWORK_GDL90_STANDARD | NETWORK_AHRS_GDL90}, diff --git a/main/gpsd.go b/main/gpsd.go index acb6a546..2245d893 100644 --- a/main/gpsd.go +++ b/main/gpsd.go @@ -10,7 +10,7 @@ import ( ) // Channel to disconnect current gpsd connection -var disconnectGpsd chan struct{} +var killGpsd chan struct{} var gps *gpsd.Session // Determine type of satellite based on PRN number. @@ -201,16 +201,24 @@ func initGpsd() { satelliteMutex = &sync.Mutex{} Satellites = make(map[string]SatelliteInfo) - disconnectGpsd = make(chan struct{}) + killGpsd = make(chan struct{}) - setGpsdHost(gpsd.DefaultAddress) + if globalSettings.GPS_Enabled { + connectGpsd(globalSettings.GpsdAddress) + } } -func setGpsdHost(address string) { +// Main interface for enabling and changing the gpsd connection +// Calling will block until previous connection disconnects +// If address is zero value, it connects to gpsd on the local machine +func connectGpsd(address string) { // kill existing monitor goroutine if it exists if gps != nil { - log.Printf("Stopping previous gpsd session") - disconnectGpsd <- struct{}{} + disconnectGpsd() + } + + if address == "" { + address = gpsd.DefaultAddress } go func() { @@ -232,9 +240,10 @@ func setGpsdHost(address string) { reconnect := gps.Watch() select { - case <-disconnectGpsd: + case <-killGpsd: log.Printf("Gpsd %s disconnecting", address) gps.Close() + gps = nil return case <-reconnect: log.Printf("Gpsd %s disconnected. Reconnecting..", address) @@ -243,3 +252,10 @@ func setGpsdHost(address string) { } }() } + +// Disconnect from gpsd +// Blocks until connection is disconnected and all goroutines are stopped +func disconnectGpsd() { + log.Printf("Stopping gpsd session") + killGpsd <- struct{}{} +} diff --git a/main/managementinterface.go b/main/managementinterface.go index 290a10b3..5b3ebf2d 100644 --- a/main/managementinterface.go +++ b/main/managementinterface.go @@ -218,6 +218,12 @@ func handleSettingsSetRequest(w http.ResponseWriter, r *http.Request) { case "Ping_Enabled": globalSettings.Ping_Enabled = val.(bool) case "GPS_Enabled": + switch { + case val.(bool) == true && globalSettings.GPS_Enabled == false: + connectGpsd(globalSettings.GpsdAddress) + case val.(bool) == false && globalSettings.GPS_Enabled == true: + disconnectGpsd() + } globalSettings.GPS_Enabled = val.(bool) case "AHRS_Enabled": globalSettings.AHRS_Enabled = val.(bool) From 1e65c0fe80dd0a28770daea87ab9eea16fea1ba7 Mon Sep 17 00:00:00 2001 From: Jason McNew Date: Sun, 4 Dec 2016 20:08:03 +0000 Subject: [PATCH 3/3] Gpsd callback log only in verbose mode. --- main/gpsd.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/main/gpsd.go b/main/gpsd.go index 2245d893..bd402a5a 100644 --- a/main/gpsd.go +++ b/main/gpsd.go @@ -58,7 +58,9 @@ func isSbasInSolution() bool { func processDEVICES(r interface{}) { devices := r.(*gpsd.DEVICESReport) - log.Printf("DEVICES (%d)", len(devices.Devices)) + if globalSettings.DEBUG { + log.Printf("DEVICES (%d)", len(devices.Devices)) + } for _, dev := range devices.Devices { log.Printf(" %s %s %x %s %s %i %s %s %i %s %s %i %d %d", dev.Path, @@ -83,7 +85,9 @@ func processDEVICES(r interface{}) { func processTPV(r interface{}) { tpv := r.(*gpsd.TPVReport) - log.Printf("TPV", tpv.Device, tpv.Mode, tpv.Time, tpv.Tag) + if globalSettings.DEBUG { + log.Printf("TPV", tpv.Device, tpv.Mode, tpv.Time, tpv.Tag) + } mySituation.mu_GPS.Lock() satelliteMutex.Lock() @@ -133,7 +137,9 @@ func processTPV(r interface{}) { func processSKY(r interface{}) { sky := r.(*gpsd.SKYReport) - log.Printf("SKY", sky.Device, sky.Tag) + if globalSettings.DEBUG { + log.Printf("SKY", sky.Device, sky.Tag) + } mySituation.mu_GPS.Lock() satelliteMutex.Lock() @@ -176,7 +182,9 @@ func processSKY(r interface{}) { func processATT(r interface{}) { att := r.(*gpsd.ATTReport) - log.Printf("ATT", att.Device, att.Tag, att.Pitch, att.Roll, att.Heading) + if globalSettings.DEBUG { + log.Printf("ATT", att.Device, att.Tag, att.Pitch, att.Roll, att.Heading) + } mySituation.mu_GPS.Lock()