📄 clinkcom.cpp
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <termios.h> //* tcgetattr, tcsetattr */#include <unistd.h> //* read, write, close */#include <fcntl.h> //* open */#include <string.h> //* bzero, memcpy */#include <limits.h> //* CHAR_MAX */#include <sys/time.h>#include "../tools/global.h"#include "../tools/csysconfig.h"//#include "../tools/cmsgctrl.h"#include "clink.h"#include "clinkcom.h"/* * Decription for TIMEOUT_SEC(buflen,baud); * baud bits per second, buflen bytes to send. * buflen*20 (20 means sending an octect-bit data by use of the maxim bits 20) * eg. 9600bps baudrate, buflen=1024B, then TIMEOUT_SEC = 1024*20/9600+2 = 4 * don't change the two lines below unless you do know what you are doing. */#define TIMEOUT_SEC(buflen,baud) (buflen*20/baud+2)#define TIMEOUT_USEC 0int clinkcom::cominit(){ setlinktype(LINK_TYPE_COM); return 0;}int clinkcom::comclear(){// tcsetattr 很费时?// tcsetattr (this->fd, TCSADRAIN, &termios_old); cominit(); return 0;}//构造函数clinkcom::clinkcom(){ cominit();}//析构函数clinkcom::~clinkcom(){ if(CLOSED!=this->getfd()) { tcflush (this->getfd(), TCOFLUSH); // flush all output data } comclear();}//通过当前连接,写数据int clinkcom::write(void *data,int datalength,int flags){ int retval,len, total_len = 0; fd_set fs_write; struct timeval tv_timeout; if(true == this->isdead()) { return -1; } FD_ZERO (&fs_write); FD_SET (this->getfd(), &fs_write); tv_timeout.tv_sec = TIMEOUT_SEC (datalength, getbaudrate ()); tv_timeout.tv_usec = 0; for (total_len = 0, len = 0; total_len < datalength;) { retval = select (this->getfd() + 1, NULL, &fs_write, NULL, &tv_timeout); if (retval) { len = ::write (this->getfd(), &((char *)data)[total_len], datalength - total_len); if (len > 0) { total_len += len; } } else { tcflush (this->getfd(), TCOFLUSH); // flush all output data break; } } if(total_len != datalength) { tcflush (this->getfd(), TCOFLUSH); // flush all output data this->seterror(LINK_ERROR_CLOSE); onerror(); return -2; } return (total_len);}//用串口参数连接设备int clinkcom::connect(void *pvoidarg){ char *pComPort; int retval; int fd; if(NULL == pvoidarg) { return -1; } if(false == this->setlinkparam(pvoidarg,sizeof(scomarg))) { return -1; } scomarg *parg=(scomarg *)pvoidarg; switch (parg->port) { case 0: pComPort = "/dev/ttyS0"; break; case 1: pComPort = "/dev/ttyS1"; break; case 2: pComPort = "/dev/ttyS2"; break; case 3: pComPort = "/dev/ttyS3"; break; case 4: pComPort = "/dev/ttyS4"; break; case 5: pComPort = "/dev/ttyS5"; break; case 6: pComPort = "/dev/ttyS6"; break; case 7: pComPort = "/dev/ttyS7"; break; default: pComPort = "/dev/ttyS0"; break; } fd = open (pComPort, O_RDWR | O_NOCTTY | O_NONBLOCK); if (-1 == fd) { return -2; } tcgetattr (fd, &termios_old); //* save old termios value */ //* 0 on success, -1 on failure */ retval = setportattrib(parg); if (-1 == retval) { close(fd); return -3; } tcflush (fd, TCIFLUSH); retval = tcsetattr (fd, TCSANOW, &termios_new); if (-1 == retval) { close(fd); return -4; } this->fd=fd; this->setdirection(LINK_DIRE_LINKTO); if(LINK_CHECK_NOT == parg->checkmethod) { this->setstate(LINK_STATE_GOOD); } else { this->setstate(LINK_STATE_CHECK); } setcheckmethod(parg->checkmethod); return 0;}int clinkcom::setportattrib(const scomarg *parg){ bzero (&termios_new, sizeof (termios_new)); cfmakeraw (&termios_new); setbaudrate (parg->baudrate); termios_new.c_cflag |= CLOCAL | CREAD; setflowcontrol (parg->fctrl); setdatabit (parg->databit); setparitycheck (parg->parity); setstopbit (parg->stopbit); termios_new.c_oflag = 0; termios_new.c_lflag |= 0; termios_new.c_oflag &= ~OPOST; termios_new.c_cc[VTIME] = 1; //* unit: 1/10 second. */ termios_new.c_cc[VMIN] = 1; //* minimal characters for reading */ return 0;}/* * Function: static INT32 BAUDRATE (INT32 baudrate) * Arguments: INT32 baudrate; * Description: convert baudrate from INT32 to MACRO B** */int clinkcom::baudrate(int baudrate){ switch (baudrate) { case 0: return (B0); case 50: return (B50); case 75: return (B75); case 110: return (B110); case 134: return (B134); case 150: return (B150); case 200: return (B200); case 300: return (B300); case 600: return (B600); case 1200: return (B1200); case 2400: return (B2400); case 4800: return (B4800); case 9600: return (B9600); case 19200: return (B19200); case 38400: return (B38400); case 57600: return (B57600); case 115200: return (B115200); default: return (B9600); }}/* * Function: static INT32 _BAUDRATE (INT32 baudrate) * Arguments: INT32 baudrate; * Description: convert baudrate from MACRO B** to INT32 */int clinkcom::_baudrate(int baudrate){//* reverse baudrate */ switch (baudrate) { case B0: return (0); case B50: return (50); case B75: return (75); case B110: return (110); case B134: return (134); case B150: return (150); case B200: return (200); case B300: return (300); case B600: return (600); case B1200: return (1200); case B2400: return (2400); case B4800: return (4800); case B9600: return (9600); case B19200: return (19200); case B38400: return (38400); case B57600: return (57600); case B115200: return (115200); default: return (9600); }}int clinkcom::getbaudrate (){ return (_baudrate(cfgetospeed (&termios_new)));}/* * Function: static void SetBaudrate (INT32 baudrate) * Arguments: INT32 baudrate; * Description: set serial port baudrate by use of file descriptor fd */void clinkcom::setbaudrate (int baudrate){ termios_new.c_cflag = this->baudrate (baudrate); //* set baudrate */}/* * Function: static static void SetDataBit (INT32 databit) * Arguments: INT32 databit; * Description: Set databit; */void clinkcom::setdatabit (char databit){ termios_new.c_cflag &= ~CSIZE; switch (databit) { case 8: termios_new.c_cflag |= CS8; break; case 7: termios_new.c_cflag |= CS7; break; case 6: termios_new.c_cflag |= CS6; break; case 5: termios_new.c_cflag |= CS5; break; default: termios_new.c_cflag |= CS8; break; }}/* * Function: static void SetStopBit (const char *stopbit) * Arguments: const char *stopbit; * Description: Set Stop Bit */void clinkcom::setstopbit (const char *stopbit){ if (0 == strcmp (stopbit, "1")) { termios_new.c_cflag &= ~CSTOPB; //* 1 stop bit */ } else if (0 == strcmp (stopbit, "1.5")) { termios_new.c_cflag &= ~CSTOPB; //* 1.5 stop bits */ } else if (0 == strcmp (stopbit, "2")) { termios_new.c_cflag |= CSTOPB; //* 2 stop bits */ } else { termios_new.c_cflag &= ~CSTOPB; //* 1 stop bit */ }}/* * Function: static void SetParityCheck (char parity) * Arguments: char parity; * Description: Set Parity Check */void clinkcom::setparitycheck (char parity){ switch (parity) { case 'N': //* no parity check */ termios_new.c_cflag &= ~PARENB; break; case 'E': //* even */ termios_new.c_cflag |= PARENB; termios_new.c_cflag &= ~PARODD; break; case 'O': //* odd */ termios_new.c_cflag |= PARENB; termios_new.c_cflag |= ~PARODD; break; default: //* no parity check */ termios_new.c_cflag &= ~PARENB; break; }}/* * Function: static void SetFlowControl(INT32 fctrl) * Arguments: INT32 fctrl; * 0: No Flow Control; * 1: Hardware Control; * 2: Software Control; */void clinkcom::setflowcontrol (char fctrl){ switch (fctrl) { case 0: termios_new.c_cflag &= ~CRTSCTS; break; case 1: default: termios_new.c_cflag |= CRTSCTS; break; case 2: break; }}//读当前连接的数据/*int clinkcom::read(void *buff,int len,int flags){ if(true == this->isdead()) { return -1; } return ::read(this->getfd(),buff,len);*//* INT32 retval = 0; fd_set fs_read; if (!bOpen) { return (E_NOTOPEN); } FD_ZERO (&fs_read); FD_SET (fd, &fs_read); tv_timeout.tv_sec = TIMEOUT_SEC (datalength, GetBaudrate ()); tv_timeout.tv_usec = TIMEOUT_USEC; retval = select (fd + 1, &fs_read, NULL, NULL, &tv_timeout); if (retval) { return (read (fd, data, datalength)); } else { return (E_NODATA); }*//*}*//* INT32 retval = 0; fd_set fs_read; if (!bOpen) { return (E_NOTOPEN); } FD_ZERO (&fs_read); FD_SET (fd, &fs_read); tv_timeout.tv_sec = TIMEOUT_SEC (datalength, GetBaudrate ()); tv_timeout.tv_usec = TIMEOUT_USEC; retval = select (fd + 1, &fs_read, NULL, NULL, &tv_timeout); if (retval) { return (read (fd, data, datalength)); } else { return (E_NODATA); }*//*}*//* debugprint("write com len %d\n",len); if(true == this->isdead()) { return -1; } int ret=-1; int retlen=0; int writelen=len; char *p=(char *)buff; if(len<=0) { return len; } while(writelen>0) { ret=::write(this->getfd(),p,writelen); if(ret==-1) { seterror(LINK_ERROR_CLOSE); break; } else if(ret <=0) { break; } writelen -= ret; retlen += ret; p += ret; } tcflush (this->getfd(), TCOFLUSH); // flush all output datadebugprint("write com ret %d,retlen=%d\n",ret,retlen); if(ret!=len) {// writelogfile(TYPEERROR|DESTTX|DESTSTD|DISPALL,// "write socket %s error\n",this->getsockinfo()); return -1; } else {// writelogfile(TYPENORMAL|DESTTX|DESTSTD|DISPALL,// "write socket %s LEN=%d\n",this->getsockinfo(),len); return retlen; }*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -