📄 qjmcom.cpp
字号:
#include "qjmcom.h"#include <QMessageBox>#include <QString>#include <iostream.h>#include <errno.h>#include <unistd.h>#include <ctype.h>#include <sys/ioctl.h>#include <sys/termios.h>#include <sys/time.h>#include <sys/types.h>#include <sys/select.h>#include <fcntl.h>void millisleep(int ms){ if (ms>0) { struct timeval tv; tv.tv_sec=0; tv.tv_usec=ms*1000; select(0, 0, 0, 0, &tv); }}QjmcomBase::QjmcomBase( QWidget *parent, Qt::WFlags f ) : QWidget( parent, f ){ setupUi( this );}QjmcomBase::~QjmcomBase(){}/* * Constructs a Example which is a child of 'parent', with the * name 'name' and widget flags set to 'f' */Qjmcom::Qjmcom( QWidget *parent, Qt::WFlags f ) : QjmcomBase( parent, f ){ connect(m_quitPb, SIGNAL(clicked()), this, SLOT(goodBye())); connect(m_aboutPb, SIGNAL(clicked()), this, SLOT(showAboutMsg())); connect(m_connectPb, SIGNAL(clicked()), this, SLOT(connectTTY())); connect(m_closePb, SIGNAL(clicked()), this, SLOT(disconnectTTY())); connect(m_inputSendPb, SIGNAL(clicked()), this, SLOT(sendData())); connect(m_clearOutputPb, SIGNAL(clicked()), this, SLOT(clearText()));}/* * Destroys the object and frees any allocated resources */Qjmcom::~Qjmcom(){ // no need to delete child widgets, Qt does it all for us}/* * A simple slot... not very interesting. */void Qjmcom::goodBye(){ close();}void Qjmcom::clearText(){ m_outputViewTb->clear(); m_outputBuffer="";}/** This function features some code from minicom 2.0.0, src/sysdep1.c */void Qjmcom::setNewOptions(int baudrate, int databits, const QString& parity, const QString& stop, bool softwareHandshake, bool hardwareHandshake){ struct termios newtio;// memset(&newtio, 0, sizeof(newtio)); if (tcgetattr(m_fd, &newtio)!=0) cerr<<"tcgetattr() 3 failed"<<endl; /*{ unsigned int i; char *c =(char*)&newtio; fprintf(stderr,"*****************\n"); for (i=0; i<sizeof(newtio); i++) { unsigned int t=*c; if (i%8 == 0) fprintf(stderr,"\n"); fprintf(stderr, " 0x%02x", t&0xff); c++; } }*/ speed_t _baud=0; switch (baudrate) { case 600: _baud=B600; break; case 1200: _baud=B1200; break; case 2400: _baud=B2400; break; case 4800: _baud=B4800; break; case 9600: _baud=B9600; break;// case 14400:// _baud=B14400;// break; case 19200: _baud=B19200; break;// case 28800:// _baud=B28800;// break; case 38400: _baud=B38400; break;// case 56000:// _baud=B56000;// break; case 57600: _baud=B57600; break; case 115200: _baud=B115200; break; case 230400: _baud=B230400; break; case 460800: _baud=B460800; break; case 576000: _baud=B576000; break; case 921600: _baud=B921600; break;// case 128000:// _baud=B128000;// break; default:// case 256000:// _baud=B256000; break; } cfsetospeed(&newtio, (speed_t)_baud); cfsetispeed(&newtio, (speed_t)_baud); /* We generate mark and space parity ourself. */ if (databits == 7 && (parity=="Mark" || parity == "Space")) databits = 8; switch (databits) { case 5: newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS5; break; case 6: newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS6; break; case 7: newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS7; break; case 8: default: newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS8; break; } newtio.c_cflag |= CLOCAL | CREAD; //parity newtio.c_cflag &= ~(PARENB | PARODD); if (parity == "Even") newtio.c_cflag |= PARENB; else if (parity== "Odd") newtio.c_cflag |= (PARENB | PARODD); //hardware handshake/* if (hardwareHandshake) newtio.c_cflag |= CRTSCTS; else newtio.c_cflag &= ~CRTSCTS;*/ newtio.c_cflag &= ~CRTSCTS; //stopbits if (stop=="2") newtio.c_cflag |= CSTOPB; else newtio.c_cflag &= ~CSTOPB;// newtio.c_iflag=IGNPAR | IGNBRK; newtio.c_iflag=IGNBRK;// newtio.c_iflag=IGNPAR; //software handshake if (softwareHandshake) newtio.c_iflag |= IXON | IXOFF; else newtio.c_iflag &= ~(IXON|IXOFF|IXANY); newtio.c_lflag=0; newtio.c_oflag=0; newtio.c_cc[VTIME]=1; newtio.c_cc[VMIN]=60;// tcflush(m_fd, TCIFLUSH); if (tcsetattr(m_fd, TCSANOW, &newtio)!=0) cerr<<"tcsetattr() 1 failed"<<endl; int mcs=0;// ioctl(m_fd, TIOCMODG, &mcs); ioctl(m_fd, TIOCMGET, &mcs); mcs |= TIOCM_RTS; ioctl(m_fd, TIOCMSET, &mcs); if (tcgetattr(m_fd, &newtio)!=0) cerr<<"tcgetattr() 4 failed"<<endl; //hardware handshake if (hardwareHandshake) newtio.c_cflag |= CRTSCTS; else newtio.c_cflag &= ~CRTSCTS;/* if (on) newtio.c_cflag |= CRTSCTS; else newtio.c_cflag &= ~CRTSCTS;*/ if (tcsetattr(m_fd, TCSANOW, &newtio)!=0) cerr<<"tcsetattr() 2 failed"<<endl; /*{ unsigned int i; char *c =(char*)&newtio; fprintf(stderr,"-----------------\n"); tcgetattr(m_fd, &newtio); for (i=0; i<sizeof(newtio); i++) { unsigned int t=*c; if (i%8 == 0) fprintf(stderr,"\n"); fprintf(stderr, " 0x%02x", t&0xff); c++; } }*/}bool Qjmcom::sendData(){ QString outChar = m_inputLe->text(); const char *bytes = outChar.toLatin1(); for(unsigned int i = 0; i < outChar.length(); i++) { if(!sendByte(*bytes, 2)) return false; bytes++; } sendByte('\r', 2); sendByte('\n', 2); return true;}bool Qjmcom::sendByte(char c, unsigned int delay){ if (m_fd==-1) return false;// c=c&0xff; int res=::write(m_fd, &c, 1);// cerr<<"wrote "<<(unsigned int)(c)<<endl; if (res<1) { cerr<<"write returned "<<res<<" errno: "<<errno<<endl; perror("write\n"); return false; } millisleep(delay);// else// cerr<<" \""<<c<<"\"; "; return true;}void Qjmcom::readData(int fd){ if (fd!=m_fd) return; int bytesRead=::read(m_fd, m_buf, CUTECOMM_BUFSIZE); if (bytesRead<0) { cerr<<"read result: "<<bytesRead<<endl; perror("read: \n"); return; } const char* c=m_buf; QString text; char buf[16]; for (int i=0; i<bytesRead; i++) { if ((isprint(*c)) || (*c=='\n') || (*c=='\r')) { if (*c!='\r') text+=(*c); } else { unsigned int b=*c; snprintf(buf, 16, "\\0x%02x", b & 0xff); text+=buf; } c++; } addOutput(text);}void Qjmcom::addOutput(const QString& text){ m_outputBuffer+=text; if (!m_outputTimer.isActive()) { doOutput(); m_outputTimerStart.restart(); m_outputTimer.start(50); } else { if ((m_outputTimerStart.elapsed()>400) || ((m_outputTimerStart.elapsed()>200) && (m_outputBuffer.length()<100))) { doOutput(); m_outputTimerStart.restart(); } m_outputTimer.start(50); }}void Qjmcom::doOutput(){ if (m_outputBuffer.isEmpty()) return;// m_outputViewTb->setLineWrapMode(QTextEdit::WidgetWidth);// m_outputViewTb->setText(m_outputViewTb->text() + m_outputBuffer);// cerr<<"*";#if 0 int pNumber=m_outputViewTb->paragraphs(); if (pNumber>1100) { m_outputViewTb->setUpdatesEnabled(false); m_outputViewTb->setSelection(0, 0, pNumber-1000, 0); m_outputViewTb->removeSelectedText(); m_outputViewTb->scrollToBottom(); m_outputViewTb->setCursorPosition(m_outputViewTb->paragraphs()-1, m_outputViewTb->paragraphLength(m_outputViewTb->paragraphs()-1)); m_outputViewTb->insert(m_outputBuffer); m_outputViewTb->setUpdatesEnabled(true); } else { m_outputViewTb->setCursorPosition(m_outputViewTb->paragraphs()-1, m_outputViewTb->paragraphLength(m_outputViewTb->paragraphs()-1)); m_outputViewTb->insert(m_outputBuffer); }#endif m_outputViewTb->append(m_outputBuffer); m_outputBuffer="";}void Qjmcom::connectTTY(){ int dataBits = 8; QString dev = m_deviceCb->currentText(); int baudrate = m_baudrateCb->currentText().toInt(); QString parity = "None"; QString stop = "1"; bool softwareHandshake = false; bool hardwareHandshake = false; m_fd=open(dev.toLatin1(), O_RDWR | O_NDELAY); if (m_fd<0) { cerr<<"opening failed"<<endl; m_fd=-1; QMessageBox::information(this, tr("Error"), tr("Could not open %1").arg(dev)); return; } tcflush(m_fd, TCIOFLUSH); int n = fcntl(m_fd, F_GETFL, 0); fcntl(m_fd, F_SETFL, n & ~O_NDELAY); if (tcgetattr(m_fd, &m_oldtio)!=0) cerr<<"tcgetattr() 2 failed"<<endl; setNewOptions(baudrate, dataBits, parity, stop, softwareHandshake, hardwareHandshake); m_deviceCb->setEnabled(false); m_baudrateCb->setEnabled(false); m_connectPb->setEnabled(false); m_closePb->setEnabled(true); m_quitPb->setEnabled(false); m_inputSendPb->setEnabled(true); m_closePb->setFocus(); m_isConnected = true; m_notifier=new QSocketNotifier(m_fd, QSocketNotifier::Read, this); connect(m_notifier, SIGNAL(activated(int)), this, SLOT(readData(int)));}void Qjmcom::disconnectTTY(){ m_outputTimer.stop(); m_outputBuffer="";// cerr<<"closing "<<m_fd<<endl; if (m_fd!=-1) { tcsetattr(m_fd, TCSANOW, &m_oldtio); ::close(m_fd); } m_fd=-1; m_deviceCb->setEnabled(true); m_baudrateCb->setEnabled(true); m_connectPb->setEnabled(true); m_closePb->setEnabled(false); m_quitPb->setEnabled(true); m_inputSendPb->setEnabled(false); m_connectPb->setFocus(); m_isConnected = false; delete m_notifier; m_notifier=0;}void Qjmcom::showAboutMsg(){ QMessageBox::about(this, tr("About QJMCOM"), tr("<font color=#ff0000><strong>This is QJMCOM 0.1</strong></font><br> (c)2004-2007 Brillian Network & Automation Interated System Co.,Ltd. <br>Author: Eric Qiu <jm_qiu@sohu.com>"));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -