door_nick_lookup_zmq written
[svn42.git] / go / door_daemon_zmq / main.go
1 // (c) Bernhard Tittelbach, 2013
2
3 package main
4
5 import (
6     "fmt"
7     "os"
8     "flag"
9     "time"
10     "log/syslog"
11     "log"
12 )
13
14 //~ func StringArrayToByteArray(ss []string) [][]byte {
15     //~ bb := make([][]byte, len(ss))
16     //~ for index, s := range(ss) {
17         //~ bb[index] = []byte(s)
18     //~ }
19     //~ return bb
20 //~ }
21
22 // ---------- Main Code -------------
23
24 var (
25     cmd_port_ string
26     pub_port_ string
27     door_tty_path_ string
28     use_syslog_ bool
29     syslog_ *log.Logger
30 )
31
32 func usage() {
33     fmt.Fprintf(os.Stderr, "Usage: door_daemon_0mq <door tty device>\n")
34     flag.PrintDefaults()
35 }
36
37 func init() {
38     flag.StringVar(&cmd_port_, "cmdport", "ipc:///run/tuer/door_cmd.ipc", "zmq command socket path")
39     flag.StringVar(&pub_port_, "pubport", "tcp://*:4242", "zmq public/listen socket path")
40     flag.StringVar(&door_tty_path_, "device", "/dev/door", "door tty device path")
41     flag.BoolVar(&use_syslog_, "syslog", false, "log to syslog local1 facility")
42     flag.Usage = usage
43     flag.Parse()
44 }
45
46 func main() {
47     zmqctx, cmd_chans, pub_chans := ZmqsInit(cmd_port_, pub_port_)
48     defer cmd_chans.Close()
49     defer pub_chans.Close()
50     defer zmqctx.Close()
51
52     serial_wr, serial_rd, err := OpenAndHandleSerial(door_tty_path_)
53     defer close(serial_wr)
54     if err != nil {
55         panic(err)
56     }
57
58     if use_syslog_ {
59         var logerr error
60         syslog_, logerr = syslog.NewLogger(syslog.LOG_INFO | syslog.LOG_LOCAL1, 0)
61         if logerr != nil { panic(logerr) }
62         syslog_.Print("started")
63         defer syslog_.Print("exiting")
64     }
65
66     //~ serial_wr <- "f"
67     //~ firmware_version := <- serial_rd
68     //~ log.Print("Firmware version:", firmware_version)
69     var next_incoming_serial_is_client_reply bool
70     timeout_chan := make(chan bool)
71     defer close(timeout_chan)
72     for {
73         select {
74             case incoming_ser_line, is_notclosed := <- serial_rd:
75                 if is_notclosed {
76                     //~ if syslog_ != nil { syslog_.Print(ByteArrayToString(incoming_ser_line)) }
77                     if syslog_ != nil { syslog_.Printf("%s",incoming_ser_line) }
78                     if next_incoming_serial_is_client_reply {
79                         next_incoming_serial_is_client_reply = false
80                         cmd_chans.Out() <- incoming_ser_line
81                     }
82                     pub_chans.Out() <- incoming_ser_line
83                 } else {
84                     syslog_.Print("serial device disappeared, exiting")
85                     os.Exit(1)
86                 }
87             case tv, timeout_notclosed := <- timeout_chan:
88                 if timeout_notclosed && tv && next_incoming_serial_is_client_reply {
89                         next_incoming_serial_is_client_reply = false
90                         cmd_chans.Out() <- [][]byte{[]byte("ERROR"), []byte("No reply from firmware")}
91                 }
92             case incoming_request, ic_notclosed := <- cmd_chans.In():
93                 if ! ic_notclosed {
94                     syslog_.Print("zmq socket died, exiting")
95                     os.Exit(2)
96                 }
97                 if syslog_ != nil { syslog_.Printf("%s",incoming_request) }
98                  if err := HandleCommand(incoming_request, serial_wr, serial_rd); err != nil {
99                     out_msg := [][]byte{[]byte("ERROR"), []byte(err.Error())}
100                     cmd_chans.Out() <- out_msg
101                  } else {
102                     pub_chans.Out() <- incoming_request
103                     next_incoming_serial_is_client_reply = true
104                     go func(){time.Sleep(3*time.Second); timeout_chan <- true;}()
105                  }
106         }
107     }
108 }