📄 sms.cpp
字号:
#include "stdafx.h"
#include "SMS.h"
#include "smsdef.h"
CSMSException::CSMSException()
{
m_dwErrorCode = 0;
m_sErrorDescribe = _T("");
}
CSMSException::~CSMSException()
{
}
void CSMSException::SetCode( DWORD dwCode )
{
m_dwErrorCode = dwCode;
}
void CSMSException::SetDescribe( LPCTSTR lpszDescribe )
{
m_sErrorDescribe = lpszDescribe;
}
DWORD CSMSException::GetCode()
{
return m_dwErrorCode;
}
CString CSMSException::GetDescribe()
{
return m_sErrorDescribe;
}
CSMS::CSMS()
{
m_bInitOK = FALSE;
m_hComDev = NULL ;
m_hReadEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ;
m_hWriteEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ;
m_bAsyncComm = TRUE ;
m_nKeepTime = 7*24 ;
m_nMaxLength = 140 ;
m_sAreaCode = _T("86") ;
m_sSmsCenter = _T("13800591500"); ;
m_exp = new CSMSException ;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof( SECURITY_ATTRIBUTES );
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
m_hEventOfUsing = CreateEvent( &sa, TRUE, TRUE, _T("CSms CanUse Event") );
}
CSMS::~CSMS()
{
if( m_hComDev != NULL )
CloseHandle( m_hComDev );
if( m_hReadEvent != NULL )
CloseHandle( m_hReadEvent );
if( m_hWriteEvent != NULL )
CloseHandle( m_hWriteEvent );
if( m_exp != NULL )
delete m_exp;
}
void CSMS::SetSmsParam( int nComPort, int nKeepTime, int nMaxLength, LPCSTR sAereCode, LPCSTR sSmsCenter )
{
CString str;
str.Format("COM%d", nComPort);
m_sCom = str;
m_nKeepTime = nKeepTime;
m_nMaxLength = nMaxLength;
m_sAreaCode = sAereCode;
m_sSmsCenter = sSmsCenter;
}
void CSMS::SetSmsParam( LPCSTR sCom, int nKeepTime, int nMaxLength, LPCSTR sAereCode, LPCSTR sSmsCenter )
{
m_sCom = sCom;
m_nKeepTime = nKeepTime;
m_nMaxLength = nMaxLength;
m_sAreaCode = sAereCode;
m_sSmsCenter = sSmsCenter;
}
DWORD CSMS::Init( BOOL bAsyncComm )
{
m_bAsyncComm = bAsyncComm;
m_bInitOK = FALSE;
__try
{
Lock();
ComOpen();
InitSms();
m_bInitOK = TRUE;
}
__finally
{
Unlock();
}
return CODE_SUCCESS;
}
DWORD CSMS::InitSms()
{
CString str;
AsyncComWrite( "ATEV1\r" );
str = _T("AT+CPAS\r");
AsyncComWrite( str );
AsyncComRead( str );
if( str.Find( "+CPAS: 3" ) >= 0||str.Find( "+CPAS: 4" ) >= 0 )
{
m_exp->SetCode( CODE_PHONE_BUSY );
CString strError;
strError.Format("%s[%s]", NOTE_PHONE_BUSY, str);
m_exp->SetDescribe( strError );
throw m_exp;
}
else if( str.Find( "+CPAS: 1" ) >= 0 )
{
m_exp->SetCode( CODE_PHONE_UNAVAILABLE );
CString strError;
strError.Format("%s[%s]", NOTE_PHONE_UNAVAILABLE, str);
m_exp->SetDescribe( strError );
//m_exp->SetDescribe( NOTE_PHONE_UNAVAILABLE );
throw m_exp;
}
else if( str.Find( "+CPAS: 2" ) >= 0 )
{
m_exp->SetCode( CODE_CONNECT_PHONE_ERROR );
CString strError;
strError.Format("%s[%s]", NOTE_CONNECT_PHONE_ERROR, str);
m_exp->SetDescribe( strError );
//m_exp->SetDescribe( NOTE_CONNECT_PHONE_ERROR );
throw m_exp;
}
else if( str.Find( "+CPAS: 5" ) >= 0 )
{
m_exp->SetCode( CODE_LOW_FUNCTION );
CString strError;
strError.Format("%s[%s]", NOTE_LOW_FUNCTION, str);
m_exp->SetDescribe( strError );
//m_exp->SetDescribe( NOTE_LOW_FUNCTION );
throw m_exp;
}
else if( str.Find( "+CPAS: 0" ) < 0 )
{
m_exp->SetCode( CODE_UNKNOW_ERROR );
CString strError;
strError.Format("%s[%s]", NOTE_UNKNOW_ERROR, str);
m_exp->SetDescribe( strError );
//m_exp->SetDescribe( NOTE_UNKNOW_ERROR );
throw m_exp;
}
str.Format( _T("AT+CSCA=\"+%s%s\",145\r"), m_sAreaCode, m_sSmsCenter );
PurgeComm(m_hComDev, PURGE_RXCLEAR | PURGE_TXCLEAR );
AsyncComWrite( str );
AsyncComRead( str );
if( str.Find( "OK" ) < 0 )
{
m_exp->SetCode( CODE_INIT_PHONE_ERROR );
CString strError;
strError.Format("%s[%s]", NOTE_INIT_PHONE_ERROR, str);
m_exp->SetDescribe( strError );
throw m_exp;
}
str = _T("AT+CMGF=1\r");
PurgeComm(m_hComDev, PURGE_RXCLEAR | PURGE_TXCLEAR );
AsyncComWrite( str );
AsyncComRead( str );
if( str.Find( "OK" ) < 0 )
{
m_exp->SetCode( CODE_INIT_PHONE_ERROR );
CString strError;
strError.Format("%s[%s]", NOTE_INIT_PHONE_ERROR, str);
m_exp->SetDescribe( strError );
throw m_exp;
}
str.Format( _T("AT+CSMP=17,%d,0,8\r"),SetVPH( m_nKeepTime ));
PurgeComm(m_hComDev, PURGE_RXCLEAR | PURGE_TXCLEAR );
AsyncComWrite( str );
AsyncComRead( str );
if( str.Find( "OK" ) < 0 )
{
m_exp->SetCode( CODE_INIT_PHONE_ERROR );
CString strError;
strError.Format("%s[%s]", NOTE_INIT_PHONE_ERROR, str);
m_exp->SetDescribe( strError );
throw m_exp;
}
return CODE_SUCCESS;
}
DWORD CSMS::SendShortMessage( LPCSTR sRcver,LPCSTR sShortMessage )
{
DWORD ret;
try
{
Lock();
ret = _SendShortMessage( sRcver, sShortMessage );
}
catch(...)
{
Unlock();
throw;
}
Unlock();
return ret;
}
DWORD CSMS::_SendShortMessage( LPCSTR sRcver, LPCSTR sShortMessage )
{
CString str = "", sMsg, sToSend;
CStringArray saMsg;
if( !m_bInitOK )
InitSms();
sMsg = sShortMessage;
sToSend = _T("");
BOOL bCharacter = FALSE;
int nCount = 0; //djq_020814 add计算英文字符的数目
//djq_020814 note
//由于在手机实现中如果AT+CMGF=1时,英文字符实际上也是同汉字一样算一个字
//所以必须注意140个实际上是英文字符一个算两个
while( !sMsg.IsEmpty() )
{
unsigned char c = sMsg.GetAt(0);
if( c >= 128 )
{
bCharacter = TRUE;
sToSend += sMsg.Mid(0,2);
sMsg.Delete(0,2);
}
else
{
bCharacter = FALSE;
sToSend += sMsg.GetAt(0);
sMsg.Delete(0);
nCount++;
}
if( sMsg.IsEmpty() )
saMsg.Add( sToSend );
else if( sToSend.GetLength()+nCount > m_nMaxLength ) //djq_020814 chg
{
if( bCharacter )
{
sMsg = sToSend.Mid( sToSend.GetLength() -2, 2 ) + sMsg;
sToSend.Delete( sToSend.GetLength()-2, 2 );
}
else
{
sMsg.Insert( 0, sToSend.GetAt( sToSend.GetLength()-1 ) );
sToSend.Delete( sToSend.GetLength()-1 );
}
saMsg.Add( sToSend );
sToSend = _T("(续)");
nCount = 0;
}
}
int nSmsCount = saMsg.GetSize(); //djq_020522 发送的条数
while( saMsg.GetSize() )
{
str = _T("AT+CPAS\r");
PurgeComm(m_hComDev, PURGE_RXCLEAR | PURGE_TXCLEAR );
AsyncComWrite( str );
AsyncComRead( str );
if( str.Find( "+CPAS: 3" ) >= 0||str.Find( "+CPAS: 4" ) >= 0 )
{
m_exp->SetCode( CODE_PHONE_BUSY );
CString strError;
strError.Format("%s[%s]", NOTE_PHONE_BUSY, str);
m_exp->SetDescribe( strError );
throw m_exp;
}
else if( str.Find( "+CPAS: 1" ) >= 0 )
{
m_exp->SetCode( CODE_PHONE_UNAVAILABLE );
CString strError;
strError.Format("%s[%s]", NOTE_PHONE_UNAVAILABLE, str);
m_exp->SetDescribe( strError );
throw m_exp;
}
else if( str.Find( "+CPAS: 2" ) >= 0 )
{
m_exp->SetCode( CODE_CONNECT_PHONE_ERROR );
CString strError;
strError.Format("%s[%s]", NOTE_CONNECT_PHONE_ERROR, str);
m_exp->SetDescribe( strError );
throw m_exp;
}
else if( str.Find( "+CPAS: 5" ) >= 0 )
{
m_exp->SetCode( CODE_LOW_FUNCTION );
CString strError;
strError.Format("%s[%s]", NOTE_LOW_FUNCTION, str);
m_exp->SetDescribe( strError );
throw m_exp;
}
else if( str.Find( "+CPAS: 0" ) < 0 )
{
m_exp->SetCode( CODE_CONNECT_PHONE_ERROR );
CString strError;
strError.Format("%s[%s]", NOTE_CONNECT_PHONE_ERROR, str);
m_exp->SetDescribe( strError );
throw m_exp;
}
str.Format( _T("AT+CMGS=\"+%s%s\",145\r"), m_sAreaCode, sRcver );
PurgeComm(m_hComDev, PURGE_RXCLEAR | PURGE_TXCLEAR );
AsyncComWrite( str );
//str.Format( _T("%s\x1A"), saMsg.GetAt(0) );
str.Format( _T("%s\x1A"),DoUniCode( (LPCTSTR)(saMsg.GetAt(0)) ) );
AsyncComWrite( str );
AsyncComRead( str );
if( str.Find( _T("OK") ) < 0 )
{//发送失败
m_exp->SetCode( CODE_SEND_SM_ERROR );
CString strError;
strError.Format("%s[%s]", NOTE_SEND_SM_ERROR, str);
m_exp->SetDescribe( strError );
throw m_exp;
}
saMsg.RemoveAt(0);
}
return nSmsCount;
//return CODE_SUCCESS;
}
BOOL CSMS::CanUse()
{
return TRUE;
DWORD ret;
ret = WaitForSingleObject( m_hEventOfUsing, 0 );
return ret == WAIT_OBJECT_0;
}
DWORD CSMS::WaitForCanUse( DWORD dwMilliseconds )
{
return WaitForSingleObject( m_hEventOfUsing, dwMilliseconds );
}
void CSMS::Lock()
{
return;
if( !CanUse() )
{
m_exp->SetCode( CODE_PHONE_BUSY );
m_exp->SetDescribe( NOTE_PHONE_BUSY );
throw m_exp;
}
ResetEvent( m_hEventOfUsing );
}
void CSMS::Unlock()
{
return;
SetEvent( m_hEventOfUsing );
}
BOOL CSMS::ComOpen()
{
CString strPort;
DCB dcb;
COMMTIMEOUTS CommTimeOuts;
DWORD dwOpenFlag;
if( m_hComDev != (HANDLE) -1 )
CloseHandle( m_hComDev );
if( m_hReadEvent != (HANDLE) -1 )
CloseHandle( m_hReadEvent );
if( m_hWriteEvent != (HANDLE) -1 )
CloseHandle( m_hWriteEvent );
m_hReadEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_hWriteEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
strPort.Format( _T("%s"),m_sCom );
if( m_bAsyncComm )
dwOpenFlag = FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED;
else
dwOpenFlag = 0;
m_hComDev = CreateFile( strPort,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
dwOpenFlag,
NULL );
if ( m_hComDev == ( HANDLE )-1 )
{
m_exp->SetCode( CODE_COM_OPEN_ERROR );
m_exp->SetDescribe( _T("打开端口") + strPort + _T("失败") );
throw m_exp;
}
SetupComm( m_hComDev, 5*1024, 5*1024 );
GetCommState( m_hComDev,&dcb );
dcb.BaudRate = 9600;
dcb.ByteSize = DATABITS_8;
dcb.fParity = 1;
dcb.Parity = NOPARITY;
dcb.EvtChar = '\xD';
SetCommState( m_hComDev,&dcb );
if( m_bAsyncComm )
{//异步
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 1000;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
}
else
{//同步
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutConstant = 1000;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 1000;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
}
SetCommTimeouts( m_hComDev,&CommTimeOuts );
DWORD dwStoredFlags;
dwStoredFlags = EV_RXFLAG;
SetCommMask( m_hComDev, dwStoredFlags );
return CODE_SUCCESS;
}
DWORD CSMS::AsyncComWrite ( LPCTSTR lpszWrite )
{
COMSTAT ComStat;
DWORD dwErrorFlags;
DWORD dwLength;
BOOL bState;
OVERLAPPED opWrite;
CString strPort;
strPort.Format( _T("%s"),m_sCom );
memset( &opWrite, 0, sizeof( OVERLAPPED ) );
opWrite.hEvent = m_hWriteEvent;
PurgeComm(m_hComDev, PURGE_TXCLEAR | PURGE_RXCLEAR );
ClearCommError(m_hComDev, &dwErrorFlags, &ComStat);
bState=WriteFile(m_hComDev,lpszWrite,strlen(lpszWrite),&dwLength,&opWrite);
if(!bState)
{
if(GetLastError()==ERROR_IO_PENDING)
GetOverlappedResult(m_hComDev,&opWrite,&dwLength,TRUE);// 等待
else
{
m_exp->SetCode( CODE_WRITE_TO_COM_ERROR );
m_exp->SetDescribe( _T("写端口") + strPort + _T("失败") );
throw m_exp;
}
}
return CODE_SUCCESS;
}
DWORD CSMS::AsyncComRead( CString &strRead )
{
COMSTAT ComStat;
DWORD dwErrorFlags;
OVERLAPPED opRead;
DWORD dwWantRead, dwRealRead;
CString strPort;
char szBuf[512];
strPort.Format( _T("%s"),m_sCom );
memset( &opRead, 0, sizeof( OVERLAPPED ) );
opRead.hEvent = m_hReadEvent;
memset( szBuf, 0, 512 );
ClearCommError(m_hComDev, &dwErrorFlags, &ComStat);
dwRealRead = 0;
dwWantRead = 512;
OVERLAPPED op;
memset( &op, 0, sizeof(op) );
op.hEvent = NULL;
DWORD dwFlag;
dwFlag = EV_RXFLAG;
op.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
SetCommMask( m_hComDev, EV_RXFLAG );
strRead = "";
while( strRead.Find("OK") < 0 && strRead.Find("ERROR") < 0 )
{
WaitCommEvent( m_hComDev, &dwFlag, &op );
if( WaitForSingleObject( op.hEvent, SEND_TIMEOUT*1000 ) != WAIT_OBJECT_0 )
{
m_exp->SetCode( CODE_READ_COM_TIMEOUT );
m_exp->SetDescribe( _T("读端口") + strPort + _T("超时") );
throw m_exp;
}
ClearCommError(m_hComDev, &dwErrorFlags, &ComStat);
ReadFile(m_hComDev,szBuf,ComStat.cbInQue,&dwRealRead,&opRead);
GetOverlappedResult(m_hComDev,&opRead,&dwRealRead,TRUE);
strRead += szBuf;
memset( szBuf, 0, 512 );
}
CloseHandle( op.hEvent );
return CODE_SUCCESS;
}
DWORD CSMS::SyncComWrite( CString &strWrite )
{
DWORD dwWritedCount;
CString strPort;
strPort.Format( _T("%s"),m_sCom );
if( !WriteFile( m_hComDev,
(LPCVOID)strWrite,
strWrite.GetLength(),
&dwWritedCount,
NULL ) ){
m_exp->SetCode( CODE_WRITE_TO_COM_ERROR );
m_exp->SetDescribe( _T("写端口") + strPort + _T("失败") );
throw m_exp;
}
return CODE_SUCCESS;
}
DWORD CSMS::SyncComRead( CString &strRead )
{
DWORD lReadCount = 0;
char szBuf[1024];
CString strPort;
strPort.Format( _T("%s"),m_sCom );
memset( szBuf, 0, 1024 );
if( !ReadFile( m_hComDev,
szBuf,
1203,
&lReadCount,
NULL ) ){
m_exp->SetCode( CODE_READ_FROM_COM_ERROR );
m_exp->SetDescribe( _T("读端口") + strPort + _T("失败") );
throw m_exp;
}
strRead = szBuf;
return CODE_SUCCESS;
}
CString CSMS::DoUniCode( LPCTSTR lpszSource )
{
CString str;
char temp[512],buffer[256];
int i,nLength;
unsigned short uTemp[256];
strcpy( buffer,lpszSource );
nLength = MultiByteToWideChar( 936,MB_COMPOSITE,buffer,-1,uTemp,255 );
memset( temp,0,sizeof(temp) );
for ( i = 0; i < nLength; i ++ ) {
if ( uTemp[i] == 0 ) break;
sprintf( temp+strlen(temp),"%04X",(int)uTemp[i] );
}
str = temp;
return str;
}
int CSMS::SetVPH(int nHour)
{//保留时间编码
int nResult;
if ( nHour > 10584 ) nHour = 10584;
if ( nHour >= 5*7*24 ) {
nResult = nHour/(24*7)+192;
}else if ( nHour >= 48 ) {
if( nHour >720 ) nHour = 720;
nResult = nHour/24+166;
}else if ( nHour >= 13 ) {
if( nHour >24 ) nHour = 24;
nResult = (nHour-12)*2+143;
}else if ( nHour >= 0 ) {
if( nHour==0 ) nResult = 0;
else nResult = nHour*12-1;
}
return nResult;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -