FreeBSD Bugzilla – Attachment 234662 Details for
Bug 264654
/usr/include/sys/_termios.h
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
modification to mshv
qextserialport_unix.cpp (text/plain), 14.41 KB, created by
lu9dce
on 2022-06-13 14:10:44 UTC
(
hide
)
Description:
modification to mshv
Filename:
MIME Type:
Creator:
lu9dce
Created:
2022-06-13 14:10:44 UTC
Size:
14.41 KB
patch
obsolete
>/**************************************************************************** >** Copyright (c) 2000-2003 Wayne Roth >** Copyright (c) 2004-2007 Stefan Sander >** Copyright (c) 2007 Michal Policht >** Copyright (c) 2008 Brandon Fosdick >** Copyright (c) 2009-2010 Liam Staskawicz >** Copyright (c) 2011 Debao Zhang >** All right reserved. >** Web: http://code.google.com/p/qextserialport/ >** >** Permission is hereby granted, free of charge, to any person obtaining >** a copy of this software and associated documentation files (the >** "Software"), to deal in the Software without restriction, including >** without limitation the rights to use, copy, modify, merge, publish, >** distribute, sublicense, and/or sell copies of the Software, and to >** permit persons to whom the Software is furnished to do so, subject to >** the following conditions: >** >** The above copyright notice and this permission notice shall be >** included in all copies or substantial portions of the Software. >** >** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, >** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF >** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND >** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE >** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION >** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION >** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. >** >****************************************************************************/ > >#include "qextserialport.h" >#include "qextserialport_p.h" >#include <fcntl.h> >#include <stdio.h> >#include <errno.h> >#include <unistd.h> >#include <sys/time.h> >#include <sys/ioctl.h> >#include <sys/select.h> >#include <QtCore/QMutexLocker> >#include <QtCore/QDebug> >#include <QtCore/QSocketNotifier> > >void QextSerialPortPrivate::platformSpecificInit() >{ > fd = 0; > readNotifier = 0; >} > >/*! > Standard destructor. >*/ >void QextSerialPortPrivate::platformSpecificDestruct() >{ >} > >static QString fullPortName(const QString &name) >{ > if (name.startsWith(QLatin1Char('/'))) > return name; > return QLatin1String("/dev/")+name; >} > >bool QextSerialPortPrivate::open_sys(QIODevice::OpenMode mode) >{ > Q_Q(QextSerialPort); > //note: linux 2.6.21 seems to ignore O_NDELAY flag > if ((fd = ::open(fullPortName(port).toLatin1() ,O_RDWR | O_NOCTTY | O_NDELAY)) != -1) { > > /*In the Private class, We can not call QIODevice::open()*/ > q->setOpenMode(mode); // Flag the port as opened > ::tcgetattr(fd, &oldTermios); // Save the old termios > currentTermios = oldTermios; // Make a working copy > ::cfmakeraw(¤tTermios); // Enable raw access > > /*set up other port settings*/ > currentTermios.c_cflag |= CREAD|CLOCAL; > currentTermios.c_lflag &= (~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG)); > currentTermios.c_iflag &= (~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY)); > currentTermios.c_oflag &= (~OPOST); > currentTermios.c_cc[VMIN] = 0; >#ifdef _POSIX_VDISABLE // Is a disable character available on this system? > // Some systems allow for per-device disable-characters, so get the > // proper value for the configured device > const long vdisable = ::fpathconf(fd, _PC_VDISABLE); > currentTermios.c_cc[VINTR] = vdisable; > currentTermios.c_cc[VQUIT] = vdisable; > currentTermios.c_cc[VSTART] = vdisable; > currentTermios.c_cc[VSTOP] = vdisable; > currentTermios.c_cc[VSUSP] = vdisable; >#endif //_POSIX_VDISABLE > settingsDirtyFlags = DFE_ALL; > updatePortSettings(); > > if (queryMode == QextSerialPort::EventDriven) { > readNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, q); > q->connect(readNotifier, SIGNAL(activated(int)), q, SLOT(_q_canRead())); > } > return true; > } else { > translateError(errno); > return false; > } >} > >bool QextSerialPortPrivate::close_sys() >{ > // Force a flush and then restore the original termios > flush_sys(); > // Using both TCSAFLUSH and TCSANOW here discards any pending input > ::tcsetattr(fd, TCSAFLUSH | TCSANOW, &oldTermios); // Restore termios > ::close(fd); > if (readNotifier) { > delete readNotifier; > readNotifier = 0; > } > return true; >} > >bool QextSerialPortPrivate::flush_sys() >{ > ::tcdrain(fd); > return true; >} > >qint64 QextSerialPortPrivate::bytesAvailable_sys() const >{ > int bytesQueued; > if (::ioctl(fd, FIONREAD, &bytesQueued) == -1) { > return (qint64)-1; > } > return bytesQueued; >} > >/*! > Translates a system-specific error code to a QextSerialPort error code. Used internally. >*/ >void QextSerialPortPrivate::translateError(ulong error) >{ > switch (error) { > case EBADF: > case ENOTTY: > lastErr = E_INVALID_FD; > break; > case EINTR: > lastErr = E_CAUGHT_NON_BLOCKED_SIGNAL; > break; > case ENOMEM: > lastErr = E_NO_MEMORY; > break; > case EACCES: > lastErr = E_PERMISSION_DENIED; > break; > case EAGAIN: > lastErr = E_AGAIN; > break; > } >} > >void QextSerialPortPrivate::setDtr_sys(bool set) >{ > int status; > ::ioctl(fd, TIOCMGET, &status); > if (set) > status |= TIOCM_DTR; > else > status &= ~TIOCM_DTR; > ::ioctl(fd, TIOCMSET, &status); >} > >void QextSerialPortPrivate::setRts_sys(bool set) >{ > int status; > ::ioctl(fd, TIOCMGET, &status); > if (set) > status |= TIOCM_RTS; > else > status &= ~TIOCM_RTS; > ::ioctl(fd, TIOCMSET, &status); >} > >unsigned long QextSerialPortPrivate::lineStatus_sys() >{ > unsigned long Status=0, Temp=0; > ::ioctl(fd, TIOCMGET, &Temp); > if (Temp & TIOCM_CTS) Status |= LS_CTS; > if (Temp & TIOCM_DSR) Status |= LS_DSR; > if (Temp & TIOCM_RI) Status |= LS_RI; > if (Temp & TIOCM_CD) Status |= LS_DCD; > if (Temp & TIOCM_DTR) Status |= LS_DTR; > if (Temp & TIOCM_RTS) Status |= LS_RTS; > if (Temp & TIOCM_ST) Status |= LS_ST; > if (Temp & TIOCM_SR) Status |= LS_SR; > return Status; >} > >/*! > Reads a block of data from the serial port. This function will read at most maxSize bytes from > the serial port and place them in the buffer pointed to by data. Return value is the number of > bytes actually read, or -1 on error. > > \warning before calling this function ensure that serial port associated with this class > is currently open (use isOpen() function to check if port is open). >*/ >qint64 QextSerialPortPrivate::readData_sys(char *data, qint64 maxSize) >{ > int retVal = ::read(fd, data, maxSize); > if (retVal == -1) > lastErr = E_READ_FAILED; > > return retVal; >} > >/*! > Writes a block of data to the serial port. This function will write maxSize bytes > from the buffer pointed to by data to the serial port. Return value is the number > of bytes actually written, or -1 on error. > > \warning before calling this function ensure that serial port associated with this class > is currently open (use isOpen() function to check if port is open). >*/ >qint64 QextSerialPortPrivate::writeData_sys(const char *data, qint64 maxSize) >{ > int retVal = ::write(fd, data, maxSize); > if (retVal == -1) > lastErr = E_WRITE_FAILED; > > return (qint64)retVal; >} > >static void setBaudRate2Termios(termios *config, int baudRate) >{ >#ifdef CBAUD > config->c_cflag &= (~CBAUD); > config->c_cflag |= baudRate; >#else > ::cfsetispeed(config, baudRate); > ::cfsetospeed(config, baudRate); >#endif >} > >/* > All the platform settings was performed in this function. >*/ > >#if defined _FREEBSDHV_ //freeBSD 13.1 exeption >#define B576000 576000 >#define B1152000 1152000U >#endif > >void QextSerialPortPrivate::updatePortSettings() >{ > if (!q_func()->isOpen() || !settingsDirtyFlags) > return; > > if (settingsDirtyFlags & DFE_BaudRate) { > switch (settings.BaudRate) { > case BAUD50: > setBaudRate2Termios(¤tTermios, B50); > break; > case BAUD75: > setBaudRate2Termios(¤tTermios, B75); > break; > case BAUD110: > setBaudRate2Termios(¤tTermios, B110); > break; > case BAUD134: > setBaudRate2Termios(¤tTermios, B134); > break; > case BAUD150: > setBaudRate2Termios(¤tTermios, B150); > break; > case BAUD200: > setBaudRate2Termios(¤tTermios, B200); > break; > case BAUD300: > setBaudRate2Termios(¤tTermios, B300); > break; > case BAUD600: > setBaudRate2Termios(¤tTermios, B600); > break; > case BAUD1200: > setBaudRate2Termios(¤tTermios, B1200); > break; > case BAUD1800: > setBaudRate2Termios(¤tTermios, B1800); > break; > case BAUD2400: > setBaudRate2Termios(¤tTermios, B2400); > break; > case BAUD4800: > setBaudRate2Termios(¤tTermios, B4800); > break; > case BAUD9600: > setBaudRate2Termios(¤tTermios, B9600); > break; > case BAUD19200: > setBaudRate2Termios(¤tTermios, B19200); > break; > case BAUD38400: > setBaudRate2Termios(¤tTermios, B38400); > break; > case BAUD57600: > setBaudRate2Termios(¤tTermios, B57600); > break; >#ifdef B76800 > case BAUD76800: > setBaudRate2Termios(¤tTermios, B76800); > break; >#endif > case BAUD115200: > setBaudRate2Termios(¤tTermios, B115200); > break; >#if defined(B230400) && defined(B4000000) > case BAUD230400: > setBaudRate2Termios(¤tTermios, B230400); > break; > case BAUD460800: > setBaudRate2Termios(¤tTermios, B460800); > break; > case BAUD500000: > setBaudRate2Termios(¤tTermios, B500000); > break; > case BAUD576000: > setBaudRate2Termios(¤tTermios, B576000); > break; > case BAUD921600: > setBaudRate2Termios(¤tTermios, B921600); > break; > case BAUD1000000: > setBaudRate2Termios(¤tTermios, B1000000); > break; > case BAUD1152000: > setBaudRate2Termios(¤tTermios, B1152000); > break; > case BAUD1500000: > setBaudRate2Termios(¤tTermios, B1500000); > break; > case BAUD2000000: > setBaudRate2Termios(¤tTermios, B2000000); > break; > case BAUD2500000: > setBaudRate2Termios(¤tTermios, B2500000); > break; > case BAUD3000000: > setBaudRate2Termios(¤tTermios, B3000000); > break; > case BAUD3500000: > setBaudRate2Termios(¤tTermios, B3500000); > break; > case BAUD4000000: > setBaudRate2Termios(¤tTermios, B4000000); > break; >#endif >#ifdef Q_OS_MAC > default: > setBaudRate2Termios(¤tTermios, settings.BaudRate); > break; >#endif > } > } > if (settingsDirtyFlags & DFE_Parity) { > switch (settings.Parity) { > case PAR_SPACE: > /*space parity not directly supported - add an extra data bit to simulate it*/ > settingsDirtyFlags |= DFE_DataBits; > break; > case PAR_NONE: > currentTermios.c_cflag &= (~PARENB); > break; > case PAR_EVEN: > currentTermios.c_cflag &= (~PARODD); > currentTermios.c_cflag |= PARENB; > break; > case PAR_ODD: > currentTermios.c_cflag |= (PARENB|PARODD); > break; > } > } > /*must after Parity settings*/ > if (settingsDirtyFlags & DFE_DataBits) { > if (settings.Parity != PAR_SPACE) { > currentTermios.c_cflag &= (~CSIZE); > switch(settings.DataBits) { > case DATA_5: > currentTermios.c_cflag |= CS5; > break; > case DATA_6: > currentTermios.c_cflag |= CS6; > break; > case DATA_7: > currentTermios.c_cflag |= CS7; > break; > case DATA_8: > currentTermios.c_cflag |= CS8; > break; > } > } else { > /*space parity not directly supported - add an extra data bit to simulate it*/ > currentTermios.c_cflag &= ~(PARENB|CSIZE); > switch(settings.DataBits) { > case DATA_5: > currentTermios.c_cflag |= CS6; > break; > case DATA_6: > currentTermios.c_cflag |= CS7; > break; > case DATA_7: > currentTermios.c_cflag |= CS8; > break; > case DATA_8: > /*this will never happen, put here to Suppress an warning*/ > break; > } > } > } > if (settingsDirtyFlags & DFE_StopBits) { > switch (settings.StopBits) { > case STOP_1: > currentTermios.c_cflag &= (~CSTOPB); > break; > case STOP_2: > currentTermios.c_cflag |= CSTOPB; > break; > } > } > if (settingsDirtyFlags & DFE_Flow) { > switch(settings.FlowControl) { > case FLOW_OFF: > currentTermios.c_cflag &= (~CRTSCTS); > currentTermios.c_iflag &= (~(IXON|IXOFF|IXANY)); > break; > case FLOW_XONXOFF: > /*software (XON/XOFF) flow control*/ > currentTermios.c_cflag &= (~CRTSCTS); > currentTermios.c_iflag |= (IXON|IXOFF|IXANY); > break; > case FLOW_HARDWARE: > currentTermios.c_cflag |= CRTSCTS; > currentTermios.c_iflag &= (~(IXON|IXOFF|IXANY)); > break; > } > } > > /*if any thing in currentTermios changed, flush*/ > if (settingsDirtyFlags & DFE_Settings_Mask) > ::tcsetattr(fd, TCSAFLUSH, ¤tTermios); > > if (settingsDirtyFlags & DFE_TimeOut) { > int millisec = settings.Timeout_Millisec; > if (millisec == -1) { > ::fcntl(fd, F_SETFL, O_NDELAY); > } > else { > //O_SYNC should enable blocking ::write() > //however this seems not working on Linux 2.6.21 (works on OpenBSD 4.2) > ::fcntl(fd, F_SETFL, O_SYNC); > } > ::tcgetattr(fd, ¤tTermios); > currentTermios.c_cc[VTIME] = millisec/100; > ::tcsetattr(fd, TCSAFLUSH, ¤tTermios); > } > > settingsDirtyFlags = 0; >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 264654
: 234662