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

📄 comport.cpp

📁 通过GSM模块接收和发送短信的代码。在eVC4.0下编译通过
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "stdafx.h"
#include "Resource.h"
#include "ComPort.h"

#include "ReadSMS.h"
#define MAX_SAVE_SMS 20//最大存储数量
#define TALK_CONTINUE 300//异常时通话时长:1/10秒为单位
#define REGCHECK_INTERVAL 1//异常时通话时长:秒为单位
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

CComPort port;
CReadSMS *pread;
#include "PortPe.h"
extern CPortPeApp theApp;

//extern CPortPeDlg dlg;

CComPort::CComPort ()
{
	strcpy(DataSaveBuff,"\0");
	pTail=new CmdStruct;
	memset(pTail,0,sizeof(CmdStruct));
	pTail->iserial =0;
	pTail->iType =0;
	pTail->next =NULL;
	pTail->iLen =0;
	strcpy(pTail->Param ,"\0");

	pHeader=pTail;
	m_hList=CreateEvent (NULL,TRUE,FALSE,NULL);

	iRing=0;
}
CComPort::~CComPort()
{
}
//数据发送端口
DWORD WINAPI ProcSendData(void *)   //读串口线程
{
	try
	{
		HANDLE hWait=CreateEvent (NULL,TRUE,TRUE,NULL);
		BOOL bWait=TRUE;

		LPCmdStruct temp;
		int i=0;
		int iIdle=0;
		char tp[64]="\0";
		while(TRUE)
		{
			temp=port.pHeader ;
			if (strlen(port.pHeader->Param)>0)//有数据
			{
				//发送数据,计数归零
				iIdle=0;
				//发送命令;拨号
				if (1 == port.pHeader->iType)
					port.SendData (port.pHeader->Param );
				else if(3 == port.pHeader->iType)
				{
					port.LocalVoice (1);
					port.SendData (port.pHeader->Param );
				}
				else
					port.SendData (port.pHeader->Param ,port.pHeader->iLen );

				strcpy(port.pHeader->Param ,"\0");
				i=0;//初始化循环计数
				BOOL bTalk=FALSE;
				do
				{
					i++;
					ResetEvent (port.m_CmdFinish);
					port.ReadData ();
					if(WaitForSingleObject (port.m_CmdFinish,100) == WAIT_OBJECT_0)
					{
						if( 3 == port.pHeader->iType  )//拨打电话
						{
							//WaitForSingleObject (port.m_CmdFinish,1000*15);
							if (!bTalk)
							{
								i=0;
								bTalk=TRUE;
							}
							else
							{
								if (i>TALK_CONTINUE )
									break;
							}
						}
						else 
						{
							break;
						}
					}
					if (i>50 && (3 != port.pHeader->iType))
						break;
					if (i>TALK_CONTINUE && (3 == port.pHeader->iType))
						break;
				}while(TRUE);

				bWait=FALSE;
			}

			strcpy(port.pHeader->Param,"\0");
			if (port.pHeader->next != NULL)
			{
				//释放资源
				port.pHeader=port.pHeader->next;
				delete []temp;

				ResetEvent (port.m_hList);
				WaitForSingleObject (port.m_hList,100);
				SetEvent (port.m_hList );
			}
			else//等待有内容
			{
				//MessageBox(NULL,TEXT("等待命令"),TEXT("系统提示信息"),MB_OK);
				port.ReadData ();
				if (bWait)
				{
				//MessageBox(NULL,TEXT("开始等待"),TEXT("系统提示信息"),MB_OK);
					ResetEvent (port.m_hList);
					WaitForSingleObject (port.m_hList,1000);
					SetEvent (port.m_hList );
					iIdle++;

					//空闲到一定时间
					if (iIdle >60*5)
					{						
						port.SetList (1,"AT+CMGL=4\r\0");
						iIdle=0;
					}
				}
				else
					bWait=TRUE;
			}
		}
		MessageBox(NULL,TEXT("退出发送"),TEXT("系统提示信息"),MB_OK);
	}
	catch(...)
	{
		MessageBox(NULL,TEXT("退出发送"),TEXT("系统提示信息"),MB_OK);
	}
	return TRUE;
}


