NMEA pass-through mode

This commit is contained in:
Torsten Harenberg
2025-02-21 14:25:36 +01:00
parent 80f55af864
commit 89c19cf9b8
3 changed files with 152 additions and 103 deletions

View File

@@ -42,14 +42,21 @@ cmdline_init: ""
vara_mode: false
```
Next time ptb will start using the settings in your config file.
## Settings
The meaning of the vables in the config file are as follows:
| Variable | Meaning |
|-------------------|-----------------------------------------------------------------------------------------------------------------------------|
|-------------------|----------------------------------------------------------------------------------------------------------------|
| `device` | Path to the serial device where the modem is connected **or** `tcp://address:port` (useful for Android) |
| `baudrate` | baud rate of the modem |
| `mycall` | The callsign to be used on HF |
| `server_address` | server socket address for the **commands** |
| `data_address` | server socket address for the **data** |
| `gpsd_address` | **optional** See the chapter about GPS below |
| `nmeapassthrough` | **only when gpsd_address has been set** bool value: if true pass NMEA data trough instead of interpreting them |
| `cmdline_init` | extra commands sent to the modem before going into hostmode, separated by semicolons, Ex: `DISP BR 1;DISP A 1;DISP DIMMOFF` |
| `vara_mode` | see the chapter about the VARA mode |
@@ -97,7 +104,9 @@ to make your position visible to Pat (or any other gpsd client).
To configure it you just need to add a line like
`gpsd_address: 0.0.0.0:2947`
```yaml
gpsd_address: 0.0.0.0:2947`
```
to the config file. In Pat, a possible counterpart could look like this:
@@ -110,6 +119,19 @@ to the config file. In Pat, a possible counterpart could look like this:
},
```
### NMEA Pass-Through
If you need the **raw** NMEA data (for example if your GPS is not supported by the built-in mini-gpsd, or you want to
run your own gpsd), set `nmeapassthough` to `true`, for example:
```yaml
gpsd_address: 0.0.0.0:8888
nmeapassthough: true
```
Note that if you plan to use Pat, you'd need to run `gpsd` to use
the position of the GNSS receiver.
## How to run
As a rule of thumb, you have to start the PACTOR-TCP-bridge before you want to use

29
gpsd.go
View File

@@ -130,6 +130,20 @@ func isNetConnClosedErr(err error) bool {
}
func addClient(client net.Conn) {
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)
}
}()
} 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)
@@ -147,7 +161,6 @@ func addClient(client net.Conn) {
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 {
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,6 +236,16 @@ func publishTPV() {
func readAndBroadcast() {
device := s.DeviceType
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)
}
} else {
for {
nmeaSentence, err := s.GPSStream.DequeueOrWait()
if err != nil {
@@ -285,6 +307,7 @@ func readAndBroadcast() {
writeDebug(fmt.Sprintf("unsupported NMEA type: %T", s), 1)
}
}
}
}
func parseTime(gpstime string) string {

View File

@@ -35,6 +35,7 @@ type TCPServer struct {
VARAMode bool
DaemonMode bool
GPSdMode bool
NMEAPassthrough bool
DeviceType string
Status uint8
Command struct {
@@ -48,7 +49,7 @@ type TCPServer struct {
GPSStream *StringFIFO // NMEA steam from PTC to gpsd server, see gpsd.go
}
func NewTCPServer(varamode bool, daemonmode bool, gpsdmode bool) *TCPServer {
func NewTCPServer(varamode bool, daemonmode bool, gpsdmode bool, nmeapassthrough bool) *TCPServer {
return &TCPServer{
Protocol: make(chan string, 1024),
ToPactor: NewByteFIFO(1024),
@@ -56,6 +57,7 @@ func NewTCPServer(varamode bool, daemonmode bool, gpsdmode bool) *TCPServer {
VARAMode: varamode,
DaemonMode: daemonmode,
GPSdMode: gpsdmode,
NMEAPassthrough: nmeapassthrough,
DeviceType: "",
Status: 0,
Command: struct {
@@ -77,6 +79,7 @@ type Userconfig struct {
ServerAddress string `yaml:"server_address"`
DataAddress string `yaml:"data_address"`
GPSdAddress string `yaml:"gpsd_address"`
NMEAPassthrough bool `yaml:"nmeapassthrough"`
CmdLineInit string `yaml:"cmdline_init"`
StartwithVaraMode bool `yaml:"vara_mode"`
}
@@ -94,6 +97,7 @@ func configmanage(Config *Userconfig, path string) error {
ServerAddress: "127.0.0.1:8300",
DataAddress: "127.0.0.1:8301",
GPSdAddress: "",
NMEAPassthrough: false,
CmdLineInit: "",
StartwithVaraMode: false}
@@ -158,7 +162,7 @@ func main() {
os.Exit(1)
}
s = NewTCPServer(Config.StartwithVaraMode, daemonMode, Config.GPSdAddress != "")
s = NewTCPServer(Config.StartwithVaraMode, daemonMode, Config.GPSdAddress != "", Config.NMEAPassthrough)
fmt.Println("Initializing PACTOR modem, please wait...")
m, err := OpenModem(Config.Device, Config.Baudrate, Config.Mycall, "", Config.CmdLineInit)
if err != nil {