/** * Open the serial port setting the baud etc. */ func openSerial() (io.ReadWriteCloser, error) { file, err := os.OpenFile( "/dev/ttyUSB0", syscall.O_RDWR|syscall.O_NOCTTY, 0600) if err != nil { return nil, err } fd := C.int(file.Fd()) if C.isatty(fd) == 0 { err := errors.New("File is not a serial port") return nil, err } var termios C.struct_termios _, err = C.tcgetattr(fd, &termios) if err != nil { return nil, err } var baud C.speed_t baud = C.B115200 _, err = C.cfsetispeed(&termios, baud) if err != nil { return nil, err } _, err = C.cfsetospeed(&termios, baud) if err != nil { return nil, err } return file, nil }
// Determines if the device is a terminal. Return an error, if any. // // int isatty(int fd); func CheckIsatty(fd int) error { exitCode, errno := C.isatty(C.int(fd)) if exitCode == 1 { return nil } return errors.New("it is not a tty: " + errno.Error()) }
// Determines if the device is a terminal. // // int isatty(int fd); func Isatty(fd int) bool { exitCode, _ := C.isatty(C.int(fd)) if exitCode == 1 { return true } return false }
func (c *Connection) getFileDescriptor() (fd C.int, err error) { fd = C.int(c.file.Fd()) if C.isatty(fd) != 1 { err = errors.New("File is not a tty") } return fd, err }
// May move to util/file? For now is here because it's the only // one used by colors. func IsTerminal(file *os.File) bool { rv, err := C.isatty(C.int(file.Fd())) if err != nil { return false } if rv != 0 { return true } return false }
func openPort(name string, c *Config) (rwc io.ReadWriteCloser, err error) { f, err := os.OpenFile(name, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0666) if err != nil { return } defer func() { if err != nil { f.Close() } }() fd := C.int(f.Fd()) if C.isatty(fd) != 1 { return nil, errors.New("File is not a tty") } var st C.struct_termios _, err = C.tcgetattr(fd, &st) if err != nil { return nil, err } var speed C.speed_t switch c.Baud { case 115200: speed = C.B115200 case 57600: speed = C.B57600 case 38400: speed = C.B38400 case 19200: speed = C.B19200 case 9600: speed = C.B9600 default: return nil, fmt.Errorf("Unknown baud rate %v", c.Baud) } _, err = C.cfsetispeed(&st, speed) if err != nil { return nil, err } _, err = C.cfsetospeed(&st, speed) if err != nil { return nil, err } // Select local mode st.c_cflag |= C.CLOCAL | C.CREAD // Select stop bits switch c.StopBits { case StopBits1: st.c_cflag &^= C.CSTOPB case StopBits2: st.c_cflag |= C.CSTOPB default: panic(c.StopBits) } // Select character size st.c_cflag &^= C.CSIZE switch c.Size { case Byte5: st.c_cflag |= C.CS5 case Byte6: st.c_cflag |= C.CS6 case Byte7: st.c_cflag |= C.CS7 case Byte8: st.c_cflag |= C.CS8 default: panic(c.Size) } // Select parity mode switch c.Parity { case ParityNone: st.c_cflag &^= C.PARENB case ParityEven: st.c_cflag |= C.PARENB st.c_cflag &^= C.PARODD case ParityOdd: st.c_cflag |= C.PARENB st.c_cflag |= C.PARODD default: panic(c.Parity) } // Select CRLF translation if c.CRLFTranslate { st.c_iflag |= C.ICRNL } else { st.c_iflag &^= C.ICRNL } // Select raw mode st.c_lflag &^= C.ICANON | C.ECHO | C.ECHOE | C.ISIG st.c_oflag &^= C.OPOST _, err = C.tcsetattr(fd, C.TCSANOW, &st) if err != nil { return nil, err } //fmt.Println("Tweaking", name) r1, _, e := syscall.Syscall(syscall.SYS_FCNTL, uintptr(f.Fd()), uintptr(syscall.F_SETFL), uintptr(0)) if e != 0 || r1 != 0 { s := fmt.Sprint("Clearing NONBLOCK syscall error:", e, r1) return nil, errors.New(s) } /* r1, _, e = syscall.Syscall(syscall.SYS_IOCTL, uintptr(f.Fd()), uintptr(0x80045402), // IOSSIOSPEED uintptr(unsafe.Pointer(&baud))); if e != 0 || r1 != 0 { s := fmt.Sprint("Baudrate syscall error:", e, r1) return nil, os.NewError(s) } */ return f, nil }
func OpenPort(name string, baud int) (rwc io.ReadWriteCloser, err error) { f, err := os.OpenFile(name, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0666) if err != nil { return } fd := C.int(f.Fd()) if C.isatty(fd) != 1 { f.Close() return nil, fmt.Errorf("[ERROR] not a tty/cu device") } var st C.struct_termios _, err = C.tcgetattr(fd, &st) if err != nil { f.Close() return nil, err } var speed C.speed_t switch baud { case 115200: speed = C.B115200 case 57600: speed = C.B57600 case 38400: speed = C.B38400 case 19200: speed = C.B19200 case 9600: speed = C.B9600 default: f.Close() return nil, fmt.Errorf("Unknown baud rate %v", baud) } _, err = C.cfsetispeed(&st, speed) if err != nil { f.Close() return nil, err } _, err = C.cfsetospeed(&st, speed) if err != nil { f.Close() return nil, err } // Select local mode st.c_cflag |= (C.CLOCAL | C.CREAD) // Select raw mode st.c_lflag &= ^C.tcflag_t(C.ICANON | C.ECHO | C.ECHOE | C.ISIG) st.c_oflag &= ^C.tcflag_t(C.OPOST) _, err = C.tcsetattr(fd, C.TCSANOW, &st) if err != nil { f.Close() return nil, err } r1, _, e := syscall.Syscall(syscall.SYS_FCNTL, uintptr(f.Fd()), uintptr(syscall.F_SETFL), uintptr(0)) if e != 0 || r1 != 0 { s := fmt.Sprint("[WARN] clearing NONBLOCK syscall error:", e, r1) f.Close() return nil, fmt.Errorf("%s", s) } return f, nil }
func isatty(fd uintptr) bool { return int(C.isatty(C.int(fd))) != 0 }
// IsTty returns true is stdin is a terminal func IsTty() bool { return int(C.isatty(C.int(os.Stdin.Fd()))) != 0 }
// isatty is a wrapper around isatty(3). // Returns true if the specified fd is associated with a tty. func isatty(fd int) bool { return C.isatty(C.int(fd)) == 1 }
func openPort(name string, baud int, spec []byte, flow []bool) (rwc io.ReadWriteCloser, err error) { port := new(serialPort) f, err := os.OpenFile(name, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0666) if err != nil { return } fd := C.int(f.Fd()) if C.isatty(fd) != 1 { f.Close() return nil, errors.New("File is not a tty") } var st C.struct_termios _, err = C.tcgetattr(fd, &st) if err != nil { f.Close() return nil, err } var speed C.speed_t switch baud { case 115200: speed = C.B115200 case 57600: speed = C.B57600 case 38400: speed = C.B38400 case 19200: speed = C.B19200 case 9600: speed = C.B9600 default: f.Close() return nil, fmt.Errorf("Unknown baud rate %v", baud) } _, err = C.cfsetispeed(&st, speed) if err != nil { f.Close() return nil, err } _, err = C.cfsetospeed(&st, speed) if err != nil { f.Close() return nil, err } // Select local mode st.c_cflag |= (C.CLOCAL | C.CREAD) // Select raw mode st.c_lflag &= ^C.tcflag_t(C.ICANON | C.ECHO | C.ECHOE | C.ISIG) st.c_oflag &= ^C.tcflag_t(C.OPOST) // Flow control if flow[RTS_FLAG] { st.c_cflag |= C.tcflag_t(C.CRTSCTS) } if flow[XON_FLAG] { st.c_cflag |= C.tcflag_t(C.IXON | C.IXOFF | C.IXANY) } // Defaults to 8N1 if nothing valid is given byteSize := spec[0] parity := spec[1] stopBits := spec[2] switch byteSize { case byte(5): st.c_cflag |= C.tcflag_t(C.CS5) break case byte(6): st.c_cflag |= C.tcflag_t(C.CS6) break case byte(7): st.c_cflag |= C.tcflag_t(C.CS7) break case byte(8): default: st.c_cflag |= C.tcflag_t(C.CS8) break } switch parity { case PARITY_EVEN: st.c_cflag |= C.tcflag_t(C.PARENB) st.c_cflag &= ^C.tcflag_t(C.PARODD) break case PARITY_ODD: st.c_cflag |= C.tcflag_t(C.PARENB) st.c_cflag |= C.tcflag_t(C.PARODD) break case PARITY_NONE: default: st.c_cflag &= ^C.tcflag_t(C.PARENB) break } switch stopBits { case byte(2): st.c_cflag |= C.tcflag_t(C.CSTOPB) break case byte(1): default: st.c_cflag &= ^C.tcflag_t(C.CSTOPB) break } st.c_cflag &= ^C.tcflag_t(C.CSIZE) _, err = C.tcsetattr(fd, C.TCSANOW, &st) if err != nil { f.Close() return nil, err } //fmt.Println("Tweaking", name) r1, _, e := syscall.Syscall(syscall.SYS_FCNTL, uintptr(f.Fd()), uintptr(syscall.F_SETFL), uintptr(0)) if e != 0 || r1 != 0 { s := fmt.Sprint("Clearing NONBLOCK syscall error:", e, r1) f.Close() return nil, errors.New(s) } /* r1, _, e = syscall.Syscall(syscall.SYS_IOCTL, uintptr(f.Fd()), uintptr(0x80045402), // IOSSIOSPEED uintptr(unsafe.Pointer(&baud))); if e != 0 || r1 != 0 { s := fmt.Sprint("Baudrate syscall error:", e, r1) f.Close() return nil, os.NewError(s) } */ port.f = f return port, nil }
func openPort(name string, baud int) (rwc io.ReadWriteCloser, err error) { f, err := os.OpenFile(name, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0666) if err != nil { return } fd := C.int(f.Fd()) if C.isatty(fd) != 1 { f.Close() return nil, errors.New("File is not a tty") } var st C.struct_termios _, err = C.tcgetattr(fd, &st) if err != nil { f.Close() return nil, err } var speed C.speed_t switch baud { case 115200: speed = C.B115200 case 57600: speed = C.B57600 case 38400: speed = C.B38400 case 19200: speed = C.B19200 case 9600: speed = C.B9600 case 4800: speed = C.B4800 case 2400: speed = C.B2400 default: f.Close() return nil, fmt.Errorf("Unknown baud rate %v", baud) } _, err = C.cfsetispeed(&st, speed) if err != nil { f.Close() return nil, err } _, err = C.cfsetospeed(&st, speed) if err != nil { f.Close() return nil, err } // Select local mode st.c_cflag |= (C.CLOCAL | C.CREAD) // Select raw mode st.c_lflag &= ^C.tcflag_t(C.ICANON | C.ECHO | C.ECHOE | C.ISIG) st.c_oflag &= ^C.tcflag_t(C.OPOST) _, err = C.tcsetattr(fd, C.TCSANOW, &st) if err != nil { f.Close() return nil, err } //fmt.Println("Tweaking", name) r1, _, e := syscall.Syscall(syscall.SYS_FCNTL, uintptr(f.Fd()), uintptr(syscall.F_SETFL), uintptr(0)) if e != 0 || r1 != 0 { s := fmt.Sprint("Clearing NONBLOCK syscall error:", e, r1) f.Close() return nil, errors.New(s) } /* r1, _, e = syscall.Syscall(syscall.SYS_IOCTL, uintptr(f.Fd()), uintptr(0x80045402), // IOSSIOSPEED uintptr(unsafe.Pointer(&baud))); if e != 0 || r1 != 0 { s := fmt.Sprint("Baudrate syscall error:", e, r1) f.Close() return nil, os.NewError(s) } */ return f, nil }
func isTerminal(file *os.File) bool { return int(C.isatty(C.int(file.Fd()))) != 0 }
func IsATTY(fd int) bool { return C.isatty(C.int(fd)) != 0 }
func openPort(name string, baud int) (rwc io.ReadWriteCloser, err error) { f, err := os.OpenFile(name, syscall.O_RDWR|syscall.O_NOCTTY, 0666) if err != nil { return } fd := C.int(f.Fd()) if C.isatty(fd) != 1 { f.Close() return nil, errors.New("File is not a tty") } var st C.struct_termios _, err = C.tcgetattr(fd, &st) if err != nil { f.Close() return nil, err } var speed C.speed_t switch baud { case 115200: speed = C.B115200 case 57600: speed = C.B57600 case 38400: speed = C.B38400 case 19200: speed = C.B19200 case 9600: speed = C.B9600 case 4800: speed = C.B4800 case 2400: speed = C.B2400 default: f.Close() return nil, fmt.Errorf("Unknown baud rate %v", baud) } _, err = C.cfsetispeed(&st, speed) if err != nil { f.Close() return nil, err } _, err = C.cfsetospeed(&st, speed) if err != nil { f.Close() return nil, err } // Select local mode st.c_cflag |= (C.CLOCAL | C.CREAD) // Select raw mode st.c_lflag &= ^C.tcflag_t(C.ICANON | C.ECHO | C.ECHOE | C.ISIG) st.c_oflag &= ^C.tcflag_t(C.OPOST) _, err = C.tcsetattr(fd, C.TCSANOW, &st) if err != nil { f.Close() return nil, err } return f, nil }
func NewLogger(clevel int) *logger { return &logger{clevel, int(C.isatty(C.int(os.Stdout.Fd()))) != 0, os.Stdout} }
func SerialChannels(name string, baud int, debug bool) (chan byte, chan byte, chan bool, chan bool, error) { var err error var serFile *os.File var chFromSerial, chToSerial chan byte var chDTRSerial, chQuitSerial chan bool serFile, err = os.OpenFile(name, os.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0666) if err == nil { fd := C.int(serFile.Fd()) var st C.struct_termios _, err = C.tcgetattr(fd, &st) if err == nil { if C.isatty(fd) != 1 { err = errors.New("Not a tty") } } var speed C.speed_t if err == nil { switch baud { case 230400: speed = C.B230400 case 115200: speed = C.B115200 case 57600: speed = C.B57600 case 19200: speed = C.B19200 case 9600: speed = C.B9600 default: err = errors.New("Invalid baud rate") } } if err == nil { _, err = C.cfsetispeed(&st, speed) if err == nil { _, err = C.cfsetospeed(&st, speed) } } if err == nil { C.cfmakeraw(&st) _, err = C.tcsetattr(fd, C.TCSANOW, &st) } if err == nil { chFromSerial = make(chan byte, 8192) chQuitFrom := make(chan bool) go func() { datain := make([]byte, 1) for q := false; q == false; { count, _ := serFile.Read(datain) for i := 0; i < count; i++ { if debug { if datain[i] == byte(0x0D) { fmt.Print("(\n)") } else { fmt.Printf("(%02X)", datain[i]) } } chFromSerial <- datain[i] } select { case q = <-chQuitFrom: default: } time.Sleep(10) } }() chToSerial = make(chan byte, 8192) chQuitTo := make(chan bool) go func() { dataout := make([]byte, 1) for q := false; q == false; { dataout[0] = <-chToSerial if debug { if dataout[0] == byte(0x0D) { fmt.Print("[\n]") } else { fmt.Printf("[%c]", dataout[0]) } } scount, serr := serFile.Write(dataout) if scount != 1 || serr != nil { fmt.Printf("SERIAL ERROR: write error [%d][%s]\n", scount, serr) } } }() chDTRSerial = make(chan bool) chQuitDTR := make(chan bool) go func() { var param uint var ep syscall.Errno for q := false; q == false; { select { case q = <-chQuitDTR: case dtr := <-chDTRSerial: param = syscall.TIOCM_DTR if dtr { _, _, ep = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TIOCMBIS, uintptr(unsafe.Pointer(¶m))) } else { _, _, ep = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TIOCMBIC, uintptr(unsafe.Pointer(¶m))) } if ep != 0 { fmt.Printf("SERIAL ERROR: DTR error [%d]\n", ep) } } } }() go func() { <-chQuitSerial serFile.Close() chQuitFrom <- true chQuitTo <- true chQuitDTR <- true }() } } return chFromSerial, chToSerial, chDTRSerial, chQuitSerial, err }
func isTerminal(file *os.File) bool { if C.isatty(C.int(file.Fd())) == 0 { return false } return true }
func openPort(name string, baud int, readTimeout time.Duration) (p *Port, err error) { f, err := os.OpenFile(name, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0666) if err != nil { return } fd := C.int(f.Fd()) if C.isatty(fd) != 1 { f.Close() return nil, errors.New("File is not a tty") } var st C.struct_termios _, err = C.tcgetattr(fd, &st) if err != nil { f.Close() return nil, err } var speed C.speed_t switch baud { case 115200: speed = C.B115200 case 57600: speed = C.B57600 case 38400: speed = C.B38400 case 19200: speed = C.B19200 case 9600: speed = C.B9600 case 4800: speed = C.B4800 case 2400: speed = C.B2400 default: f.Close() return nil, fmt.Errorf("Unknown baud rate %v", baud) } _, err = C.cfsetispeed(&st, speed) if err != nil { f.Close() return nil, err } _, err = C.cfsetospeed(&st, speed) if err != nil { f.Close() return nil, err } // Turn off break interrupts, CR->NL, Parity checks, strip, and IXON st.c_iflag &= ^C.tcflag_t(C.BRKINT | C.ICRNL | C.INPCK | C.ISTRIP | C.IXOFF | C.IXON | C.PARMRK) // Select local mode, turn off parity, set to 8 bits st.c_cflag &= ^C.tcflag_t(C.CSIZE | C.PARENB) st.c_cflag |= (C.CLOCAL | C.CREAD | C.CS8) // Select raw mode st.c_lflag &= ^C.tcflag_t(C.ICANON | C.ECHO | C.ECHOE | C.ISIG) st.c_oflag &= ^C.tcflag_t(C.OPOST) // set blocking / non-blocking read /* * http://man7.org/linux/man-pages/man3/termios.3.html * - Supports blocking read and read with timeout operations */ vmin, vtime := posixTimeoutValues(readTimeout) st.c_cc[C.VMIN] = C.cc_t(vmin) st.c_cc[C.VTIME] = C.cc_t(vtime) _, err = C.tcsetattr(fd, C.TCSANOW, &st) if err != nil { f.Close() return nil, err } //fmt.Println("Tweaking", name) r1, _, e := syscall.Syscall(syscall.SYS_FCNTL, uintptr(f.Fd()), uintptr(syscall.F_SETFL), uintptr(0)) if e != 0 || r1 != 0 { s := fmt.Sprint("Clearing NONBLOCK syscall error:", e, r1) f.Close() return nil, errors.New(s) } /* r1, _, e = syscall.Syscall(syscall.SYS_IOCTL, uintptr(f.Fd()), uintptr(0x80045402), // IOSSIOSPEED uintptr(unsafe.Pointer(&baud))); if e != 0 || r1 != 0 { s := fmt.Sprint("Baudrate syscall error:", e, r1) f.Close() return nil, os.NewError(s) } */ return &Port{f: f}, nil }
func IsTerminal(file *os.File) bool { return (int(C.isatty(C.int(file.Fd()))) == 1) }