summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rhctl/audio_switch.go116
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
}