?? msgctrl.cpp
字號:
// 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 + -