func (c *Connection) setBaudRate(baud Baud) error { fd, err := c.getFileDescriptor() if err != nil { return err } var st C.struct_termios _, err = C.tcgetattr(fd, &st) if err != nil { return err } speed, err := convertBaud(c.Baud) if err != nil { return err } _, err = C.cfsetispeed(&st, speed) if err != nil { return err } _, err = C.cfsetospeed(&st, speed) if err != nil { return err } return nil }
/** * 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 }
// SetISpeed sets the input (receiver) baudrate in Termios structure t // to speed. Argument speed must be a numerical (integer) baudrate // value in bits-per-second. Returns syscall.EINVAL if the requested // baudrate is not supported. See also cfsetispeed(3). func (t *Termios) SetISpeed(speed int) error { code, ok := stdSpeeds.Code(speed) if !ok { return syscall.EINVAL } C.cfsetispeed(&t.t, C.speed_t(code)) return nil }
// Setispeed sets the input baud rate in the Termios // structure referenced by dst to speed. func Setispeed(dst *Termios, speed C.speed_t) error { dst.i.c_iflag = dst.C_iflag dst.i.c_oflag = dst.C_oflag dst.i.c_cflag = dst.C_cflag dst.i.c_lflag = dst.C_lflag dst.i.c_cc = dst.C_cc _, rv := C.cfsetispeed(&dst.i, speed) if rv == nil { dst.C_iflag = dst.i.c_iflag dst.C_oflag = dst.i.c_oflag dst.C_cflag = dst.i.c_cflag dst.C_lflag = dst.i.c_lflag dst.C_cc = dst.i.c_cc } return rv }
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 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 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 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 }
// Opens and returns a non-blocking serial port. // The device, baud rate, and SerConf is specified. // // Example: rs232.OpenPort("/dev/ttyS0", 115200, rs232.S_8N1) func OpenPort(port string, baudRate int, serconf SerConf) (*SerialPort, error) { rv := &SerialPort{} f, err := os.OpenFile(port, syscall.O_RDWR|syscall.O_NOCTTY, 0666) if err != nil { return nil, err } rv.port = f fd := rv.port.Fd() var options C.struct_termios if C.tcgetattr(C.int(fd), &options) < 0 { defer f.Close() return nil, fmt.Errorf("tcgetattr failed") } if C.cfsetispeed(&options, baudConversion(baudRate)) < 0 { defer f.Close() return nil, fmt.Errorf("cfsetispeed failed") } if C.cfsetospeed(&options, baudConversion(baudRate)) < 0 { defer f.Close() return nil, fmt.Errorf("cfsetospeed failed") } switch serconf { case S_8N1: { options.c_cflag &^= C.PARENB options.c_cflag &^= C.CSTOPB options.c_cflag &^= C.CSIZE options.c_cflag |= C.CS8 } case S_7E1: { options.c_cflag |= C.PARENB options.c_cflag &^= C.PARODD options.c_cflag &^= C.CSTOPB options.c_cflag &^= C.CSIZE options.c_cflag |= C.CS7 } case S_7O1: { options.c_cflag |= C.PARENB options.c_cflag |= C.PARODD options.c_cflag &^= C.CSTOPB options.c_cflag &^= C.CSIZE options.c_cflag |= C.CS7 } } // Local options.c_cflag |= (C.CLOCAL | C.CREAD) // no hardware flow control options.c_cflag &^= C.CRTSCTS // Don't EOF on a zero read, just block options.c_cc[C.VMIN] = 1 if C.tcsetattr(C.int(fd), C.TCSANOW, &options) < 0 { defer f.Close() return nil, fmt.Errorf("tcsetattr failed") } return rv, nil }
// Opens and returns a non-blocking serial port. // The device, baud rate, and SerConf is specified. // // Example: rs232.OpenPort("/dev/ttyS0", 115200, rs232.S_8N1) func OpenPort(port string, baudRate int, serconf SerConf) (rv SerialPort, err error) { f, open_err := os.OpenFile(port, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NDELAY, 0666) if open_err != nil { err = open_err return } rv.port = f fd := rv.port.Fd() var options C.struct_termios if C.tcgetattr(C.int(fd), &options) < 0 { panic("tcgetattr failed") } if C.cfsetispeed(&options, baudConversion(baudRate)) < 0 { panic("cfsetispeed failed") } if C.cfsetospeed(&options, baudConversion(baudRate)) < 0 { panic("cfsetospeed failed") } switch serconf { case S_8N1: { options.c_cflag &^= C.PARENB options.c_cflag &^= C.CSTOPB options.c_cflag &^= C.CSIZE options.c_cflag |= C.CS8 } case S_7E1: { options.c_cflag |= C.PARENB options.c_cflag &^= C.PARODD options.c_cflag &^= C.CSTOPB options.c_cflag &^= C.CSIZE options.c_cflag |= C.CS7 } case S_7O1: { options.c_cflag |= C.PARENB options.c_cflag |= C.PARODD options.c_cflag &^= C.CSTOPB options.c_cflag &^= C.CSIZE options.c_cflag |= C.CS7 } } // Local options.c_cflag |= (C.CLOCAL | C.CREAD) // no hardware flow control options.c_cflag &^= C.CRTSCTS if C.tcsetattr(C.int(fd), C.TCSANOW, &options) < 0 { panic("tcsetattr failed") } if syscall.SetNonblock(int(fd), false) != nil { panic("Error disabling blocking") } return }
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 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 (s *Serial) SetBaud(b uint32) { if s.Opened { var tios C.struct_termios getTermios(s.f, &tios) var baud C.speed_t switch b { case 0: baud = C.B0 case 50: baud = C.B50 case 75: baud = C.B75 case 110: baud = C.B110 case 134: baud = C.B134 case 150: baud = C.B150 case 200: baud = C.B200 case 300: baud = C.B300 case 600: baud = C.B600 case 1200: baud = C.B1200 case 1800: baud = C.B1800 case 2400: baud = C.B2400 case 4800: baud = C.B4800 case 9600: baud = C.B9600 case 19200: baud = C.B19200 case 38400: baud = C.B38400 case 57600: baud = C.B57600 case 115200: baud = C.B115200 case 230400: baud = C.B230400 case 460800: baud = C.B460800 case 500000: baud = C.B500000 case 576000: baud = C.B576000 case 921600: baud = C.B921600 case 1000000: baud = C.B1000000 case 1152000: baud = C.B1152000 case 1500000: baud = C.B1500000 case 2000000: baud = C.B2000000 case 2500000: baud = C.B2500000 case 3000000: baud = C.B3000000 case 3500000: baud = C.B3500000 case 4000000: baud = C.B4000000 default: baud = 10000000 } if baud != 10000000 { C.cfsetispeed(&tios, baud) C.cfsetospeed(&tios, baud) setTermios(s.f, &tios) } } }
// Cfsetispeed sets the input baud rate stored in the termios structure. func Cfsetispeed(attr *syscall.Termios, speed uintptr) error { solTermios := (*unix.Termios)(attr) _, err := C.cfsetispeed((*C.termios_t)(unsafe.Pointer(solTermios)), C.speed_t(speed)) return err }