//定时监测是否有报警
DWORD WINAPI ProcAlarm(void *)
{
	HANDLE hWait=CreateEvent (NULL,TRUE,FALSE,NULL);
	BOOL bAlarm=FALSE;
	char tel[32]="ATD\0";
	int iAlarm=1;
	while(TRUE)
	{
		WaitForSingleObject (hWait,1000*REGCHECK_INTERVAL);
		ResetEvent (hWait);

		bAlarm=FALSE;
		HKEY hKey;
		DWORD dwType=REG_DWORD;
		BYTE nBuf[128];
		DWORD dwLen;
		// regOpen
		hKey = 0;
		RegOpenKeyEx(HKEY_CURRENT_USER,TEXT("PLINK"),0,
			0,&hKey);
		
		// status
		memset(nBuf,0,sizeof(nBuf));
		dwLen = 128;
		RegQueryValueEx(hKey,TEXT("Alarm_Status"),0,&dwType,
			nBuf,&dwLen);
		
		if((nBuf[0] & 0x01) == 0x01) //0bit,RING
		{
			port.EncodeSMSBody(TEXT("RING报警"),theApp.AppSetup.SAFE1,2);
			port.EncodeSMSBody(TEXT("RING报警"),theApp.AppSetup.SAFE2,2);
			bAlarm=TRUE;
			//拨打电话
			port.LocalVoice (1);
			strcat(tel,theApp.AppSetup.SAFE1);
			strcat(tel,";\r");
			port.SetList (3,tel);
			port.SetList (1,"ATH\r");
			strcpy(tel,"ATD");
			strcat(tel,theApp.AppSetup.SAFE2);
			strcat(tel,";\r");
			port.SetList (3,tel);
			port.SetList (1,"ATH\r");
		}
		if(((nBuf[0]>>0x01) & 0x01) == 0x01)  //1bit,sos
		{
			port.EncodeSMSBody(TEXT("sos报警测试"),theApp.AppSetup.SOS1,2);
			port.EncodeSMSBody(TEXT("sos报警测试"),theApp.AppSetup.SOS2,2);
			
			bAlarm=TRUE;
			//拨打电话
			port.LocalVoice (1);
			strcat(tel,theApp.AppSetup.SOS1);
			strcat(tel,";\r");
			port.SetList (3,tel);
			port.SetList (1,"ATH\r");
			strcpy(tel,"ATD");
			strcat(tel,theApp.AppSetup.SOS1);
			strcat(tel,";\r");
			port.SetList (3,tel);
			port.SetList (1,"ATH\r");
		}
		if(((nBuf[0]>>0x02) & 0x01) == 0x01)  //2bit,BUGR ALARM
		{
			port.EncodeSMSBody(TEXT("BUGR ALARM报警测试"),theApp.AppSetup.SAFE1,2);
			port.EncodeSMSBody(TEXT("BUGR ALARM报警测试"),theApp.AppSetup.SAFE2,2);
			bAlarm=TRUE;
			//拨打电话
			port.LocalVoice (1);
			strcat(tel,theApp.AppSetup.SAFE1);
			strcat(tel,";\r");
			port.SetList (3,tel);
			port.SetList (1,"ATH\r");
			strcpy(tel,"ATD");
			strcat(tel,theApp.AppSetup.SAFE2);
			strcat(tel,";\r");
			port.SetList (3,tel);
			port.SetList (1,"ATH\r");
		}
		if(((nBuf[0]>>0x03) & 0x01) == 0x01)  //3bit,SPARE ALARM
		{
			port.EncodeSMSBody(TEXT("SPARE ALARM报警测试"),theApp.AppSetup.SAFE1,2);
			port.EncodeSMSBody(TEXT("SPARE ALARM报警测试"),theApp.AppSetup.SAFE2,2);
			bAlarm=TRUE;
			//拨打电话
			port.LocalVoice (1);
			strcat(tel,theApp.AppSetup.SAFE1);
			strcat(tel,";\r");
			port.SetList (3,tel);
			port.SetList (1,"ATH\r");
			strcpy(tel,"ATD");
			strcat(tel,theApp.AppSetup.SAFE2);
			strcat(tel,";\r");
			port.SetList (3,tel);
			port.SetList (1,"ATH\r");
		}
		if(((nBuf[0]>>0x05) & 0x01) == 0x01)  //5bit,ACC ON
		{
			port.EncodeSMSBody(TEXT("ACC ON报警测试"),theApp.AppSetup.SAFE1,2);
			port.EncodeSMSBody(TEXT("ACC ON报警测试"),theApp.AppSetup.SAFE2,2);
			bAlarm=TRUE;
			//拨打电话
			port.LocalVoice (1);
			strcat(tel,theApp.AppSetup.SAFE1);
			strcat(tel,";\r");
			port.SetList (3,tel);
			port.SetList (1,"ATH\r");
			strcpy(tel,"ATD");
			strcat(tel,theApp.AppSetup.SAFE2);
			strcat(tel,";\r");
			port.SetList (3,tel);
			port.SetList (1,"ATH\r");
		}
		
		//复位		
		if (bAlarm)
		{
			memset(nBuf,0,sizeof(nBuf));
			dwLen = 128;
			RegSetValueEx(hKey,TEXT("Alarm_Status"),0,dwType,nBuf,dwLen);
#ifdef	TEST
			port.dlg->m_lst.InsertItem (0,TEXT("系统报警测试"));
#endif
		}
#ifdef	TEST
		else
		{
			//nBuf[0]=iAlarm;
			//RegSetValueEx(hKey,TEXT("Alarm_Status"),0,dwType,nBuf,dwLen);
			//port.dlg->m_lst.InsertItem (0,TEXT("没有报警"));

			iAlarm *= 2;
			if (iAlarm ==32 ) 
				iAlarm=1;
		}
#endif
		RegCloseKey(hKey);	
	}
}

