From fa5cf2acaacf73e4848f1f29d235e681a495e9f5 Mon Sep 17 00:00:00 2001 From: Othmar Gsenger Date: Mon, 11 Mar 2013 23:02:26 +0000 Subject: [PATCH] new features for door daemon --- door_daemon_go/run.sh | 2 +- door_daemon_go/src/termios/termios.go | 121 +++++++++++++++++++++++++++++++++ door_daemon_go/unix_socket_server.go | 79 +++++++++++++++++---- 3 files changed, 189 insertions(+), 13 deletions(-) create mode 100644 door_daemon_go/src/termios/termios.go diff --git a/door_daemon_go/run.sh b/door_daemon_go/run.sh index 0f91b48..42b55c5 100755 --- a/door_daemon_go/run.sh +++ b/door_daemon_go/run.sh @@ -1,4 +1,4 @@ #!/bin/sh clear rm /tmp/test.sock 2>/dev/null -go build unix_socket_server.go && ./unix_socket_server || sleep 5 +go build unix_socket_server.go && ./unix_socket_server /dev/ttyACM0 || sleep 5 diff --git a/door_daemon_go/src/termios/termios.go b/door_daemon_go/src/termios/termios.go new file mode 100644 index 0000000..cc953cb --- /dev/null +++ b/door_daemon_go/src/termios/termios.go @@ -0,0 +1,121 @@ +package termios + +import ( + "fmt"; + "os"; + "syscall"; + "unsafe" + "errors" +) + +// termios types +type cc_t byte +type speed_t uint +type tcflag_t uint + +// termios constants +const ( + BRKINT = tcflag_t (0000002); + ICRNL = tcflag_t (0000400); + INPCK = tcflag_t (0000020); + ISTRIP = tcflag_t (0000040); + IXON = tcflag_t (0002000); + OPOST = tcflag_t (0000001); + CS8 = tcflag_t (0000060); + ECHO = tcflag_t (0000010); + ICANON = tcflag_t (0000002); + IEXTEN = tcflag_t (0100000); + ISIG = tcflag_t (0000001); + VTIME = tcflag_t (5); + VMIN = tcflag_t (6) +) + +const NCCS = 32 +type termios struct { + c_iflag, c_oflag, c_cflag, c_lflag tcflag_t; + c_line cc_t; + c_cc [NCCS]cc_t; + c_ispeed, c_ospeed speed_t +} + +// ioctl constants +const ( + TCGETS = 0x5401; + TCSETS = 0x5402 +) + +var ( + orig_termios termios; + ttyfd uintptr = 0 // STDIN_FILENO +) + +func Ttyfd(fd uintptr) { + ttyfd=fd +} + +func getTermios (dst *termios) error { + r1, _, errno := syscall.Syscall (syscall.SYS_IOCTL, + uintptr (ttyfd), uintptr (TCGETS), + uintptr (unsafe.Pointer (dst))); + + if err := os.NewSyscallError ("SYS_IOCTL", errno); err != nil { + return err + } + + if r1 != 0 { + return errors.New("Error") + } + + return nil +} + +func setTermios (src *termios) error { + r1, _, errno := syscall.Syscall (syscall.SYS_IOCTL, + uintptr (ttyfd), uintptr (TCSETS), + uintptr (unsafe.Pointer (src))); + + if err := os.NewSyscallError ("SYS_IOCTL", errno); err != nil { + return err + } + + if r1 != 0 { + return errors.New ("Error") + } + + return nil +} + +func tty_raw () error { + raw := orig_termios; + + raw.c_iflag &= ^(BRKINT | ICRNL | INPCK | ISTRIP | IXON); + raw.c_oflag &= ^(OPOST); + raw.c_cflag |= (CS8); + raw.c_lflag &= ^(ECHO | ICANON | IEXTEN | ISIG); + + raw.c_cc[VMIN] = 1; + raw.c_cc[VTIME] = 0; + + if err := setTermios (&raw); err != nil { return err } + + return nil +} + +func SetRaw () { + var ( + err error + ) + + defer func () { + if err != nil { fmt.Println (err) } + } (); + + if err = getTermios (&orig_termios); err != nil { return } + +// defer func () { +// err = setTermios (&orig_termios) +// } (); + + if err = tty_raw (); err != nil { return } + //if err = screenio (); err != nil { return } +} diff --git a/door_daemon_go/unix_socket_server.go b/door_daemon_go/unix_socket_server.go index 886cf11..14b9226 100644 --- a/door_daemon_go/unix_socket_server.go +++ b/door_daemon_go/unix_socket_server.go @@ -5,6 +5,8 @@ import "bufio" import "strings" import "os" import "io" +import "termios" +import "flag" var cmdHandler = map[string]func([]string,string,*bufio.ReadWriter ) { "test":handleCmdTest, @@ -14,7 +16,7 @@ var cmdHandler = map[string]func([]string,string,*bufio.ReadWriter ) { } -func readLineSafe(rw *bufio.ReadWriter) (string, error) { +func readLineSafe(rw *bufio.Reader) (string, error) { wasPrefix:=false var line string for isPrefix:=true;isPrefix; { @@ -32,16 +34,16 @@ func readLineSafe(rw *bufio.ReadWriter) (string, error) { } if wasPrefix { fmt.Println("line too long") - fmt.Fprintf(rw,"line too long\n") - rw.Flush() + //fmt.Fprintf(rw,"line too long\n") + //rw.Flush() return "",nil } return line,nil } func connToReadWriter(c io.Reader,cw io.Writer) (*bufio.ReadWriter) { - client_r := bufio.NewReaderSize(c,14) - client_w := bufio.NewWriterSize(cw,14) + client_r := bufio.NewReaderSize(c,1024) + client_w := bufio.NewWriterSize(cw,1024) return bufio.NewReadWriter(client_r,client_w) } @@ -49,7 +51,7 @@ func handleConnection(c net.Conn) () { client:=connToReadWriter(c,c) fmt.Println("new connection") for { - line,err:=readLineSafe(client) + line,err:=readLineSafe(bufio.NewReader(client)) if err != nil { if err.Error() != "EOF" { fmt.Printf("Error: readLineSafe returned %v\n",err.Error()) @@ -93,29 +95,82 @@ func handleCmdController(tokens []string, remainStr string, client * bufio.ReadW } -func openTTY(name string) *bufio.ReadWriter{ +func openTTY(name string) *os.File { file, err := os.OpenFile(name,os.O_RDWR ,0600) // For read access. if err != nil { fmt.Println(err.Error()) } - return connToReadWriter(file,file) + termios.Ttyfd(file.Fd()) + termios.SetRaw() + return file +} +func usage() { + fmt.Fprintf(os.Stderr, "usage: myprog [inputfile]\n") + flag.PrintDefaults() + os.Exit(2) +} + +func SerialWriter(c chan string, serial * os.File ) { + for { + serial.WriteString(<-c) + serial.Sync() + } +} + +func SerialReader(c chan string , serial * bufio.Reader) { + for { + s,err := readLineSafe(serial) + if (s=="") { + continue + } + if (err!=nil) { + fmt.Printf("Error in read from serial: %v\n",err.Error()) + os.Exit(1) + } + fmt.Printf("Serial: Read %v\n",s); + c<-s + } +} + +func openSerial(filename string) (chan string,chan string) { + serial:=openTTY(filename) + in:=make(chan string) + out:=make(chan string) + //go SerialWriter(out,serial) + go SerialReader(in,bufio.NewReaderSize(serial,128)) + return in,out } +func SerialHandler(serial_i chan string) { + for { + fmt.Printf("Serial said: %v\n",<-serial_i); + } +} func main() { - serial:=openTTY("tty") - serial.WriteString("foo") - serial.Flush() + flag.Usage = usage + flag.Parse() + + args := flag.Args() + if len(args) < 1 { + fmt.Println("Input file is missing."); + os.Exit(1); + } ln, err := net.Listen("unix", "/tmp/test.sock") if err != nil { fmt.Printf("Error: %s\n",err.Error()) return } fmt.Printf("Listener started\n") + + serial_i,serial_o:=openSerial(args[0]) + go SerialHandler(serial_i) + serial_o<-"f" + for { conn, err := ln.Accept() if err != nil { // handle error - continue + continue } go handleConnection(conn) } -- 1.7.10.4