diff options
author | Christian Pointner <equinox@helsinki.at> | 2016-11-17 01:51:03 (GMT) |
---|---|---|
committer | Christian Pointner <equinox@helsinki.at> | 2016-11-17 01:51:03 (GMT) |
commit | aed7e2d70f10c20e3f9bbaa046594133aa29dda1 (patch) | |
tree | 4d9a376c3feb4bac7b3778ffac881deec2d79edf | |
parent | 8f39244ad12e47121324f881b9caa651d8d7e85f (diff) |
move serial port to external package
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | src/rhctl/audio_switch.go | 12 | ||||
-rw-r--r-- | src/rhctl/conf.go | 11 | ||||
-rw-r--r-- | src/rhctl/playout_server.go | 14 | ||||
-rw-r--r-- | src/rhctl/serial_port.go | 209 |
5 files changed, 22 insertions, 225 deletions
@@ -1,3 +1,4 @@ bin/ pkg/ src/github.com +src/code.helsinki.at diff --git a/src/rhctl/audio_switch.go b/src/rhctl/audio_switch.go index f8c1cb1..27449cf 100644 --- a/src/rhctl/audio_switch.go +++ b/src/rhctl/audio_switch.go @@ -25,6 +25,8 @@ import ( "fmt" "strings" "time" + + "code.helsinki.at/goserial" ) type SwitchResult uint8 @@ -106,7 +108,7 @@ type SwitchState struct { } type AudioSwitch struct { - port *SerialPort + port *goserial.Port timeout time.Duration Inputs ConfigSwitchInputs current *SwitchCommand @@ -342,7 +344,7 @@ func (sw *AudioSwitch) Run() { } sw.current = nil sw.timer = nil - case data := <-sw.port.rx: + case data := <-sw.port.RX: sw.handleData(data) } } else { @@ -358,10 +360,10 @@ func (sw *AudioSwitch) Run() { } else { rhdl.Printf("sending '%s' to switch", c) sw.current = cmd - sw.port.tx <- c + sw.port.TX <- c sw.timer = time.NewTimer(sw.timeout) } - case data := <-sw.port.rx: + case data := <-sw.port.RX: sw.handleData(data) } } @@ -380,7 +382,7 @@ func SwitchInit(conf *Config) (sw *AudioSwitch, err error) { sw.Commands = make(chan *SwitchCommand, 16) sw.Updates = make(chan SwitchUpdate, 32) - if sw.port, err = SerialOpen(conf.Audioswitch.Device, conf.Audioswitch.Baudrate, ""); err != nil { + if sw.port, err = goserial.Open(conf.Audioswitch.Device, conf.Audioswitch.Baudrate, ""); err != nil { err = fmt.Errorf("Audioswitch: error opening serial port: %s", err) return } diff --git a/src/rhctl/conf.go b/src/rhctl/conf.go index c163b60..3edacdc 100644 --- a/src/rhctl/conf.go +++ b/src/rhctl/conf.go @@ -28,6 +28,7 @@ import ( "strings" "time" + "code.helsinki.at/goserial" "github.com/naoina/toml" ) @@ -60,17 +61,17 @@ func (p ConfigSwitchInputs) GetServerAndChannel(in SwitchInputNum) (string, stri type Config struct { Audioswitch struct { Device string `toml:"dev"` - Baudrate Baudrate `toml:"baud"` + Baudrate goserial.Baudrate `toml:"baud"` Timeout Duration `toml:"timeout"` Unit SwitchUnitID `toml:"unit"` Inputs ConfigSwitchInputs `toml:"inputs"` } Servers map[string]struct { - Device string `toml:"dev"` - Baudrate Baudrate `toml:"baud"` - HeartbeatTimeout Duration `toml:"heartbeat_timeout"` - HeartbeatThreshold uint `toml:"heartbeat_threshold"` + Device string `toml:"dev"` + Baudrate goserial.Baudrate `toml:"baud"` + HeartbeatTimeout Duration `toml:"heartbeat_timeout"` + HeartbeatThreshold uint `toml:"heartbeat_threshold"` } Timing struct { diff --git a/src/rhctl/playout_server.go b/src/rhctl/playout_server.go index b6054c6..b0cf433 100644 --- a/src/rhctl/playout_server.go +++ b/src/rhctl/playout_server.go @@ -25,6 +25,8 @@ import ( "fmt" "strings" "time" + + "code.helsinki.at/goserial" ) type ServerHealth bool @@ -61,7 +63,7 @@ type ServerState struct { type PlayoutServer struct { name string - device *SerialPort + device *goserial.Port hbtimeout time.Duration hbtimer *time.Timer hbthreshold uint @@ -90,7 +92,7 @@ func (srv *PlayoutServer) handleHeartbeat() { srv.StateChanges <- srv.state rhl.Printf("Server(%s): is back from the dead!", srv.name) if srv.state.Channel == "" { - srv.device.tx <- ServerChannelReq + srv.device.TX <- ServerChannelReq } } } @@ -145,7 +147,7 @@ func (srv *PlayoutServer) Run() { select { case <-stop: return - case data := <-srv.device.rx: + case data := <-srv.device.RX: srv.handleMessage(data) case <-srv.hbtimer.C: srv.handleHBTimeout() @@ -153,10 +155,10 @@ func (srv *PlayoutServer) Run() { if srv.state.Health == ServerDead { srv.StateChanges <- srv.state } else { - srv.device.tx <- ServerChannelReq + srv.device.TX <- ServerChannelReq } case update := <-srv.SwitchUpdates: - srv.device.tx <- update.Data + srv.device.TX <- update.Data } } } @@ -181,7 +183,7 @@ func ServerInit(name string, conf *Config) (srv *PlayoutServer, err error) { srv.UpdateRequest = make(chan bool, 8) srv.SwitchUpdates = make(chan SwitchUpdate, 32) - if srv.device, err = SerialOpen(conf.Servers[name].Device, conf.Servers[name].Baudrate, "\n"); err != nil { + if srv.device, err = goserial.Open(conf.Servers[name].Device, conf.Servers[name].Baudrate, "\n"); err != nil { err = fmt.Errorf("Server(%s): error opening serial port: %s", srv.name, err) return } diff --git a/src/rhctl/serial_port.go b/src/rhctl/serial_port.go deleted file mode 100644 index 5440f99..0000000 --- a/src/rhctl/serial_port.go +++ /dev/null @@ -1,209 +0,0 @@ -// -// rhctl -// -// Copyright (C) 2009-2016 Christian Pointner <equinox@helsinki.at> -// -// This file is part of rhctl. -// -// rhctl is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// any later version. -// -// rhctl is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with rhctl. If not, see <http://www.gnu.org/licenses/>. -// - -package main - -import ( - "bufio" - "errors" - "strconv" - "syscall" - - "github.com/schleibinger/sio" -) - -type Baudrate struct { - value uint32 - code uint32 -} - -func NewBaudrate(value uint32) (b *Baudrate, err error) { - b = &Baudrate{} - err = b.FromUint(value) - return -} - -func (b Baudrate) String() string { - return strconv.FormatUint(uint64(b.value), 10) -} - -func (b Baudrate) MarshalText() (data []byte, err error) { - data = []byte(b.String()) - return -} - -func (b Baudrate) MarshalJSON() (data []byte, err error) { - data = []byte(b.String()) - return -} - -func (b Baudrate) MarshalTOML() (data []byte, err error) { - data = []byte(b.String()) - return -} - -func (b *Baudrate) FromUint(value uint32) error { - b.value = value - switch b.value { - case 50: - b.code = syscall.B50 - case 75: - b.code = syscall.B75 - case 110: - b.code = syscall.B110 - case 134: - b.code = syscall.B134 - case 150: - b.code = syscall.B150 - case 200: - b.code = syscall.B200 - case 300: - b.code = syscall.B300 - case 600: - b.code = syscall.B600 - case 1200: - b.code = syscall.B1200 - case 1800: - b.code = syscall.B1800 - case 2400: - b.code = syscall.B2400 - case 4800: - b.code = syscall.B4800 - case 9600: - b.code = syscall.B9600 - case 19200: - b.code = syscall.B19200 - case 38400: - b.code = syscall.B38400 - case 57600: - b.code = syscall.B57600 - case 115200: - b.code = syscall.B115200 - case 230400: - b.code = syscall.B230400 - case 460800: - b.code = syscall.B460800 - case 500000: - b.code = syscall.B500000 - case 576000: - b.code = syscall.B576000 - case 921600: - b.code = syscall.B921600 - case 1000000: - b.code = syscall.B1000000 - case 1152000: - b.code = syscall.B1152000 - case 1500000: - b.code = syscall.B1500000 - case 2000000: - b.code = syscall.B2000000 - case 2500000: - b.code = syscall.B2500000 - case 3000000: - b.code = syscall.B3000000 - case 3500000: - b.code = syscall.B3500000 - case 4000000: - b.code = syscall.B4000000 - default: - return errors.New("invalid baudrate") - } - return nil -} - -func (b *Baudrate) fromString(str string) error { - vuint, err := strconv.ParseUint(str, 10, 32) - if err != nil { - return err - } - return b.FromUint(uint32(vuint)) -} - -func (b *Baudrate) UnmarshalText(data []byte) error { - return b.fromString(string(data)) -} - -func (b *Baudrate) UnmarshalJSON(data []byte) error { - return b.fromString(string(data)) -} - -func (b *Baudrate) UnmarshalTOML(data []byte) error { - return b.fromString(string(data)) -} - -type SerialPort struct { - port *sio.Port - rx <-chan string - tx chan<- string - newline string -} - -func serialReader(c chan<- string, port *sio.Port, stop chan<- bool) { - defer func() { - port.Close() - stop <- true - }() - - scanner := bufio.NewScanner(port) - scanner.Split(bufio.ScanLines) - for scanner.Scan() { - data := scanner.Text() - if len(data) == 0 { - continue - } - c <- data - } - if err := scanner.Err(); err != nil { - rhl.Printf("device(%s): read error: %s", port.LocalAddr(), err) - } else { - rhl.Printf("device(%s): closed", port.LocalAddr()) - } -} - -func serialWriter(c <-chan string, port *sio.Port, newline string, stop chan<- bool) { - defer func() { - port.Close() - stop <- true - }() - - for data := range c { - port.Write([]byte(data + newline)) - } -} - -func (port *SerialPort) Run(stop chan<- bool) (err error) { - tx := make(chan string, 10) - rx := make(chan string, 20) - go serialReader(rx, port.port, stop) - go serialWriter(tx, port.port, port.newline, stop) - - port.rx = rx - port.tx = tx - return -} - -func SerialOpen(device string, rate Baudrate, newline string) (port *SerialPort, err error) { - port = &SerialPort{newline: newline} - if port.port, err = sio.Open(device, rate.code); err != nil { - return - } - return -} |