Add automatic serialout when /dev/serialout0 is present.

/dev/serialout0 created by either inserting a CP2102-based
USB-to-Serial dongle or by symlink.
pull/490/head
Christopher Young 2016-09-19 12:21:39 -04:00
rodzic 85d73964c7
commit 30fe7295c4
5 zmienionych plików z 113 dodań i 1 usunięć

Wyświetl plik

@ -959,6 +959,7 @@ type settings struct {
Ping_Enabled bool
GPS_Enabled bool
NetworkOutputs []networkConnection
SerialOutputs map[string]serialConnection
AHRS_Enabled bool
DisplayTrafficSource bool
DEBUG bool

Wyświetl plik

@ -232,6 +232,22 @@ func handleSettingsSetRequest(w http.ResponseWriter, r *http.Request) {
}
case "PPM":
globalSettings.PPM = int(val.(float64))
case "Baud":
if serialOut, ok := globalSettings.SerialOutputs["/dev/serialout0"]; ok { //FIXME: Only one device for now.
newBaud := int(val.(float64))
if newBaud == serialOut.Baud { // Same baud rate. No change.
continue
}
log.Printf("changing /dev/serialout0 baud rate from %d to %d.\n", serialOut.Baud, newBaud)
serialOut.Baud = newBaud
// Close the port if it is open.
if serialOut.serialPort != nil {
log.Printf("closing /dev/serialout0 for baud rate change.\n")
serialOut.serialPort.Close()
serialOut.serialPort = nil
}
globalSettings.SerialOutputs["/dev/serialout0"] = serialOut
}
case "WatchList":
globalSettings.WatchList = val.(string)
case "OwnshipModeS":

Wyświetl plik

@ -11,6 +11,7 @@ package main
import (
"errors"
"github.com/tarm/serial"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
"io/ioutil"
@ -50,6 +51,12 @@ type networkConnection struct {
FFCrippled bool
}
type serialConnection struct {
DeviceString string
Baud int
serialPort *serial.Port
}
var messageQueue chan networkMessage
var outSockets map[string]networkConnection
var dhcpLeases map[string]string
@ -113,6 +120,11 @@ func isThrottled(k string) bool {
}
func sendToAllConnectedClients(msg networkMessage) {
if (msg.msgType & NETWORK_GDL90_STANDARD) != 0 {
// It's a GDL90 message. Send to serial output channel (which may or may not cause something to happen).
serialOutputChan <- msg.msg
}
netMutex.Lock()
defer netMutex.Unlock()
for k, netconn := range outSockets {
@ -159,6 +171,65 @@ func sendToAllConnectedClients(msg networkMessage) {
}
}
var serialOutputChan chan []byte
// Monitor serial output channel, send to serial port.
func serialOutWatcher() {
// Check every 30 seconds for a serial output device.
serialTicker := time.NewTicker(30 * time.Second)
serialDev := "/dev/serialout0" //FIXME: This is temporary. Only one serial output device for now.
for {
select {
case <-serialTicker.C:
if _, err := os.Stat(serialDev); !os.IsNotExist(err) { // Check if the device file exists.
var thisSerialConn serialConnection
// Check if we need to start handling a new device.
if val, ok := globalSettings.SerialOutputs[serialDev]; !ok {
newSerialOut := serialConnection{DeviceString: serialDev, Baud: 38400}
log.Printf("detected new serial output, setting up now: %s. Default baudrate 38400.\n", serialDev)
if globalSettings.SerialOutputs == nil {
globalSettings.SerialOutputs = make(map[string]serialConnection)
}
globalSettings.SerialOutputs[serialDev] = newSerialOut
saveSettings()
thisSerialConn = newSerialOut
} else {
thisSerialConn = val
}
// Check if we need to open the connection now.
if thisSerialConn.serialPort == nil {
cfg := &serial.Config{Name: thisSerialConn.DeviceString, Baud: thisSerialConn.Baud}
p, err := serial.OpenPort(cfg)
if err != nil {
log.Printf("serialout port (%s) err: %s\n", thisSerialConn.DeviceString, err.Error())
break // We'll attempt again in 30 seconds.
} else {
log.Printf("opened serialout: Name: %s, Baud: %d\n", thisSerialConn.DeviceString, thisSerialConn.Baud)
}
// Save the serial port connection.
thisSerialConn.serialPort = p
globalSettings.SerialOutputs[serialDev] = thisSerialConn
}
}
case b := <-serialOutputChan:
if val, ok := globalSettings.SerialOutputs[serialDev]; ok {
if val.serialPort != nil {
_, err := val.serialPort.Write(b)
if err != nil { // Encountered an error in writing to the serial port. Close it and set Serial_out_enabled.
log.Printf("serialout (%s) port err: %s. Closing port.\n", val.DeviceString, err.Error())
val.serialPort.Close()
val.serialPort = nil
globalSettings.SerialOutputs[serialDev] = val
}
}
}
}
}
}
// Returns the number of DHCP leases and prints queue lengths.
func getNetworkStats() {
@ -511,6 +582,7 @@ func ffMonitor() {
func initNetwork() {
messageQueue = make(chan networkMessage, 1024) // Buffered channel, 1024 messages.
serialOutputChan = make(chan []byte, 1024) // Buffered channel, 1024 GDL90 messages.
outSockets = make(map[string]networkConnection)
pingResponse = make(map[string]time.Time)
netMutex = &sync.Mutex{}
@ -519,4 +591,5 @@ func initNetwork() {
go messageQueueSender()
go sleepMonitor()
go networkStatsCounter()
go serialOutWatcher()
}

Wyświetl plik

@ -17,6 +17,9 @@ function SettingsCtrl($rootScope, $scope, $state, $location, $window, $http) {
settings = angular.fromJson(data);
// consider using angular.extend()
$scope.rawSettings = angular.toJson(data, true);
if ((settings.SerialOutputs !== undefined) && (settings.SerialOutputs !== null) && (settings.SerialOutputs['/dev/serialout0'] !== undefined)) {
$scope.Baud = settings.SerialOutputs['/dev/serialout0'].Baud;
}
$scope.UAT_Enabled = settings.UAT_Enabled;
$scope.ES_Enabled = settings.ES_Enabled;
$scope.Ping_Enabled = settings.Ping_Enabled;
@ -91,6 +94,18 @@ function SettingsCtrl($rootScope, $scope, $state, $location, $window, $http) {
}
};
$scope.updateBaud = function () {
settings["Baud"] = 0
if (($scope.Baud !== undefined) && ($scope.Baud !== null) && ($scope.Baud !== settings["Baud"])) {
settings["Baud"] = parseInt($scope.Baud);
newsettings = {
"Baud": settings["Baud"]
};
// console.log(angular.toJson(newsettings));
setSettings(angular.toJson(newsettings));
}
};
$scope.updatewatchlist = function () {
if ($scope.WatchList !== settings["WatchList"]) {
settings["WatchList"] = "";
@ -180,4 +195,4 @@ function SettingsCtrl($rootScope, $scope, $state, $location, $window, $http) {
});
};
};
};

Wyświetl plik

@ -92,6 +92,13 @@
<input class="col-xs-7" type="number_format" required ng-model="PPM" placeholder="integer" ng-blur="updateppm()" />
</form>
</div>
<div class="form-group reset-flow">
<label class="control-label col-xs-5">Serial Output Baudrate</label>
<form name="ppmForm" ng-submit="updateBaud()" novalidate>
<!-- type="number" not supported except on mobile -->
<input class="col-xs-7" type="number_format" required ng-model="Baud" placeholder="integer" ng-blur="updateBaud()" />
</form>
</div>
</div>
</div>
</div>