From 5f6f582835748fcc15616c11eaa76bac358e9fc2 Mon Sep 17 00:00:00 2001 From: Bernhard Tittelbach Date: Tue, 24 Sep 2013 13:37:51 +0000 Subject: [PATCH] better go, but still needs alternative to go-zmq --- go/door_daemon_zmq/handle_commands.go | 12 ++++----- go/door_daemon_zmq/main.go | 44 ++++++++++++++++++++++----------- go/door_daemon_zmq/serial_tty.go | 39 ++++++----------------------- 3 files changed, 41 insertions(+), 54 deletions(-) diff --git a/go/door_daemon_zmq/handle_commands.go b/go/door_daemon_zmq/handle_commands.go index 5e5d6e1..35c3b02 100644 --- a/go/door_daemon_zmq/handle_commands.go +++ b/go/door_daemon_zmq/handle_commands.go @@ -46,23 +46,21 @@ func checkCmdStatus(tokens [][]byte) (error) { 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 } diff --git a/go/door_daemon_zmq/main.go b/go/door_daemon_zmq/main.go index 52e8197..d943d8d 100644 --- a/go/door_daemon_zmq/main.go +++ b/go/door_daemon_zmq/main.go @@ -49,7 +49,7 @@ func main() { 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) @@ -58,19 +58,33 @@ func main() { //~ 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") + } + } } } diff --git a/go/door_daemon_zmq/serial_tty.go b/go/door_daemon_zmq/serial_tty.go index ddd41e6..d7fd7a9 100644 --- a/go/door_daemon_zmq/serial_tty.go +++ b/go/door_daemon_zmq/serial_tty.go @@ -9,7 +9,6 @@ import ( "os" "svn.spreadspace.org/realraum/go.svn/termios" "log" - "sync" ) // ---------- Serial TTY Code ------------- @@ -32,53 +31,29 @@ func serialWriter(in <- chan string, serial * os.File) { } } -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 } -- 1.7.10.4