better go, but still needs alternative to go-zmq
authorBernhard Tittelbach <xro@realraum.at>
Tue, 24 Sep 2013 13:37:51 +0000 (13:37 +0000)
committerBernhard Tittelbach <xro@realraum.at>
Tue, 24 Sep 2013 13:37:51 +0000 (13:37 +0000)
go/door_daemon_zmq/handle_commands.go
go/door_daemon_zmq/main.go
go/door_daemon_zmq/serial_tty.go

index 5e5d6e1..35c3b02 100644 (file)
@@ -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
 }
index 52e8197..d943d8d 100644 (file)
@@ -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")
+                 }
+        }
     }
 }
index ddd41e6..d7fd7a9 100644 (file)
@@ -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
 }