NMEA pass-through mode
This commit is contained in:
171
gpsd.go
171
gpsd.go
@@ -130,24 +130,37 @@ func isNetConnClosedErr(err error) bool {
|
||||
}
|
||||
func addClient(client net.Conn) {
|
||||
|
||||
_, err := client.Write([]byte("{\"class\":\"VERSION\",\"release\":\"3.25\",\"rev\":\"3.25\",\"proto_major\":3,\"proto_minor\":15}\n"))
|
||||
if err != nil {
|
||||
writeDebug(fmt.Sprintf("Error writing to client: %v\n", err), 1)
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
client.Close()
|
||||
removeClient(client)
|
||||
writeDebug(fmt.Sprintf("GPSd Client disconnected: %v\n", client.RemoteAddr()), 0)
|
||||
if s.NMEAPassthrough {
|
||||
go func() {
|
||||
defer func() {
|
||||
client.Close()
|
||||
removeClient(client)
|
||||
writeDebug(fmt.Sprintf("GPSd Client disconnected: %v\n", client.RemoteAddr()), 0)
|
||||
}()
|
||||
rd := bufio.NewScanner(client)
|
||||
for rd.Scan() {
|
||||
writeDebug(fmt.Sprintf("GPSd Client received message: %v\n", rd.Text()), 0)
|
||||
}
|
||||
}()
|
||||
writeDebug(fmt.Sprintf("gpsd: starting conversation with %v\n", client.RemoteAddr()), 0)
|
||||
rd := bufio.NewReader(client)
|
||||
for {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
// looks like gpsd does not expect \n terminated lines so read what is there from the socket
|
||||
client.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
|
||||
if true {
|
||||
|
||||
} else {
|
||||
_, err := client.Write([]byte("{\"class\":\"VERSION\",\"release\":\"3.25\",\"rev\":\"3.25\",\"proto_major\":3,\"proto_minor\":15}\n"))
|
||||
if err != nil {
|
||||
writeDebug(fmt.Sprintf("Error writing to client: %v\n", err), 1)
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
client.Close()
|
||||
removeClient(client)
|
||||
writeDebug(fmt.Sprintf("GPSd Client disconnected: %v\n", client.RemoteAddr()), 0)
|
||||
}()
|
||||
writeDebug(fmt.Sprintf("gpsd: starting conversation with %v\n", client.RemoteAddr()), 0)
|
||||
rd := bufio.NewReader(client)
|
||||
for {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
// looks like gpsd does not expect \n terminated lines so read what is there from the socket
|
||||
client.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
|
||||
buff := make([]byte, 1024)
|
||||
n, err := rd.Read(buff)
|
||||
if isNetConnClosedErr(err) {
|
||||
@@ -197,9 +210,8 @@ func addClient(client net.Conn) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
}()
|
||||
}
|
||||
// register the client, so it gets updates from now on
|
||||
clientMutex.Lock()
|
||||
clients[client] = struct{}{}
|
||||
@@ -224,65 +236,76 @@ func publishTPV() {
|
||||
|
||||
func readAndBroadcast() {
|
||||
device := s.DeviceType
|
||||
for {
|
||||
nmeaSentence, err := s.GPSStream.DequeueOrWait()
|
||||
if err != nil {
|
||||
writeDebug(fmt.Sprintf("Error dequeuing GPS sentence: %v\n", err), 0)
|
||||
continue
|
||||
if s.NMEAPassthrough {
|
||||
for {
|
||||
nmeaSentence, err := s.GPSStream.DequeueOrWait()
|
||||
if err != nil {
|
||||
writeDebug(fmt.Sprintf("Error dequeuing GPS sentence: %v\n", err), 0)
|
||||
continue
|
||||
}
|
||||
broadcastToClients(nmeaSentence)
|
||||
}
|
||||
writeDebug(fmt.Sprintf("gpsd: received NMEA: %s", nmeaSentence), 1)
|
||||
//broadcastToClients(string(nmeaSentence) + "\n")
|
||||
|
||||
// NMEA-Satz parsen
|
||||
sentence, err := nmea.Parse(nmeaSentence)
|
||||
if err != nil {
|
||||
writeDebug(fmt.Sprintf("gpsd: error parsing NMEA sentence '%s': %v", nmeaSentence, err), 1)
|
||||
continue
|
||||
}
|
||||
|
||||
switch s := sentence.(type) {
|
||||
|
||||
// RMC (Mindestdaten: Zeit, Position, Kurs, Geschwindigkeit)
|
||||
case nmea.RMC:
|
||||
updateTPVFromRMC(s, device)
|
||||
|
||||
// GGA (Positions- und Höheninformation)
|
||||
case nmea.GGA:
|
||||
updateTPVFromGGA(s, device)
|
||||
|
||||
// VTG: Aktualisierung von Kurs und Geschwindigkeit.
|
||||
case nmea.VTG:
|
||||
updateTPVFromVTG(s)
|
||||
|
||||
// GSV (Satelliten in Sicht)
|
||||
case nmea.GSV:
|
||||
sats := make([]SatelliteInfo, 0, len(s.Info))
|
||||
for _, sat := range s.Info {
|
||||
sats = append(sats, SatelliteInfo{
|
||||
PRN: int(sat.SVPRNNumber),
|
||||
Elevation: int(sat.Elevation),
|
||||
Azimuth: int(sat.Azimuth),
|
||||
SNR: int(sat.SNR),
|
||||
})
|
||||
} else {
|
||||
for {
|
||||
nmeaSentence, err := s.GPSStream.DequeueOrWait()
|
||||
if err != nil {
|
||||
writeDebug(fmt.Sprintf("Error dequeuing GPS sentence: %v\n", err), 0)
|
||||
continue
|
||||
}
|
||||
sky := SKY{
|
||||
Class: "SKY",
|
||||
Device: device,
|
||||
Satellites: sats,
|
||||
}
|
||||
if jsonOut, err := json.Marshal(sky); err == nil {
|
||||
broadcastToClients(string(jsonOut))
|
||||
//fmt.Println(string(jsonOut))
|
||||
} else {
|
||||
writeDebug(fmt.Sprintf("gpsd: error serializing SKY object: %v", err), 1)
|
||||
writeDebug(fmt.Sprintf("gpsd: received NMEA: %s", nmeaSentence), 1)
|
||||
//broadcastToClients(string(nmeaSentence) + "\n")
|
||||
|
||||
// NMEA-Satz parsen
|
||||
sentence, err := nmea.Parse(nmeaSentence)
|
||||
if err != nil {
|
||||
writeDebug(fmt.Sprintf("gpsd: error parsing NMEA sentence '%s': %v", nmeaSentence, err), 1)
|
||||
continue
|
||||
}
|
||||
|
||||
// GSA (z.B. GPGSA oder auch ohne Talker-ID)
|
||||
case nmea.GSA:
|
||||
updateTPVFromGSA(s)
|
||||
switch s := sentence.(type) {
|
||||
|
||||
default:
|
||||
writeDebug(fmt.Sprintf("unsupported NMEA type: %T", s), 1)
|
||||
// RMC (Mindestdaten: Zeit, Position, Kurs, Geschwindigkeit)
|
||||
case nmea.RMC:
|
||||
updateTPVFromRMC(s, device)
|
||||
|
||||
// GGA (Positions- und Höheninformation)
|
||||
case nmea.GGA:
|
||||
updateTPVFromGGA(s, device)
|
||||
|
||||
// VTG: Aktualisierung von Kurs und Geschwindigkeit.
|
||||
case nmea.VTG:
|
||||
updateTPVFromVTG(s)
|
||||
|
||||
// GSV (Satelliten in Sicht)
|
||||
case nmea.GSV:
|
||||
sats := make([]SatelliteInfo, 0, len(s.Info))
|
||||
for _, sat := range s.Info {
|
||||
sats = append(sats, SatelliteInfo{
|
||||
PRN: int(sat.SVPRNNumber),
|
||||
Elevation: int(sat.Elevation),
|
||||
Azimuth: int(sat.Azimuth),
|
||||
SNR: int(sat.SNR),
|
||||
})
|
||||
}
|
||||
sky := SKY{
|
||||
Class: "SKY",
|
||||
Device: device,
|
||||
Satellites: sats,
|
||||
}
|
||||
if jsonOut, err := json.Marshal(sky); err == nil {
|
||||
broadcastToClients(string(jsonOut))
|
||||
//fmt.Println(string(jsonOut))
|
||||
} else {
|
||||
writeDebug(fmt.Sprintf("gpsd: error serializing SKY object: %v", err), 1)
|
||||
}
|
||||
|
||||
// GSA (z.B. GPGSA oder auch ohne Talker-ID)
|
||||
case nmea.GSA:
|
||||
updateTPVFromGSA(s)
|
||||
|
||||
default:
|
||||
writeDebug(fmt.Sprintf("unsupported NMEA type: %T", s), 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user