📄 serialstreambuf.cc
字号:
} else { return 1 ; }}const SerialStreamBuf::ParityEnumSerialStreamBuf::SetParity(const ParityEnum parity) { if( -1 == mFileDescriptor ) { return PARITY_INVALID ; } // // Get the current terminal settings. // struct termios term_setting ; if( -1 == tcgetattr(mFileDescriptor, &term_setting) ) { return PARITY_INVALID ; } // // Set the parity in the termios structure. // switch( parity ) { case PARITY_EVEN: term_setting.c_cflag |= PARENB ; term_setting.c_cflag &= ~PARODD ; break ; case PARITY_ODD: term_setting.c_cflag |= PARENB ; term_setting.c_cflag |= PARODD ; break ; case PARITY_NONE: term_setting.c_cflag &= ~PARENB ; break ; default: return PARITY_INVALID ; } // // Write the settings back to the serial port. // if( -1 == tcsetattr(mFileDescriptor, TCSANOW, &term_setting) ) { return PARITY_INVALID ; } return Parity() ;}const SerialStreamBuf::ParityEnumSerialStreamBuf::Parity() const { if( -1 == mFileDescriptor ) { return PARITY_INVALID ; } // // Get the current terminal settings. // struct termios term_setting ; if( -1 == tcgetattr(mFileDescriptor, &term_setting) ) { return PARITY_INVALID ; } // // Get the parity setting from the termios structure. // if( term_setting.c_cflag & PARENB ) { // parity is enabled. if( term_setting.c_cflag & PARODD ) { // odd parity return PARITY_ODD ; } else { // even parity return PARITY_EVEN ; } } else { // no parity. return PARITY_NONE ; } return PARITY_INVALID ; // execution should never reach here. }const SerialStreamBuf::FlowControlEnumSerialStreamBuf::SetFlowControl(const FlowControlEnum flow_c) { if( -1 == mFileDescriptor ) { return FLOW_CONTROL_INVALID ; } // // Flush any unwritten, unread data from the serial port. // if( -1 == tcflush(mFileDescriptor, TCIOFLUSH) ) { return FLOW_CONTROL_INVALID ; } // // Get the current terminal settings. // struct termios tset; int retval = tcgetattr(mFileDescriptor, &tset); if (-1 == retval) { return FLOW_CONTROL_INVALID ; } // // Set the flow control. Hardware flow control uses the RTS (Ready // To Send) and CTS (clear to Send) lines. Software flow control // uses IXON|IXOFF // if ( FLOW_CONTROL_HARD == flow_c ) { tset.c_iflag &= ~ (IXON|IXOFF); tset.c_cflag |= CRTSCTS; tset.c_cc[VSTART] = _POSIX_VDISABLE; tset.c_cc[VSTOP] = _POSIX_VDISABLE; } else if ( FLOW_CONTROL_SOFT == flow_c ) { tset.c_iflag |= IXON|IXOFF; tset.c_cflag &= ~CRTSCTS; tset.c_cc[VSTART] = CTRL_Q ; // 0x11 (021) ^q tset.c_cc[VSTOP] = CTRL_S ; // 0x13 (023) ^s } else { tset.c_iflag &= ~(IXON|IXOFF); tset.c_cflag &= ~CRTSCTS; } retval = tcsetattr(mFileDescriptor, TCSANOW, &tset); if (-1 == retval) { return FLOW_CONTROL_INVALID ; } return FlowControl() ;}const SerialStreamBuf::FlowControlEnumSerialStreamBuf::FlowControl() const { if( -1 == mFileDescriptor ) { return FLOW_CONTROL_INVALID ; } // // Get the current terminal settings. // struct termios tset ; if( -1 == tcgetattr(mFileDescriptor, &tset) ) { return FLOW_CONTROL_INVALID ; } // // Check if IXON and IXOFF are set in c_iflag. If both are set and // VSTART and VSTOP are set to 0x11 (^Q) and 0x13 (^S) respectively, // then we are using software flow control. // if( (tset.c_iflag & IXON) && (tset.c_iflag & IXOFF) && (CTRL_Q == tset.c_cc[VSTART]) && (CTRL_S == tset.c_cc[VSTOP] ) ) { return FLOW_CONTROL_SOFT ; } else if ( ! ( (tset.c_iflag & IXON) || (tset.c_iflag & IXOFF) ) ) { if ( tset.c_cflag & CRTSCTS ) { // // If neither IXON or IXOFF is set then we must have hardware flow // control. // return FLOW_CONTROL_HARD ; } else { return FLOW_CONTROL_NONE ; } } // // If none of the above conditions are satisfied then the serial // port is using a flow control setup which we do not support at // present. // return FLOW_CONTROL_INVALID ;}const short SerialStreamBuf::SetVMin( short vmin ) { if( -1 == mFileDescriptor ) { return -1 ; } if ( vmin < 0 || vmin > 255 ) { return -1 ; }; // // Get the current terminal settings. // struct termios term_setting ; if( -1 == tcgetattr(mFileDescriptor, &term_setting) ) { return -1 ; } term_setting.c_cc[VMIN] = (cc_t)vmin; // // Set the new settings for the serial port. // if( -1 == tcsetattr(mFileDescriptor, TCSANOW, &term_setting) ) { return -1 ; } return vmin;}const short SerialStreamBuf::VMin() const { if( -1 == mFileDescriptor ) { return -1 ; } // // Get the current terminal settings. // struct termios term_setting ; if( -1 == tcgetattr(mFileDescriptor, &term_setting) ) { return -1 ; } return term_setting.c_cc[VMIN];}const short SerialStreamBuf::SetVTime( short vtime ) { if( -1 == mFileDescriptor ) { return -1 ; } if ( vtime < 0 || vtime > 255 ) { return -1 ; }; // // Get the current terminal settings. // struct termios term_setting ; if( -1 == tcgetattr(mFileDescriptor, &term_setting) ) { return -1 ; } term_setting.c_cc[VTIME] = (cc_t)vtime; // // Set the new settings for the serial port. // if( -1 == tcsetattr(mFileDescriptor, TCSANOW, &term_setting) ) { return -1 ; } return vtime;}const short SerialStreamBuf::VTime() const { if( -1 == mFileDescriptor ) { return -1 ; } // // Get the current terminal settings. // struct termios term_setting ; if( -1 == tcgetattr(mFileDescriptor, &term_setting) ) { return -1 ; } return term_setting.c_cc[VTIME];}streamsizeSerialStreamBuf::xsgetn(char_type *s, streamsize n) { // // If mFileDescriptor is -1 then we do not have a valid serial port // associated with this buffer. Hence, we cannot read any characters // from the serial port. Similarly, if the parameter n is less than // or equal to 0, then we do not need to do anything here. // if( (-1 == mFileDescriptor) || (n <= 0) ) { return 0 ; } // // Try to read upto n characters in the array s. // ssize_t retval ; // // If a putback character is available, then we need to read only // n-1 character. // if( mPutbackAvailable ) { // // Put the mPutbackChar at the beginning of the array, s. // s[0] = mPutbackChar ; // // The putback character is no longer available. // mPutbackAvailable = false ; // // If we need to read more than one character, then call read() // and try to read n-1 more characters and put them at location // starting from &s[1]. // if( n > 1 ) { retval = read(mFileDescriptor, &s[1], n-1) ; // // If read was successful, then we need to increment retval by // one to indicate that the putback character was prepended to // the array, s. If read failed then leave retval at -1. // if( retval != -1 ) { retval ++ ; } } } else { // // If no putback character is available then we try to read n // characters. // retval = read(mFileDescriptor, s, n); } // // If retval == -1 then the read call had an error, otherwise, if // retval == 0 then we could not read the characters. In either // case, we return 0 to indicate that no characters could be read // from the serial port. // if( ( -1 == retval ) || ( 0 == retval ) ) { return 0 ; } // // Return the number of characters actually read from the serial // port. // return retval ;}std::streamsize SerialStreamBuf::showmanyc() { int retval = -1; if ( -1 == mFileDescriptor ) { return -1; }; if ( mPutbackAvailable ) { // We still have a character left in the buffer. retval = 1; } else { // Switch to non-blocking read. int flags = fcntl(this->mFileDescriptor, F_GETFL, 0) ; if( -1 == fcntl( this->mFileDescriptor, F_SETFL, flags | O_NONBLOCK ) ) { return -1; } // Try to read a character. retval = read(mFileDescriptor, &mPutbackChar, 1); if ( retval == 1 ) { mPutbackAvailable = true; } else retval = 0; // Switch back to blocking read. if( -1 == fcntl( this->mFileDescriptor, F_SETFL, flags ) ) { return -1; } }; return retval; }streambuf::int_typeSerialStreamBuf::underflow() { // // If we do not have a valid file handler for the serial port, we // cannot do much. // if( -1 == mFileDescriptor ) { return traits_type::eof() ; } // // Read the next character from the serial port. // char next_ch ; ssize_t retval ; // // If a putback character is available then we return that // character. However, we are not supposed to change the value of // gptr() in this routine so we leave mPutbackAvailable set to true. // if ( mPutbackAvailable ) { next_ch = mPutbackChar ; } else { // // If no putback character is available then we need to read one // character from the serial port. // retval = read(mFileDescriptor, &next_ch, 1); // // Make the next character the putback character. This has the // effect of returning the next character without changing gptr() // as required by the C++ standard. // if( retval == 1 ) { mPutbackChar = next_ch ; mPutbackAvailable = true ; } else if( ( -1 == retval ) || ( 0 == retval ) ) { // // If we had a problem reading the character, we return // traits::eof(). // return traits_type::eof() ; } } // // :NOTE: Wed Aug 9 21:26:51 2000 Pagey // The value of mPutbackAvailable is always true when the code // reaches here. // // // Return the character as an int value as required by the C++ // standard. // return traits_type::to_int_type(next_ch) ;}streambuf::int_typeSerialStreamBuf::pbackfail(int_type c) { // // If we do not have a valid file descriptor, then we return eof. // if( -1 == mFileDescriptor ) { return traits_type::eof() ; } // // If a putback character is already available, then we cannot // do any more putback and hence need to return eof. // if( mPutbackAvailable ) { return traits_type::eof() ; } else if ( traits_type::eq_int_type(c, traits_type::eof()) ) { // // If an eof character is passed in, then we are required to // backup one character. However, we cannot do this for a serial // port. Hence we return eof to signal an error. // return traits_type::eof() ; } else { // // If no putback character is available at present, then make // c the putback character and return it. // mPutbackChar = traits_type::to_char_type(c) ; mPutbackAvailable = true ; return traits_type::not_eof(c) ; }}streamsizeSerialStreamBuf::xsputn(const char_type *s, streamsize n) { // // If we do not have a valid file descriptor, then we cannot do much // here. Similarly if n is non-positive then we have nothing to do // here. // if( (-1 == mFileDescriptor) || (n <= 0) ) { return 0 ; } // // Write the n characters to the serial port. // ssize_t retval = write(mFileDescriptor, s, n) ; // // If the write failed then return 0. // if( (-1 == retval) || ( 0 == retval) ) { return 0 ; } // // Otherwise, return the number of bytes actually written. // return retval ;}streambuf::int_typeSerialStreamBuf::overflow(int_type c) { // // If we do not have a valid file descriptor then we cannot do much // here. // if( -1 == mFileDescriptor ) { return traits_type::eof() ; } // // Try to write the specified character to the serial port. // if ( traits_type::eq_int_type( c, traits_type::eof()) ) { // // If c is the eof character then we do nothing. // return traits_type::eof() ; } else { // // Otherwise we write the character to the serial port. // char out_ch = traits_type::to_char_type(c) ; ssize_t retval = write(mFileDescriptor, &out_ch, 1) ; // // If the write failed then return eof. // if( (-1 == retval) || ( 0 == retval) ) { return traits_type::eof() ; } // // Otherwise, return something other than eof(). // return traits_type::not_eof(c) ; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -