⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttyfun.c

📁 在GPRS或者CDMA modem上实现发送/接收短信的C代码;支持Siemens
💻 C
字号:
/** Modify Records:* 2007-01-25    when writing tty fails, it need to check the errno,*               if errno equals to EINTR or EAGAIN, continue to write.*/#include <stdio.h>      #include <stdlib.h>     #include <stdarg.h>       #include <fcntl.h>          #include <errno.h>#ifndef _LINUX_#define _LINUX_#endif#ifdef _LINUX_#include <termios.h>#include <unistd.h>#include <sys/termios.h>#include <sys/types.h>  #include <sys/stat.h>#include <sys/ioctl.h>#else#include <windows.h>#endif#include "ttyfun.h"/*********************************************** extern variales**********************************************/extern char debugType;extern void WMMP_TRACE(char type, const char *format, ...);//interior functions and variablesint gttyfd; //tty file descriptorint opentty(const char *dev);int initialtty(int fd, int inspeed,int databits,int stopbits,int parity,int crtscts);int readtty(int fd, int len, int timeout, void *pRecv, int *pRetLen);int writetty(int fd, int len, int timeout, const void *pSend);int cleartty(int fd);int closetty(int fd);#ifdef _LINUX_void wmmp_set_up_tty(int tty_fd, int local,int inspeed,int crtscts,int parity,int databits,int stopbits,int mode);#define ok_error(num) ((num)==EIO)struct wmmp_speed {    int speed_int, speed_val;} wmmp_speeds[] = {#ifdef B50    { 50, B50 },#endif#ifdef B75    { 75, B75 },#endif#ifdef B110    { 110, B110 },#endif#ifdef B134    { 134, B134 },#endif#ifdef B150    { 150, B150 },#endif#ifdef B200    { 200, B200 },#endif#ifdef B300    { 300, B300 },#endif#ifdef B600    { 600, B600 },#endif#ifdef B1200    { 1200, B1200 },#endif#ifdef B1800    { 1800, B1800 },#endif#ifdef B2000    { 2000, B2000 },#endif#ifdef B2400    { 2400, B2400 },#endif#ifdef B3600    { 3600, B3600 },#endif#ifdef B4800    { 4800, B4800 },#endif#ifdef B7200    { 7200, B7200 },#endif#ifdef B9600    { 9600, B9600 },#endif#ifdef B19200    { 19200, B19200 },#endif#ifdef B38400    { 38400, B38400 },#endif#ifdef B57600    { 57600, B57600 },#endif#ifdef B115200    { 115200, B115200 },#endif#ifdef EXTA    { 19200, EXTA },#endif#ifdef EXTB    { 38400, EXTB },#endif#ifdef B230400    { 230400, B230400 },#endif#ifdef B460800    { 460800, B460800 },#endif    { 0, 0 }};static int translate_speed (int bps){    struct wmmp_speed *speedp;    if (bps != 0) {	for (speedp = wmmp_speeds; speedp->speed_int; speedp++) {	    if (bps == speedp->speed_int)		return speedp->speed_val;	}	//DAEMON_WMMP_TRACE("speed %d not supported", bps);    }    return 0;}void wmmp_setdtr (int tty_fd, int on){    int modembits = TIOCM_DTR;    //DAEMON_WMMP_TRACE("setdtr,tty_fd:%d,value:%d\n",tty_fd,on);    ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);}//dev = "/dev/ttyS1"int opentty(const char* dev){		gttyfd = open(dev, O_RDWR|O_NOCTTY|O_NONBLOCK);	if(gttyfd < 0)	{		WMMP_TRACE(debugType, "Error: Open Serial fail!!!\n");	}    return gttyfd;}int initialtty(int fd, int inspeed, int databits, int stopbits, int parity, int crtscts){    wmmp_set_up_tty(fd, 0, inspeed, crtscts, parity, databits, stopbits, 0);    return 0;}int cleartty(int fd){	tcflush(fd, TCIOFLUSH);		return 0;}int closetty(int fd){	int ret = 0;    ret = close(fd);	if(ret < 0)    {        WMMP_TRACE(debugType, "Failed to close tty resource\n");	    goto closetty_fail;    }    else    {       	 WMMP_TRACE(debugType, "Succ to close tty resource\n");    }     	     return 0;closetty_fail:    return -1;}int readtty(int fd, int len, int timeout, void * pRecv, int * pRetLen){	int ret = 0;	int iTotalLen = 0;	int iLeftLen = 0;	int utime= timeout;// * 1000;	struct timeval time_start, time_cur;	char *pBuf = NULL;//(uchar*)pRecv;	iTotalLen = 0;	iLeftLen = len;	utime = timeout;// * 1000;//ms	pBuf = (char*)pRecv;	gettimeofday(&time_start, NULL);	gettimeofday(&time_cur, NULL);	while((time_cur.tv_sec - time_start.tv_sec) < utime)	{		ret = read(fd, pBuf + iTotalLen, iLeftLen);		if(ret >= 0)		{			iLeftLen -= ret;			iTotalLen += ret;		}		else if(errno == EINTR || errno == EAGAIN)		{		     gettimeofday(&time_cur, NULL);		     continue;		}		else        {             return -1;        }		if(iLeftLen == 0)		{			break;		}		gettimeofday(&time_cur, NULL);	}	*pRetLen = iTotalLen;	WMMP_TRACE(debugType, "\r\nReadTty: %s\r\n", pRecv);		return 0;}int writetty(int fd, int len, int timeout, const void *pSend){	int ret = 0;	int iLeftLen = 0;	int iSentLen = 0;	int utime = 0;	struct timeval time_start, time_cur;	char *pBuf = NULL;	iLeftLen = len;	iSentLen = 0;	utime = timeout;// * 1000;	pBuf = (char*)pSend;	gettimeofday(&time_start, NULL);	gettimeofday(&time_cur, NULL);	WMMP_TRACE(debugType, "\r\nWriteTty: %s\r\n", pBuf);	while((time_cur.tv_sec - time_start.tv_sec) < utime)	{			ret = write(fd, pBuf + iSentLen, iLeftLen);		if(ret >= 0)		{			iLeftLen -= ret;			iSentLen += ret;		}		else//	if()		{			if(errno == EINTR || errno == EAGAIN)			{//add in 2007-01-25 by ljs				WMMP_TRACE(debugType, "Error: INTR or EAGAIN\r\n");				gettimeofday(&time_cur, NULL);				continue;		        }			WMMP_TRACE(debugType, "Error: write tty\r\n");			return -1;		}		if(iLeftLen == 0)		{			break;		}		gettimeofday(&time_cur, NULL);	}	if(iLeftLen > 0)	{		WMMP_TRACE(debugType, "Error: send not all data\r\n");		return -2;	}		return 0;}int wait_for_OK(int fd, const char *szMatch, uint uiTime){	char szTemp[1000];	int iRet;	int iRetCount = 0;	int iLeftCount = 0;	ulong utime = uiTime ;// * 1000000;	struct timeval time_start, time_cur;		memset(szTemp,0x00,sizeof(szTemp));	gettimeofday(&time_start, NULL);	gettimeofday(&time_cur, NULL);		iLeftCount = sizeof(szTemp);	while((time_cur.tv_sec - time_start.tv_sec) < utime)	{	      	iRet = read(fd, szTemp+iRetCount, iLeftCount);			if(iRet>=0)			{				iRetCount += iRet;				iLeftCount -= iRet;				if( (strstr(szTemp,szMatch))!=NULL )				{					WMMP_TRACE(debugType, "\r\nreceived string match: %s", szTemp);					iRetCount=0;					return 0;				}				if( (strstr(szTemp,"ERROR"))!=NULL )				{ 					WMMP_TRACE(debugType, "\r\nError: received ERROR after sending SMS");					WMMP_TRACE(debugType, "\r\nszTemp: %s", szTemp);					return -1;				}							}			else			{				switch(errno)				{				case EINTR:				case EAGAIN:					break;				case EBADF:					{						WMMP_TRACE(debugType, "Read Err: Illegal ttyfd\r\n");						break;					}				default:					{						WMMP_TRACE(debugType, "Read Err:Unknown\r\n");						break;					}				}				if(errno == EINTR || errno == EAGAIN)				{					gettimeofday(&time_cur, NULL);					continue;				}				return -1;			}			gettimeofday(&time_cur, NULL);	} 		if((time_cur.tv_sec - time_start.tv_sec) >= utime)	{		WMMP_TRACE(debugType, "Error: wait for OK timeout!\r\n");		WMMP_TRACE(debugType, "szTemp: %s\r\n", szTemp);		return -2;	}		return 0;}void wmmp_set_up_tty(int tty_fd, int local,int inspeed,int crtscts,int parity,int databits,int stopbits,int mode){    int speed;    struct termios tios;    wmmp_setdtr(tty_fd, 1);        if (tcgetattr(tty_fd, &tios) < 0) {	if (!ok_error(errno))	    WMMP_TRACE(debugType, "\r\ntcgetattr: %m(%d)", errno);	return;    }        //Ignore modem control lines,enable receiver,ignore break    tios.c_cflag |= (CLOCAL | CREAD | IGNBRK);	            switch (parity)     {   	case NO_PARITY:    		tios.c_cflag &= ~PARENB;   /* Clear parity enable */		//tios.c_iflag &= ~INPCK;     /* Enable parity checking */		tios.c_iflag &=~(INPCK |ISTRIP);		tios.c_iflag |= IGNPAR;		break;  	case ODD_PARITY:     		tios.c_cflag |= (PARODD | PARENB);  		tios.c_iflag |= INPCK;             /* Disnable parity checking */ 		break;  	case EVEN_PARITY:   		tios.c_cflag |= PARENB;     /* Enable parity */    		tios.c_cflag &= ~PARODD;        		tios.c_iflag |= INPCK;       /* Disnable parity checking */		break;	 	default:   		//DAEMON_WMMP_TRACE("Not supported parity,set no parity\n");    		tios.c_cflag &= ~PARENB;   /* Clear parity enable */		tios.c_iflag &= ~INPCK;     /* Enable parity checking */				break;     }        tios.c_cflag &= ~CSIZE;    switch (databits) /**/    {   	case 7:				tios.c_cflag |= CS7; 		break;	case 8:     		tios.c_cflag |= CS8;		break;   	default:    		//DAEMON_WMMP_TRACE("Not supported databits,set 8\n");		tios.c_cflag |= CS8;		break;      }    switch (stopbits)    {   	case 1:    		tios.c_cflag &= ~CSTOPB;  		break;  	case 2:    		tios.c_cflag |= CSTOPB;  	   	break;	default:    		//DAEMON_WMMP_TRACE("Not supported stopbits,set 1\n"); 		tios.c_cflag &= ~CSTOPB;  		break;     }          if(mode==0)    {//RAW MODE    	//tios.c_oflag &= ~OPOST;    	//tios.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);    	tios.c_iflag &=~(INLCR | IGNCR | ICRNL);		//NL to CR,ignore CR,CR to NL    		    	tios.c_lflag=0;    	tios.c_oflag=0;    }           switch (crtscts) {        case FLOWCTR_HARDWARE:	    tios.c_cflag |= CRTSCTS;		    break;    case FLOWCTR_XONXOFF:	    tios.c_iflag     |= IXON | IXOFF;	    tios.c_cc[VSTOP]  = 0x13;	/* DC3 = XOFF = ^S */	    tios.c_cc[VSTART] = 0x11;	/* DC1 = XON  = ^Q */		    break;    case FLOWCTR_NONE:    	tios.c_iflag&=~(IXON|IXOFF|IXANY);	    tios.c_cflag &= ~CRTSCTS;		    break;    default:	    break;    }            tios.c_cc[VMIN]     = 1;    tios.c_cc[VTIME]    = 0;          speed = translate_speed(inspeed);    if (speed) {	cfsetospeed (&tios, speed);	cfsetispeed (&tios, speed);    }/* * We can't proceed if the serial port speed is B0, * since that implies that the serial port is disabled. */    else {	speed = cfgetospeed(&tios);	/*if (speed == B0)	    DAEMON_WMMP_TRACE("Baud rate for ttyS1 is 0; need explicit baud rate");*/    }    if (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0)	if (!ok_error(errno))	    ;//DAEMON_WMMP_TRACE("error: tcsetattr");        //baud_rate = baud_rate_of(speed);    //restore_term = 1;}#else#include <stdio.h> #include <stdlib.h>    #include <stdarg.h> #include <fcntl.h> #include <errno.h>#include <windows.h>#include "ttyfun.h"#include "typedef.h"HANDLE ghCom = INVALID_HANDLE_VALUE;int gttyfd; //tty file descriptorint opentty(const char *dev){	int err = 0;		ghCom = CreateFile(dev, /*device name*/		           GENERIC_WRITE | GENERIC_READ,  /*share mode*/			   0, /**/			   NULL,  /*no security attr.*/					   OPEN_EXISTING,                 /*comm must be open using OPEN_EXISTING*/					   0,                             /*not overlapped I/O*/					   NULL);                         /*hTemplate must be NULL for comm devices*/	if(ghCom == INVALID_HANDLE_VALUE)	{		err =  GetLastError();		goto opentty_fail;	}	gttyfd = (int)ghCom;	return gttyfd;opentty_fail:	return -1;}int initialtty(int fd, int inspeed,int databits,int stopbits,int parity,int crtscts){	int err = 0;	BOOL bRet = FALSE;	DCB dcb;	char szDcb[50];	COMMTIMEOUTS m_CommTimeouts;	//Fill in the DCB: baud, 8 data bits, no parity, and 1 stop bit	memset(szDcb, 0, sizeof(szDcb));	sprintf(szDcb, "baud=%d parity=N data=8 stop=1", inspeed);		bRet = GetCommState(ghCom, &dcb);	if (bRet == FALSE)	{		err = GetLastError();		goto initialtty_fail;	}		dcb.fRtsControl = RTS_CONTROL_ENABLE;	dcb.fDtrControl = DTR_CONTROL_ENABLE;	bRet = BuildCommDCB(szDcb, &dcb);	if (bRet == FALSE)	{		err = GetLastError();		goto initialtty_fail;	}	// set the timeout values	m_CommTimeouts.ReadIntervalTimeout = 1000;	m_CommTimeouts.ReadTotalTimeoutMultiplier = 0;	m_CommTimeouts.ReadTotalTimeoutConstant = 500;	m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;	m_CommTimeouts.WriteTotalTimeoutConstant = 1000;	SetCommTimeouts(ghCom, &m_CommTimeouts);		bRet = SetCommState(ghCom, &dcb);	if (!bRet)	{		err = GetLastError();		goto initialtty_fail;	}	return 0;initialtty_fail:	return -1;}//may be problemint readtty(int fd, int len, int timeout, void *pRecv, int *pRetLen){	DWORD dwRet = 0;	int iRead = 0;	int iRetCount = 0;	int iLeftCount = 0;	long utime = timeout * 1000;	long time_start, time_cur;	iLeftCount = len;	time_start = GetTickCount();	time_cur   = GetTickCount();	while ((time_cur - time_start) < utime)	{		dwRet = ReadFile(ghCom, (char*)pRecv + iRetCount, iLeftCount, &iRead, NULL);		if(dwRet && iRead > 0)		{//get some data			iRetCount += iRead;			iLeftCount -= iRead;		}		else if (dwRet == 0)		{			if(errno == EINTR || errno == EAGAIN)			{				time_cur = GetTickCount();				continue;			}			goto readtty_fail;		}		time_cur = GetTickCount();	}	*pRetLen = iRetCount;	return 0;readtty_fail:	return -1;}int writetty(int fd, int len, int timeout, const void *pSend){	DWORD dwRet = 0;	DWORD dwWrtn = 0;		dwRet = WriteFile(ghCom, pSend, len, &dwWrtn, NULL);	if (dwRet == 0 || dwWrtn < (DWORD)len)	{		goto WriteFile_fail;	}	return 0;WriteFile_fail:	return -1;}//DORD GetTickCount(VOID);//the return value is the number of milliseconds that have elapsed since the system was startedint wait_for_OK(int fd, const char *szMatch, uint uiTime){	char szTemp[1000];	int iRet;	int iRetCount = 0;			int iLeftCount = 0;	int iRead = 0;	ulong utime = uiTime*1000;	ulong time_start, time_cur;		memset(szTemp,0x00,sizeof(szTemp));	iLeftCount = sizeof(szTemp);		time_start = GetTickCount();	time_cur = GetTickCount();		while((time_cur - time_start) < utime)	{		iRet = ReadFile(ghCom, szTemp+iRetCount, iLeftCount, &iRead, NULL);		if ( iRet && iRead > 0)		{			iRetCount += iRead;			iLeftCount -= iRead;			if( (strstr(szTemp, szMatch))!=NULL )			{				iRetCount=0;				return 0;			}			if( (strstr(szTemp,"ERROR"))!=NULL )			{ 				return -1;			}		}		else if(iRet == 0)		{			if(errno == EINTR || errno == EAGAIN)			{				time_cur = GetTickCount();				continue;			}			return -1;		}				time_cur = GetTickCount();	} 			if((time_cur - time_start) >= utime)	{		return -2;	}		if (strstr(szTemp, szMatch) == NULL)	{		return -3;	}		return 0;}int cleartty(int fd){	PurgeComm(ghCom, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);	return 0;}int closetty(int fd){	BOOL bRet = FALSE ;	bRet = CloseHandle(ghCom);	if(!bRet)	{		goto closetty_fail;	}	ghCom = INVALID_HANDLE_VALUE;	return 0;closetty_fail:	return -1;}int gettotalcomm(char* comm[]){	ulong ulProtNum = 0;	char portName[30], commName[7];	DWORD dwLong, dwSize;	ulong i=0, ulTemp = 0;	HKEY m_hPortKey;	if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, 		"Hardware\\DeviceMap\\SerialComm",		0,		KEY_READ,		&m_hPortKey ) == ERROR_SUCCESS)	{		// 获取注册表子项数					RegQueryInfoKey(m_hPortKey, NULL, NULL, NULL, NULL, 			NULL, NULL, &ulProtNum, NULL, NULL, 0, 0);				while(ulTemp < ulProtNum)		{			dwLong = dwSize = sizeof(portName);			// 枚举串口			if(RegEnumValue(m_hPortKey, i, portName, &dwLong, 				NULL, NULL, (PUCHAR)commName, 				&dwSize ) == ERROR_SUCCESS)//ERROR_NO_MORE_ITEMS)			{				memcpy(comm[ulTemp], commName, strlen(commName));				ulTemp ++;			}			i++;		}	}		return ulProtNum;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -