diff options
-rw-r--r-- | src/rhctl/audio_switch.go | 116 |
1 files changed, 107 insertions, 9 deletions
diff --git a/src/rhctl/audio_switch.go b/src/rhctl/audio_switch.go index 4464a10..537e108 100644 --- a/src/rhctl/audio_switch.go +++ b/src/rhctl/audio_switch.go @@ -23,35 +23,133 @@ package main import ( "fmt" + "time" ) +type SwitchResult uint8 + +const ( + SwitchOK SwitchResult = iota + SwitchError +) + +type SwitchResponse struct { + Result SwitchResult + Message string +} + +type SwitchCommand struct { + Cmd string + Response chan<- SwitchResponse +} + +type SwitchUpdateType uint8 + +const ( + SwitchStatus SwitchUpdateType = iota + SwitchGPI + SwitchOC + SwitchRelay + SwitchSilence +) + +type SwitchUpdate struct { + Type SwitchUpdateType + Data string +} + type AudioSwitch struct { - port *SerialPort + port *SerialPort + timeout time.Duration + current *SwitchCommand + timer *time.Timer + Commands chan *SwitchCommand + Updates chan SwitchUpdate } -func (sw *AudioSwitch) Run() { - rhdl.Printf("running audio switch") +func (sw *AudioSwitch) handleData(data string) { + if len(data) < 3 { + rhl.Printf("Warning: ignoring short line from audioswitch") + return + } + + rhdl.Printf("got data from audio switch: %q", data) + switch data[0:3] { + case "RRR": + fallthrough + case "EEE": + if sw.current != nil { + resp := SwitchResponse{Message: data} + resp.Result = SwitchError + if data[0] == 'R' { + resp.Result = SwitchOK + } + sw.current.Response <- resp + sw.current = nil + sw.timer.Stop() + sw.timer = nil + } else { + rhl.Printf("Warning: ignoring unexpected response: %q", data) + } + case "S0L": + sw.Updates <- SwitchUpdate{SwitchStatus, data} + case "S0P": + sw.Updates <- SwitchUpdate{SwitchGPI, data} + case "S0O": + sw.Updates <- SwitchUpdate{SwitchOC, data} + case "S0R": + sw.Updates <- SwitchUpdate{SwitchRelay, data} + case "S0S": + sw.Updates <- SwitchUpdate{SwitchSilence, data} + default: + rhl.Printf("Warning: ignoring invalid data from switch: %q", data) + } +} +func (sw *AudioSwitch) Run() { stop := make(chan bool) sw.port.Run(stop) + sw.current = nil + sw.timer = nil + rhdl.Printf("audioswitch handler running...") for { - select { - case <-stop: - return - case data := <-sw.port.rx: - rhl.Printf("got data from audio switch: %q", data) + if sw.current != nil { + select { + case <-stop: + return + case <-sw.timer.C: + resp := SwitchResponse{SwitchError, "EEE timeout"} + sw.current.Response <- resp + sw.current = nil + sw.timer = nil + case data := <-sw.port.rx: + sw.handleData(data) + } + } else { + select { + case <-stop: + return + case cmd := <-sw.Commands: + sw.current = cmd + sw.port.tx <- cmd.Cmd + sw.timer = time.NewTimer(sw.timeout) + case data := <-sw.port.rx: + sw.handleData(data) + } } } } func SwitchInit(conf *Config) (sw *AudioSwitch, err error) { sw = &AudioSwitch{} + sw.timeout = conf.Audioswitch.Timeout.Duration + sw.Commands = make(chan *SwitchCommand, 8) + sw.Updates = make(chan SwitchUpdate, 32) if sw.port, err = SerialOpen(conf.Audioswitch.Device, conf.Audioswitch.Baudrate, ""); err != nil { err = fmt.Errorf("Error opening switch port: %s", err) return } - return } |