BOOL CComPort::InitComPort(TCHAR sComNo[] )
{
	try
	{
		DCB dcb;                         //配置串口使用的结构。
		COMMTIMEOUTS TimeOuts;           //设置读写串口的超时所用的结构。
		DWORD dwMask,dwError;                    //设置串口的事件屏蔽码。
		TCHAR Msg[256]=TEXT("\0");

		//检索短信中心号码
		TCHAR temp[256]=TEXT("\0");
		
		//1、打开串口:可读写,不可共享,已存在,重叠操作
		m_hComm =CreateFile(sComNo,GENERIC_READ|GENERIC_WRITE,
			0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
		if(m_hComm==INVALID_HANDLE_VALUE)
		{
			dwError=GetLastError ();
			swprintf(Msg,TEXT("%u"),dwError);
			MessageBox(NULL,Msg,Msg,MB_OK);
			return FALSE;
		}

		//2、设置串口
		dcb.DCBlength =sizeof(DCB);
		if(!(GetCommState (m_hComm,&dcb)))   //得到当前串口的设置值,并填充到DCB结构中
		{
			CloseHandle (m_hComm);           //发生错误,关闭打开的文件句柄
			dwError=GetLastError ();
			swprintf(Msg,TEXT("%u"),dwError);
			MessageBox(NULL,Msg,TEXT("错误提示"),MB_OK);
			return FALSE;
		}
		dcb.DCBlength =sizeof(DCB);
		dcb.BaudRate =38400;//(unsigned long)rweslog.GetStringFromINI ("SPEED");           //设置串口的波特率:19200
		dcb.ByteSize =8;                   //每字的位数:8
		dcb.fParity  =FALSE;               //不支持校验动作
		dcb.Parity   =NOPARITY;            //没有校验位
		dcb.StopBits =ONESTOPBIT;          //一个停止位
		//dcb.fBinary  =TRUE;                //二进制模式传输
		//dcb.
		if(!(SetCommState (m_hComm,&dcb)))   //使用以上设置值的DCB结构设置串口
		{
			CloseHandle (m_hComm);           //发生错误,关闭打开的文件句柄
			swprintf(Msg,TEXT("%u"),GetLastError ());
			MessageBox(NULL,TEXT("SetCommState:"),Msg,MB_OK);
			return FALSE;
		}
		//设置DCB完成
		//3、设置I/O缓冲区大小:输入缓冲区&输出换缓冲区的大小:2048 Byte
		if(!(SetupComm (m_hComm,2048,2048)))
		{
			CloseHandle (m_hComm);           //发生错误,关闭打开的文件句柄
			swprintf(Msg,TEXT("%u"),GetLastError ());
			MessageBox(NULL,TEXT("SetupComm:"),Msg,MB_OK);
			return FALSE;
		}
		//串口缓冲区设置完毕

		//4、设置读写超时限制
		if(!(GetCommTimeouts (m_hComm,&TimeOuts)))     //获取系统当前的超时限制设置值
		{
			CloseHandle (m_hComm);           //发生错误,关闭打开的文件句柄
			swprintf(Msg,TEXT("%u"),GetLastError ());
			MessageBox(NULL,TEXT("GetCommTimeouts:"),Msg,MB_OK);
			return FALSE;
		}
		TimeOuts.ReadIntervalTimeout         =500;    //读字符时间间隔
		TimeOuts.ReadTotalTimeoutMultiplier  =500;    //读字符时间系数
		TimeOuts.ReadTotalTimeoutConstant    =5000;   //读数据超时常量
		TimeOuts.WriteTotalTimeoutMultiplier =500;    //写字符时间系数
		TimeOuts.WriteTotalTimeoutConstant   =5000;   //写字符超时常量

		if(!(SetCommTimeouts (m_hComm,&TimeOuts))) //使用以上设置值得的COMMTIMEOUTS结构设置读写超时限制
		{
			CloseHandle (m_hComm);           //发生错误,关闭打开的文件句柄
			swprintf(Msg,TEXT("%u"),GetLastError ());
			MessageBox(NULL,TEXT("SetCommTimeouts:"),Msg,MB_OK);
			return FALSE;
		}
		//读写超时限制设置完毕

		//5、设置串口事件屏蔽码
		if(!(GetCommMask (m_hComm,&dwMask)))   //获取系统当前事件屏蔽码的设置值
		{
			CloseHandle (m_hComm);           //发生错误,关闭打开的文件句柄
			swprintf(Msg,TEXT("%u"),GetLastError ());
			MessageBox(NULL,TEXT("GetCommMask:"),Msg,MB_OK);
			return FALSE;
		}

		//设置事件屏蔽码为:EV_RXCHAR.即:输入缓冲区收到一个新字符时产生事件
		dwMask=EV_BREAK|EV_CTS|EV_DSR|EV_ERR|EV_RING|EV_RLSD|EV_RXCHAR|EV_RXFLAG|EV_TXEMPTY;     
		if(!(SetCommMask (m_hComm,dwMask)))
		{
			CloseHandle (m_hComm);           //发生错误,关闭打开的文件句柄
			swprintf(Msg,TEXT("%u"),GetLastError ());
			MessageBox(NULL,TEXT("SetCommMask:"),Msg,MB_OK);
			return FALSE;
		}
		//串口事件屏蔽码设置完毕
		//创建事件对象:标示是否可以读写
		//m_Events=CreateEvent(NULL,TRUE,FALSE,NULL);

		//标示命令是否完成
		m_CmdFinish=CreateEvent(NULL,TRUE,TRUE,NULL);
		SetList (1,"AT\r");
		SetList (1,"ATE0\r");
		SetList (1,"AT+CMGF=0\r");
		SetList (1,"AT^SSYNC=1\r");
		SetList (1,"AT^SNFS=4\r");
		SetList (1,"AT^SNFO=1,10337,11598,13104,14602,16999,4,0\r");

		//
		SetList (1,"AT+CNMI=1,1\r");
		SetList (1,"AT+CLIP=1\r");
		SetList (1,"AT+CMEE=1\r");
		//枚举短信内容
		SetList (1,"AT+CMGL=4\r\0");	

		DWORD   dwThreadId    = 0;
		hProcSend=CreateThread ((LPSECURITY_ATTRIBUTES)NULL,(DWORD)0,
			(LPTHREAD_START_ROUTINE)&ProcSendData,(LPVOID)NULL,(DWORD)0,(LPDWORD)&dwThreadId);
		if(hProcSend==NULL)
		{
			CloseHandle (m_hComm);             //发生错误,关闭打开的文件句柄
			MessageBox(NULL, TEXT("系统无法接管通信前置机!"),TEXT("系统提示信息"),MB_OK);
			return FALSE;
		}

		hProcAlarm=CreateThread ((LPSECURITY_ATTRIBUTES)NULL,(DWORD)0,
			(LPTHREAD_START_ROUTINE)&ProcAlarm,(LPVOID)NULL,(DWORD)0,(LPDWORD)&dwThreadId);
		if(hProcSend==NULL)
		{
			CloseHandle (m_hComm);             //发生错误,关闭打开的文件句柄
			MessageBox(NULL, TEXT("系统无法接管通信前置机!"),TEXT("系统提示信息"),MB_OK);
			return FALSE;
		}
	}
	catch(...)
	{

⌨️ 快捷键说明

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