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

📄 msgctrl.cpp

📁 GPRS拨号包括CMNET,CMWAP ,用程序实现WAP访问.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// MsgCtrl.cpp: implementation of the CMsgCtrl class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MsgCtrl.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMsgCtrl::CMsgCtrl()
{

	m_hComm = NULL;
}

CMsgCtrl::~CMsgCtrl()
{	
	CloseCom();
}

BOOL CMsgCtrl::OpenCom(LPCTSTR lpszComName)
{

	m_hComm = CreateFile( lpszComName,  GENERIC_READ | GENERIC_WRITE, 
	  0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

	if (INVALID_HANDLE_VALUE == m_hComm)
	{
	  m_hComm = NULL;
	  return FALSE;
	}


	DCB dcb;
	memset(&dcb, 0, sizeof(dcb));
	if (!GetCommState(m_hComm, &dcb)) 
	{
		CloseCom();
		return FALSE;
	}
/*
//file://硬件流控制	
	dcb.fDtrControl = DTR_CONTROL_DISABLE;
	dcb.fOutxCtsFlow = FALSE;
	dcb.fRtsControl = RTS_CONTROL_DISABLE;
//file://软件流控制
	dcb.fInX = dcb.fOutX = FALSE;
	dcb.XonChar = (char)0xFF;
	dcb.XoffChar = (char)0XFF;
	dcb.XonLim = 100;
	dcb.XoffLim = 100;
	dcb.EvtChar= 0x0d;
	dcb.fBinary = TRUE;
	dcb.fParity = TRUE;
*/
	dcb.BaudRate = CBR_115200;
	dcb.ByteSize = 8;
	dcb.Parity = NOPARITY;
	dcb.StopBits = ONESTOPBIT;


	if (!SetCommState(m_hComm, &dcb))
	{
		CloseCom();
		return FALSE;
	}
//	PurgeComm(m_hComm, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
//	PurgeComm(m_hComm, PURGE_TXCLEAR|PURGE_RXCLEAR);
	DWORD dwInQueue = 4096;
	DWORD dwOutQueue = 4096;
	SetupComm(m_hComm, dwInQueue, dwOutQueue);

	COMMTIMEOUTS timeouts = 
	{    // 串口超时控制参数
        100,        // 读字符间隔超时时间: 100 ms
        1,          // 读操作时每字符的时间: 1 ms (n个字符总共为n ms)
        500,        // 基本的(额外的)读超时时间: 500 ms
        1,          // 写操作时每字符的时间: 1 ms (n个字符总共为n ms)
        100
	};       // 基本的(额外的)写超时时间: 100 ms

	SetCommTimeouts(m_hComm, &timeouts);    // 设置超时

	CString strMsg;
	CString strMsgReturn;
	strMsg.Format("ATE0\r");//设置不回显

	SendAndGetReturn(strMsg, strMsgReturn);


	strMsg.Format("AT+CMGF=0\r");
	if (!SendAndGetReturn(strMsg, strMsgReturn))
	{
		CloseCom();
		return FALSE;
	}

	return TRUE;

}



void CMsgCtrl::CloseCom()
{

	if (m_hComm)
	{
		CloseHandle(m_hComm);
		m_hComm = NULL;
	}

}

BOOL CMsgCtrl::SendMsg(const CString &strMsgSend, const CString &strDestTermID, LPCTSTR lpszSmsCenter)
{
m_csLock.Lock();

	CString strMsg;
	CString strMsgReturn;
	CString strNumber = strDestTermID;
	CString strSmsc = lpszSmsCenter;
	CString strContent = strMsgSend;
	char szData[4096] = "";
	int nDataLen= 0;
	char szReadMsg[4096] = "";
	DWORD nMsgLen = 0;
	SM_PARAM SmParam;
	memset(&SmParam, 0, sizeof(SM_PARAM));

	// 去掉号码前的"+"
	if(lpszSmsCenter && strSmsc[0] == '+') 
	{
		strSmsc = strSmsc.Mid(1);
	}
	if(strNumber[0] == '+') 
	{
		strNumber = strNumber.Mid(1);
	}

	// 在号码前加"86"
	if(lpszSmsCenter && strSmsc.Left(2) != "86")  
	{
		strSmsc = "86" + strSmsc;
	}
//	if (strNumber.Left(2) == "13" && strNumber.GetLength() == 11)
	{
//		if(strNumber.Left(2) != "86") 
		{
//			strNumber = "86" + strNumber;
		}
	}

	// 填充短消息结构
	if (lpszSmsCenter)
	{
		strcpy(SmParam.SCA, strSmsc);
	}
	else
	{
		memset(SmParam.SCA, 0x0, sizeof(SmParam.SCA));
	}
	strcpy(SmParam.TPA, strNumber);
	strcpy(SmParam.TP_UD, strContent);
	SmParam.TP_PID = 0;
	SmParam.TP_DCS = GSM_UCS2;
	nDataLen = gsmEncodePdu(&SmParam, szData);
	szData[nDataLen] = '\0';

	strMsg.Format("AT+CMGF=0\r");
	SendAndGetReturn(strMsg, strMsgReturn);

	unsigned char nSmscLength;	// SMSC串长度
	gsmString2Bytes(szData, &nSmscLength, 2);	// 取PDU串中的SMSC信息长度
	nSmscLength++;		// 加上长度字节本身

	strMsg.Format("AT+CMGS=%d\r", nDataLen/2-nSmscLength);
	nMsgLen = strMsg.GetLength();

	if (!Writen(strMsg, nMsgLen, &nMsgLen))
	{
		goto ON_SENDMSG_ERROR;
	}
	if (!Readn(szReadMsg, 4, &nMsgLen))
	{
		goto ON_SENDMSG_ERROR;
	}
	if (strncmp(szReadMsg, "\r\n> ", 4) != 0)
	{
		goto ON_SENDMSG_ERROR;
	}
	strMsg.Format("%s%c", szData, 26);
	if (!SendAndGetReturn(strMsg, strMsgReturn))
	{
		goto ON_SENDMSG_ERROR;
	}

	if (strMsgReturn.Right(4).Compare("OK\r\n") != 0)
	{
		goto ON_SENDMSG_ERROR;
	}

	m_csLock.Unlock();
	return TRUE;

ON_SENDMSG_ERROR:
	m_csLock.Unlock();
	return FALSE;
}

BOOL CMsgCtrl::ParseCMGLHead(const CString& strLine, COneMsg& msg)
{
//+CMGL: 1,"REC READ","8178",,"05/12/17,14:55:04+00"
//前面的+CMGL:已去掉了
	int nPos = 0;
	CString strTmp;
	CString strMsg = strLine;

	nPos = strMsg.Find(",");
	if (nPos < 0)
	{
		return FALSE;
	}
	strTmp = strMsg.Left(nPos);
	strMsg = strMsg.Mid(nPos+1);
	msg.nIndex = atoi(LPCTSTR(strTmp));
/*
	nPos = strMsg.Find(",");
	if (nPos < 0)
	{
		return FALSE;
	}
	strTmp = strMsg.Left(nPos);
	strMsg = strMsg.Mid(nPos+1);
	strTmp.TrimLeft(" \"");
	strTmp.TrimRight(" \"");
	msg.strType = strTmp;

	nPos = strMsg.Find(",");
	if (nPos < 0)
	{
		return FALSE;
	}
	strTmp = strMsg.Left(nPos);
	strMsg = strMsg.Mid(nPos+1);
	strTmp.TrimLeft(" \"");
	strTmp.TrimRight(" \"");
	msg.strFromNumber = strTmp;

	nPos = strMsg.Find(",");
	if (nPos < 0)
	{
		return FALSE;
	}
	strMsg = strMsg.Mid(nPos+1);

//	nPos = strMsg.Find(",");
//	if (nPos < 0)
//	{
//		return FALSE;
//	}
//	strMsg = strMsg.Mid(nPos+1);
	strTmp = strMsg;
	strTmp.TrimLeft(" \"");
	strTmp.TrimRight(" \"\r\n");
	msg.strServiceTime = strTmp;
*/
	return TRUE;

}

BOOL CMsgCtrl::RecvAllMsg(vector<COneMsg>& vtMsgs, BOOL bAutoDel)
{
	m_csLock.Lock();

	CString strMsg;
	CString strMsgReturn;
	CString strLine;
	int nPos1 = 0;
	int nPos2 = 0;
	int offset = 0;

//	strMsg.Format("AT+CMGF=1\r"); //只有TEXT时才可以删除,不是所有MODEM
//	SendAndGetReturn(strMsg, strMsgReturn);

	strMsg.Format("AT+CMGL=4\r");
	if (!SendAndGetReturn(strMsg, strMsgReturn))
	{
		goto ON_RECVALLMSG_ERROR;
	}

	while ( (nPos1 = strMsgReturn.Find("+CMGL:", offset)) >= 0)
	{
		nPos1 += 6;
		offset = nPos1;
		nPos2 = strMsgReturn.Find("\n", offset);
		if (nPos2 < 0)
		{
			break;
		}
		offset = nPos2 + 1;
		
		COneMsg msg;
		strLine = strMsgReturn.Mid(nPos1, nPos2-nPos1);
		if (!ParseCMGLHead(strLine, msg))
		{
			continue;
		}

		nPos2 = strMsgReturn.Find("\n", offset);
		if (nPos2 < 0)
		{
			break;
		}
		strLine = strMsgReturn.Mid(offset, nPos2-offset);
		strLine.TrimLeft("\r\n ");
		strLine.TrimRight("\r\n ");
		offset = nPos2 + 1;

		SM_PARAM sm;
		memset(&sm, 0, sizeof(SM_PARAM));
		msg.nContentLen = gsmDecodePdu(LPCTSTR(strLine), &sm);
		msg.nMsgFmt = sm.TP_DCS;
		msg.nTP_PID = sm.TP_PID;
		msg.strServiceTime = sm.TP_SCTS;
		if (msg.nMsgFmt == GSM_UCS2)
		{
			msg.strContent = sm.TP_UD;
		}
		else
		{
			memcpy(msg.strContent.GetBuffer(msg.nContentLen+1), sm.TP_UD, msg.nContentLen);

		}
		msg.strFromNumber = sm.TPA;
		vtMsgs.push_back(msg);

	}

	if (bAutoDel)
	{
		//自动删除
		vector<COneMsg>::iterator iter;
		for (iter=vtMsgs.begin(); iter!=vtMsgs.end(); iter++)
		{
			strMsg.Format("AT+CMGD=%d\r", iter->nIndex);
			if (SendAndGetReturn(strMsg, strMsgReturn))
			{
				//标记已删除
				iter->bDeleted = TRUE;
			}
		}
	}


	m_csLock.Unlock();
	return TRUE;
ON_RECVALLMSG_ERROR:
	m_csLock.Unlock();
	return FALSE;
}


BOOL CMsgCtrl::SendAndGetReturn(const CString &strMsgSend, CString &strMsgReturn, BOOL bReturnFristLine)
{
#define MAX_READBUF  4096
	DWORD dwWrite = 0;
	COMSTAT ComStat;
	char szReadBuf[MAX_READBUF];
	int nReadLen = 0;
	DWORD dwBytesRead = 0;
	DWORD dwBytesToRead = (DWORD)strMsgSend.GetLength();
	DWORD dwErrorFlags = 0;
	CString strLine;
	CString strFristLine;

	strMsgReturn = "";

	if (!Writen(LPCTSTR(strMsgSend), (DWORD)(strMsgSend.GetLength()), &dwWrite) )
	{
		goto ON_CLEAR_BUF;
	}

	if (!ClearCommError(m_hComm, &dwErrorFlags, &ComStat))
	{
		return FALSE;
	}
	//应该读取的数据长度 
//	dwBytesRead = (DWORD)strMsgSend.GetLength(); 
//	if (!Readn(szReadBuf, dwBytesRead, &dwBytesRead))
//	{
//		return FALSE;
//	}
/*
	if (!ClearCommError(m_hComm, &dwErrorFlags, &ComStat))
	{
		return FALSE;
	}
	//应该读取的数据长度
	dwBytesToRead = sizeof(szReadBuf);
	dwBytesRead = dwBytesToRead < ComStat.cbInQue ? dwBytesToRead : ComStat.cbInQue; 
	if(dwBytesRead <= 0)
	{
//		return FALSE;
	}
	if (!ReadFile( m_hComm, szReadBuf, dwBytesRead, &dwBytesRead,NULL))
	{
		return FALSE;
	}
	szReadBuf[dwBytesRead] = '\0';
	strMsgReturn = szReadBuf;
*/
	

	for (;;)
	{
		if (ReadLine(szReadBuf, MAX_READBUF) < 0)
		{
			break;
		}
		strLine = szReadBuf;
		strLine.TrimRight("\r\n");
		strMsgReturn += strLine;
		strMsgReturn += "\r\n";
		
		if (bReturnFristLine && strFristLine.IsEmpty())
		{
			strFristLine = 	strLine;		
		}

		if (strLine.Compare("ERROR") == 0)
		{
			return FALSE;
		}

		if (strLine.Compare("OK") == 0)
		{
			if (bReturnFristLine)
			{
				strMsgReturn = strFristLine;
			}
			return TRUE;
		}
	}


//	return FALSE;
ON_CLEAR_BUF:

	return FALSE;
}


int CMsgCtrl::ReadLine(char *szBuf, const int maxLen)
{
	DWORD n, rc;
	char *ptr = szBuf;
	char c;
	BOOL bResult;
	int nLoop = 0;

	for (n=1; n<(DWORD)maxLen; n++)
	{
		rc = 0;
		bResult = ReadFile(m_hComm, &c, 1, &rc, 0);
		if (!bResult)
		{
			return -1;
		}

		if ( rc  == 1)
		{
			*ptr++ = c;
			if (c == '\n')
				break;
			nLoop = 0;
		}
		else
		{
			n --;
			Sleep(100);
			nLoop ++;
			if (nLoop > 10)
			{
				if (n == 2 && strncmp(szBuf, "> ", 2) == 0)
				{
					//没输入没结束
					c = 26;
					Writen(&c, 1, &rc);
					continue;
				}
				break;
			}
		}
	}

	*ptr = '\0';
	return n;
}

BOOL CMsgCtrl::Readn(char* pszData, DWORD dwToRead, DWORD *pdwRead)
{
	DWORD dwRead;
	DWORD dwError;
	
	*pdwRead = 0;
	while ( dwToRead > 0 )
	{
		if (!ReadFile(m_hComm, (LPVOID)pszData, dwToRead, &dwRead, NULL))
		{
			dwError = GetLastError();

			break;
		}

		dwToRead -= dwRead;
		*pdwRead += dwRead;
		pszData += *pdwRead;
	}
	
	if (dwToRead != 0)
	{
		return FALSE;

⌨️ 快捷键说明

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