From 7cfc7644c284b72997eb3b31b98fab447fe06bed Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sat, 26 Mar 2016 18:24:42 +0100 Subject: added config file parser improved baudrate handling diff --git a/Makefile b/Makefile index 2b06bd5..0ac1f91 100644 --- a/Makefile +++ b/Makefile @@ -24,8 +24,8 @@ GOCMD := GOPATH=$(curdir) go EXECUTEABLE := rhctl -LIBS := "github.com/schleibinger/sio" - +LIBS := "github.com/schleibinger/sio" \ + "github.com/naoina/toml" .PHONY: getlibs updatelibs vet format build clean distclean all: build diff --git a/sample-config.toml b/sample-config.toml new file mode 100644 index 0000000..9afeff2 --- /dev/null +++ b/sample-config.toml @@ -0,0 +1,22 @@ +[audioswitch] +dev = "/dev/ttyUSB0" +baud = 9600 + +[servers] + + [servers.master] + ctrl_dev = "/dev/ttyUSB1" + ctrl_baud = 38400 + heartbeat_dev = "/dev/ttyUSB2" + heartbeat_baud = 19200 + + [servers.standby] + ctrl_dev = "/dev/ttyUSB3" + ctrl_baud = 38400 + heartbeat_dev = "/dev/ttyUSB4" + heartbeat_baud = 19200 + +[clients] + + [clients.web] + addr = ":4080" diff --git a/src/rhctl/conf.go b/src/rhctl/conf.go new file mode 100644 index 0000000..fda09a6 --- /dev/null +++ b/src/rhctl/conf.go @@ -0,0 +1,64 @@ +// +// rhctl +// +// Copyright (C) 2009-2016 Christian Pointner +// +// 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 . +// + +package main + +import ( + "os" + + "github.com/naoina/toml" +) + +type Config struct { + Audioswitch struct { + Device string `toml:"dev"` + Baudrate Baudrate `toml:"baud"` + } + + Servers map[string]struct { + ControlDevice string `toml:"ctrl_dev"` + ControlBaud Baudrate `toml:"ctrl_baud"` + HeartbeatDev string `toml:"heartbeat_dev"` + HeartbeatBaud Baudrate `toml:"heartbeat_baud"` + } + + Clients struct { + Web struct { + Addr string `toml:"addr"` + } + } +} + +func ReadConfig(configfile string) (conf *Config, err error) { + conf = &Config{} + + var f *os.File + if f, err = os.Open(configfile); err != nil { + return + } + defer f.Close() + + decoder := toml.NewDecoder(f) + if err = decoder.Decode(conf); err != nil { + return + } + return +} diff --git a/src/rhctl/main.go b/src/rhctl/main.go index f6742d8..14a86bc 100644 --- a/src/rhctl/main.go +++ b/src/rhctl/main.go @@ -27,7 +27,6 @@ import ( "io/ioutil" "log" "os" - "time" ) var ( @@ -61,8 +60,8 @@ func (s *envStringValue) Get() interface{} { return string(*s) } func (s *envStringValue) String() string { return fmt.Sprintf("%s", *s) } func main() { - webAddr := newEnvStringValue("RHCTL_WEB_ADDR", "localhost:4080") - flag.Var(webAddr, "web-addr", "addr:port to listen on (environment: RHCTL_WEB_ADDR)") + configFile := newEnvStringValue("RHCTL_CONFIG_FILE", "/etc/rhctl/config.toml") + flag.Var(configFile, "conf", "path to the configuration file (environment: RHCTL_CONFIG_FILE)") help := flag.Bool("help", false, "show usage") flag.Parse() @@ -71,37 +70,34 @@ func main() { return } - if webAddr.Get().(string) != "" { - go func() { - rhl.Println("starting web-api:", webAddr.Get().(string)) - for { - time.Sleep(time.Second) - } - //StartWeb(webAddr.Get().(string)) - rhl.Println("web-api finished") - }() - } - - sw, err := SwitchInit("/dev/ttyUSB0", B9600) - if err != nil { - rhl.Println("error audio switch: ", err) - return - } - - master, err := ServerInit("master", "/dev/ttyUSB1", "/dev/ttyUSB2", B38400) - if err != nil { - rhl.Println("error master server: ", err) - return - } - - standby, err := ServerInit("standby", "/dev/ttyUSB3", "/dev/ttyUSB4", B38400) + conf, err := ReadConfig(configFile.Get().(string)) if err != nil { - rhl.Println("error standby server: ", err) + rhl.Println("Error reading configuration:", err.Error()) return } - sw.Run() - master.Run() - standby.Run() - time.Sleep(time.Second) + rhdl.Printf("config: %+v", conf) + + // sw, err := SwitchInit("/dev/ttyUSB0", B9600) + // if err != nil { + // rhl.Println("error audio switch: ", err) + // return + // } + + // master, err := ServerInit("master", "/dev/ttyUSB1", "/dev/ttyUSB2", B38400) + // if err != nil { + // rhl.Println("error master server: ", err) + // return + // } + + // standby, err := ServerInit("standby", "/dev/ttyUSB3", "/dev/ttyUSB4", B38400) + // if err != nil { + // rhl.Println("error standby server: ", err) + // return + // } + + // sw.Run() + // master.Run() + // standby.Run() + // time.Sleep(time.Second) } diff --git a/src/rhctl/serial_port.go b/src/rhctl/serial_port.go index 9f3f3f6..c7804a6 100644 --- a/src/rhctl/serial_port.go +++ b/src/rhctl/serial_port.go @@ -23,23 +23,108 @@ package main import ( "bufio" + "errors" + "strconv" "syscall" "github.com/schleibinger/sio" ) -type Baudrate uint32 +type Baudrate struct { + value uint32 + code uint32 +} -const ( - B1200 Baudrate = syscall.B1200 - B2400 = syscall.B2400 - B4800 = syscall.B4800 - B9600 = syscall.B9600 - B19200 = syscall.B19200 - B38400 = syscall.B38400 - B57600 = syscall.B57600 - B115200 = syscall.B115200 -) +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) 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) UnmarshalTOML(data []byte) error { + return b.FromString(string(data)) +} type SerialPort struct { port *sio.Port @@ -69,9 +154,9 @@ func serialWriter(c <-chan string, port *sio.Port, newline string) { port.Close() } -func SerialOpenAndHandle(device string, speed Baudrate, newline string) (port *SerialPort, err error) { +func SerialOpenAndHandle(device string, rate Baudrate, newline string) (port *SerialPort, err error) { port = &SerialPort{} - if port.port, err = sio.Open(device, uint32(speed)); err != nil { + if port.port, err = sio.Open(device, rate.code); err != nil { return } tx := make(chan string, 10) -- cgit v0.10.2