return nil
}
-func HandleCommand(tokens [][]byte, topub chan <- [][]byte, serial_wr chan string) ([][]byte, error){
+func HandleCommand(tokens [][]byte, serial_wr chan string, serial_rd chan [][]byte) error {
if len(tokens) < 1 {
- return nil, errors.New("No Command to handle")
+ return errors.New("No Command to handle")
}
dch, present := cmdToDoorCmdHandler[string(tokens[0])]
if ! present {
- return nil, errors.New("Unknown Command")
+ return errors.New("Unknown Command")
}
if err := dch.Checker(tokens); err != nil {
//return error to sender
- return nil, err
+ return nil
}
- topub <- tokens
serial_wr <- dch.FirmwareChar
- fw_reply := GetLastSerialLine()
- return fw_reply, nil
+ return nil
}
defer pub_chans.Close()
defer zmqctx.Close()
- serial_wr, err := OpenAndHandleSerial(args[0], pub_chans.Out())
+ serial_wr, serial_rd, err := OpenAndHandleSerial(args[0])
defer close(serial_wr)
if err != nil {
panic(err)
//~ serial_wr <- "f"
//~ firmware_version := <- serial_rd
//~ log.Print("Firmware version:", firmware_version)
-
- for incoming_request := range cmd_chans.In() {
- //~ log.Print(incoming_request)
- reply, err := HandleCommand(incoming_request, pub_chans.Out(), serial_wr)
- if err != nil {
- //~ log.Print(err)
- out_msg := [][]byte{[]byte("ERROR"), []byte(err.Error())}
- cmd_chans.Out() <- out_msg
- //~ log.Print("sent error")
- } else {
- //~ log.Print(reply)
- cmd_chans.Out() <- reply
- //~ log.Print("sent reply")
- }
+ var next_incoming_serial_is_client_reply bool
+ for {
+ select {
+ case incoming_ser_line, is_notclosed := <- serial_rd:
+ if is_notclosed {
+ if next_incoming_serial_is_client_reply {
+ next_incoming_serial_is_client_reply = false
+ cmd_chans.Out() <- incoming_ser_line
+ }
+ pub_chans.Out() <- incoming_ser_line
+ } else {
+ os.Exit(1)
+ }
+ case incoming_request, ic_notclosed := <- cmd_chans.In():
+ if ! ic_notclosed {os.Exit(2)}
+ //~ log.Print(incoming_request)
+ if err := HandleCommand(incoming_request, serial_wr, serial_rd); err != nil {
+ //~ log.Print(err)
+ out_msg := [][]byte{[]byte("ERROR"), []byte(err.Error())}
+ cmd_chans.Out() <- out_msg
+ //~ log.Print("sent error")
+ } else {
+ //~ log.Print(reply)
+ pub_chans.Out() <- incoming_request
+ next_incoming_serial_is_client_reply = true
+ //~ log.Print("sent reply")
+ }
+ }
}
}
"os"
"svn.spreadspace.org/realraum/go.svn/termios"
"log"
- "sync"
)
// ---------- Serial TTY Code -------------
}
}
-var last_read_serial_input [][]byte = [][]byte{{}}
-var last_read_mutex sync.Mutex
-
-func serialReader(topub chan <- [][]byte, serial * os.File) {
+func serialReader(out chan <- [][]byte, serial * os.File) {
linescanner := bufio.NewScanner(serial)
linescanner.Split(bufio.ScanLines)
for linescanner.Scan() {
if err := linescanner.Err(); err != nil {
panic(fmt.Sprintf("Error in read from serial: %v\n",err.Error()))
}
- fmt.Println("read text", linescanner.Text())
text := bytes.Fields([]byte(linescanner.Text()))
if len(text) == 0 {
continue
}
- //~ for len(serial_read) > 5 {
- //~ //drain channel before putting new line into it
- //~ //thus we make sure "out" only ever holds the last line
- //~ //thus the buffer never blocks and we don't need to read from out unless we need it
- //~ // BUT: don't drain the chan dry, or we might have a race condition resulting in a deadlock
- //~ <- serial_read
- //~ }
- last_read_mutex.Lock()
- last_read_serial_input = text
- fmt.Println("Put Text", text)
- last_read_mutex.Unlock()
- topub <- text
+ out <- text
}
}
-//TODO: improve this, make it work for multiple open serial devices
-func GetLastSerialLine() [][]byte {
- var last_line_pointer [][]byte
- last_read_mutex.Lock()
- last_line_pointer = last_read_serial_input
- last_read_mutex.Unlock()
- fmt.Println("Retrieve Text", last_line_pointer)
- return last_line_pointer
-}
-
-func OpenAndHandleSerial(filename string, topub chan <- [][]byte) (chan string, error) {
+func OpenAndHandleSerial(filename string) (chan string, chan [][]byte, error) {
serial, err :=openTTY(filename)
if err != nil {
- return nil, err
+ return nil, nil, err
}
wr := make(chan string)
+ rd := make(chan [][]byte, 10)
go serialWriter(wr, serial)
- go serialReader(topub, serial)
- return wr, nil
+ go serialReader(rd, serial)
+ return wr, rd, nil
}