本文章的版权声明: 1)任何的编程爱好者、网友可以以非商业目的下载并使用下面的源代码。 2)使用了下面全部或部分代码的朋友请注明出处:http://blog.csdn.net/dfman 3)保留对商业用途的版权
具体做法是这样的:1)买一款支持AT指令集的手机,我买的是西门子;2)买与手机配套的数据线,使手机可以与计算机串口相链接;3)当然你要有SIM/UIM卡;4)按下面的算法编写程序;5)剩下的就是收发短信了。
这个class是整个工程的一部分,不敢保证代码完整,但是可以保证算法和思路完整。整个工程可能还包括SMPP/SGIP/CMPP的源代码,如有需要,请来信相我索要:[email protected]。我没有其他的邮箱。
typedef struct _SMS_Recv //收到信息的通知结构 { long lMsgType; //短信类型:MSGTYPE_SMS 或 MSGTYPE_REPORT char szSmsc[32]; //短信中心 char szSender[32]; //发送者号码,如果lMsgType==MSGTYPE_REPORT,则是状态报告的目标手机号码 char szTime[32]; //发送时间 char szMsg[512]; //信息内容 }SMS_Recv;
// 短消息队列缓冲池 struct ShortMsgPool { HANDLE hSMPHaveData; HANDLE hSMPIDLE; DWORD dwSize; char *pData; };
// 发送短消息缓冲池 struct SubmitPool { HANDLE hSPDeliver; HANDLE hSPIDLE; DWORD dwSize; char *pData; };
// 接收短消息缓冲池 struct DeliverPool { HANDLE hDPDeliver; // 投递请求的事件句柄 HANDLE hDPIDLE; // 表示缓冲池空的事件句柄 DWORD dwSize; // 请求数据的大小,以字节为单位 char *pData; // 请求数据存放的缓冲区 };
class CGSMPhone { public: long GetRecvNum(){ return( m_dwSMNumberInPool ); } long GetMobileName( char* pName ); long GetSMContent( void ){ return( m_dwSMContent == 0 ? -1 : m_dwSMContent ); } long GetShortMsg( SMS_Recv * pSms ); long GetShortMsg2( char *pNo, char *pMsg, char *pTime ); long Send( char *pNo, char *pMsg, BOOL bReport, BOOL bHandFree, BOOL bAsyn ); bool Close(); bool Open( int nPort = 1, int nBaud = 19200 );
bool IsOpened( void ){ return( m_bOpened ); }
void DeliverThread(); void SubmitThread();
CGSMPhone(); virtual ~CGSMPhone();
HWND m_hWnd; DWORD m_dwTimeout; CString m_strSMCenter;
protected:
DWORD Deliver( char *&pData ); DWORD Submit ( char *szBuffer, DWORD dwLen ); DWORD PDUEncodeEng( char *pMsg, char *&pResultData ); DWORD PDUEncodeChn( char *pMsg, char *&pResultData ); DWORD PDUDecodeEng( char *pMsg, char *&pResultData ); DWORD PDUDecodeChn( char *pMsg, char *&pResultData ); char* NumberEncode( char *pPhoneNumber ); bool NumberDecode ( char *szNumber, int nLen ); void Str2StrArr( CString strTemp, CStringArray &sa, char cDelimiter );
DWORD ReadStringFromComm( char *szBuffer, DWORD dwBufLen ); DWORD ReadComm( char *szBuffer, DWORD dwBufLen ); bool WriteComm( const char *buffer, DWORD size );
bool FreeShortMsgPool( void ); bool FreeDeliverPool ( void ); bool FreeSubmitPool ( void ); bool CreateShortMsgPool( DWORD dwNum ); bool CreateDeliverPool ( DWORD dwNum ); bool CreateSubmitPool ( DWORD dwNum );
SubmitPool* m_pSPool; HANDLE* m_phSPDeliver; HANDLE* m_phSPIDLE; DeliverPool* m_pDPool; HANDLE* m_phDPDeliver; HANDLE* m_phDPIDLE; ShortMsgPool* m_pSMPool; HANDLE* m_phSMPHaveData; HANDLE* m_phSMPIDLE;
HANDLE m_hSystemExit; HANDLE m_hIDComDev;
LONG m_dwSMNumberInPool; DWORD m_dwThreadPoolNum; DWORD m_dwSMContentPoolNum; DWORD m_dwSMContent; bool m_bOpened; bool m_bStarted;
OVERLAPPED m_Overlapped;
CRITICAL_SECTION m_csComm;
CString m_strCommBuffer; CString m_strMobileName; };
#include "GSMPhone.h" #include <process.h>
void SubmitThreadFun( LPVOID lpParam ) { CGSMPhone* pGSMPhone = (CGSMPhone*)lpParam; pGSMPhone->SubmitThread(); }
void DeliverThreadFun( LPVOID lpParam ) { CGSMPhone* pGSMPhone = (CGSMPhone*)lpParam; pGSMPhone->DeliverThread(); }
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
CGSMPhone::CGSMPhone() { m_hIDComDev = NULL; m_hSystemExit = NULL; m_hWnd = NULL; m_bOpened = false; m_bStarted = false;
m_dwTimeout = 5; m_dwThreadPoolNum = 5; m_dwSMContent = 0; m_dwSMNumberInPool = 0;
m_strSMCenter = ""; m_strCommBuffer = ""; m_strMobileName = ""; // hDDeliver = CreateEvent( NULL,FALSE,FALSE,NULL ); }
CGSMPhone::~CGSMPhone() {
}
bool CGSMPhone::CreateSubmitPool(DWORD dwNum) { try { m_pSPool = new SubmitPool[dwNum+1]; m_phSPDeliver = new HANDLE[dwNum+1]; m_phSPIDLE = new HANDLE[dwNum+1];
for( DWORD dw = 0; dw < dwNum; dw ++ ) { m_phSPDeliver[dw] = m_pSPool[dw].hSPDeliver = CreateEvent( NULL,FALSE,FALSE,NULL ); m_phSPIDLE[dw] = m_pSPool[dw].hSPIDLE = CreateEvent( NULL,FALSE,TRUE,NULL ); }
m_phSPDeliver[dw] = m_phSPIDLE[dw] = m_hSystemExit; } catch( ... ) { return( false ); }
return( true ); }
bool CGSMPhone::FreeSubmitPool() { try { for( DWORD dwCount = 0; dwCount < m_dwThreadPoolNum; dwCount ++ ) { CloseHandle( m_pSPool[dwCount].hSPDeliver ); m_pSPool[dwCount].hSPDeliver = NULL; CloseHandle( m_pSPool[dwCount].hSPIDLE ); m_pSPool[dwCount].hSPIDLE = NULL; } delete [] m_phSPDeliver; m_phSPDeliver = NULL; delete [] m_phSPIDLE; m_phSPDeliver = NULL; delete [] m_pSPool; m_pSPool = NULL; } catch( ... ) { return( false ); } return( true ); }
bool CGSMPhone::CreateDeliverPool(DWORD dwNum) { try { m_pDPool = new DeliverPool[dwNum+1]; m_phDPDeliver = new HANDLE[dwNum+1]; m_phDPIDLE = new HANDLE[dwNum+1];
for( DWORD dw = 0; dw < dwNum; dw ++ ) { m_phDPDeliver[dw] = m_pDPool[dw].hDPDeliver = CreateEvent( NULL,FALSE,FALSE,NULL ); m_phDPIDLE[dw] = m_pDPool[dw].hDPIDLE = CreateEvent( NULL,FALSE,TRUE,NULL ); }
m_phDPDeliver[dw] = m_phDPIDLE[dw] = m_hSystemExit; } catch( ... ) { return( false ); }
return( true ); }
bool CGSMPhone::FreeDeliverPool() { try { for( DWORD dwCount = 0; dwCount < m_dwThreadPoolNum; dwCount ++ ) { CloseHandle( m_pDPool[dwCount].hDPDeliver ); m_pDPool[dwCount].hDPDeliver = NULL; CloseHandle( m_pDPool[dwCount].hDPIDLE ); m_pDPool[dwCount].hDPIDLE = NULL; } delete [] m_phDPDeliver; m_phDPDeliver = NULL; delete [] m_phDPIDLE; m_phDPDeliver = NULL; delete [] m_pDPool; m_pDPool = NULL; } catch( ... ) { return( false ); } return( true ); }
bool CGSMPhone::CreateShortMsgPool(DWORD dwNum) { try { m_pSMPool = new ShortMsgPool[dwNum]; m_phSMPHaveData = new HANDLE[dwNum]; m_phSMPIDLE = new HANDLE[dwNum];
for( DWORD dw = 0; dw < dwNum; dw ++ ) { m_phSMPHaveData[dw] = m_pSMPool[dw].hSMPHaveData = CreateEvent( NULL,FALSE,FALSE,NULL ); m_phSMPIDLE[dw] = m_pSMPool[dw].hSMPIDLE = CreateEvent( NULL,FALSE,TRUE,NULL ); } } catch( ... ) { return( false ); }
return( true ); }
bool CGSMPhone::FreeShortMsgPool() { try { for( DWORD dwCount = 0; dwCount < m_dwSMContentPoolNum; dwCount ++ ) { CloseHandle( m_pSMPool[dwCount].hSMPHaveData ); m_pSMPool[dwCount].hSMPHaveData = NULL; CloseHandle( m_pSMPool[dwCount].hSMPIDLE ); m_pSMPool[dwCount].hSMPIDLE = NULL; } delete [] m_phSMPHaveData; m_phSMPHaveData = NULL; delete [] m_phSMPIDLE; m_phSMPIDLE = NULL; delete [] m_pSMPool; m_pSMPool = NULL; } catch( ... ) { return( false ); } return( true ); }
bool CGSMPhone::WriteComm(const char *buffer, DWORD size) { if( m_bOpened == FALSE ) return( false ); DWORD dwBytesSent = 0; BOOL bResult = TRUE;
EnterCriticalSection( &m_csComm ); bResult = WriteFile( m_hIDComDev, buffer, size, &dwBytesSent, &m_Overlapped ); LeaveCriticalSection( &m_csComm ); if( !bResult ) { if( ( GetLastError() == ERROR_IO_PENDING ) ) { if( WaitForSingleObject( m_Overlapped.hEvent, 1000 ) == WAIT_OBJECT_0 ) { GetOverlappedResult( m_hIDComDev, &m_Overlapped, &dwBytesSent, FALSE ); if( dwBytesSent == size ) { Sleep( 100 ); return( true ); } } } } else { Sleep( 100 ); return( true ); } return( false ); }
DWORD CGSMPhone::ReadComm(char *szBuffer, DWORD dwBufLen) { BOOL bResult = TRUE; DWORD dwEvtMask = 0; DWORD dwError = 0; DWORD dwBytesRead = 0; COMSTAT comstat;
EnterCriticalSection( &m_csComm ); ClearCommError( m_hIDComDev, &dwError, &comstat); if( comstat.cbInQue == 0 ) { LeaveCriticalSection( &m_csComm ); return( 0 ); } dwBytesRead = comstat.cbInQue;
bResult = ReadFile( m_hIDComDev, szBuffer, dwBytesRead, &dwBytesRead, &m_Overlapped ); LeaveCriticalSection( &m_csComm ); if( !bResult ) { if( GetLastError() == ERROR_IO_PENDING ) { Sleep( 100 ); WaitForSingleObject( m_Overlapped.hEvent, 2000 ); GetOverlappedResult( m_hIDComDev, &m_Overlapped, &dwBytesRead, FALSE ); } } Sleep( 200 ); return( dwBytesRead ); }
DWORD CGSMPhone::ReadStringFromComm(char *szBuffer, DWORD dwBufLen) { char szBuf[1024]; DWORD dwRet = 0; while( 1 ) { Sleep( 100 ); memset( szBuf, 0, 1024 ); dwRet = ReadComm( szBuf, 1024 ); if( dwRet > 0 ) { m_strCommBuffer += szBuf; if( m_strCommBuffer.Find( "OK" ) == -1 ) continue; if( m_strCommBuffer.Find( '\r' ) > 0 ) break; } else { break; } }
if( !m_strCommBuffer.IsEmpty() ) { int nFirst = m_strCommBuffer.Find( "OK" ); if( nFirst > 0 ) { int nNext = m_strCommBuffer.Find( '\r', nFirst ); if( nNext > 0 ) { int nStrLen = nNext + 1; strncpy( szBuffer, (LPCTSTR)m_strCommBuffer, nStrLen ); if( m_strCommBuffer.GetLength() > nStrLen ) { m_strCommBuffer = m_strCommBuffer.Right( m_strCommBuffer.GetLength() - nStrLen ); } else { m_strCommBuffer.Empty(); } return( (DWORD)nStrLen ); } } nFirst = m_strCommBuffer.Find( "+CMTI:" ); if( nFirst > 0 ) { int nNext = m_strCommBuffer.Find( '\r', nFirst ); if( nNext > 0 ) { int nStrLen = nNext + 1; strncpy( szBuffer, (LPCTSTR)m_strCommBuffer, nStrLen ); if( m_strCommBuffer.GetLength() > nStrLen ) { m_strCommBuffer = m_strCommBuffer.Right( m_strCommBuffer.GetLength() - nStrLen ); } else { m_strCommBuffer.Empty(); } return( (DWORD)nStrLen ); } } nFirst = m_strCommBuffer.Find( ">" ); if( nFirst > 0 ) { int nNext = m_strCommBuffer.Find( ' ', nFirst ); if( nNext > 0 ) { int nStrLen = nNext + 1; strncpy( szBuffer, (LPCTSTR)m_strCommBuffer, nStrLen ); if( m_strCommBuffer.GetLength() > nStrLen ) { m_strCommBuffer = m_strCommBuffer.Right( m_strCommBuffer.GetLength() - nStrLen ); } else { m_strCommBuffer.Empty(); } return( (DWORD)nStrLen ); } } } return( 0 ); }
DWORD CGSMPhone::Submit(char *szBuffer, DWORD dwLen) { try { DWORD dwWaitRet = WaitForMultipleObjects( m_dwThreadPoolNum + 1, m_phSPIDLE, FALSE, INFINITE ); if( dwWaitRet == WAIT_OBJECT_0 + m_dwThreadPoolNum ) return( 0 ); m_pSPool[dwWaitRet].pData = new char[dwLen]; CopyMemory( m_pSPool[dwWaitRet].pData, szBuffer, dwLen ); m_pSPool[dwWaitRet].dwSize = dwLen; SetEvent( m_pSPool[dwWaitRet].hSPDeliver ); } catch( ... ) { return( 0 ); } return( dwLen ); }
DWORD CGSMPhone::Deliver(char *&pData) { try { DWORD dwWaitRet = WaitForMultipleObjects( m_dwThreadPoolNum + 1, m_phDPDeliver, FALSE, m_dwTimeout * 1000 ); if( dwWaitRet == WAIT_OBJECT_0 + m_dwThreadPoolNum ) return( 0 ); if( dwWaitRet != WAIT_TIMEOUT ) { DWORD dwDataLen = m_pDPool[dwWaitRet].dwSize; pData = new char[dwDataLen + 1]; ZeroMemory( pData, dwDataLen + 1 ); CopyMemory( pData, m_pDPool[dwWaitRet].pData, dwDataLen ); delete [] m_pDPool[dwWaitRet].pData; SetEvent( m_pDPool[dwWaitRet].hDPIDLE ); return( dwDataLen ); } } catch( ... ) { return( 0 ); } return( 0 ); }
void CGSMPhone::SubmitThread() { while( 1 ) { try { DWORD dwWaitRet = WaitForMultipleObjects( m_dwThreadPoolNum + 1, m_phSPDeliver, FALSE, INFINITE ); if( dwWaitRet == WAIT_OBJECT_0 + m_dwThreadPoolNum ) break; int n = 0; while( 1 ) { if( WriteComm( m_pSPool[dwWaitRet].pData, m_pSPool[dwWaitRet].dwSize ) ) break; if( (n ++) == 5 ) break; Sleep( 1000 ); } delete [] m_pSPool[dwWaitRet].pData; SetEvent( m_pSPool[dwWaitRet].hSPIDLE ); Sleep( 200 ); } catch( ... ) { break; } } }
void CGSMPhone::DeliverThread() { while( 1 ) { try { char szBuffer[1024] = {0}; DWORD dwReadRet = ReadStringFromComm( szBuffer, 1024 ); if( dwReadRet > 0 ) { char* pFirst; char* pNext; if( strstr( szBuffer, "+CMTI:" ) != NULL ) { pFirst = strchr( szBuffer, ',' ); pFirst ++; if( pFirst != NULL ) { pNext = strchr( pFirst, '\r' ); if( pNext != NULL ) { int len = pNext - pFirst; if( len <= 0 ) continue; char szCmd[30] = {0}; memcpy( szCmd, "AT+CMGR=", 8 ); memcpy( szCmd + 8, pFirst, len ); szCmd[8+len] = '\r'; Submit( szCmd, len + 9 ); } } } else if( strstr( szBuffer, "AT+CMGR" ) != NULL ) { pFirst = strchr( szBuffer, '=' ); pFirst ++; if( pFirst != NULL ) { pNext = strchr( pFirst, '\n' ); if( pNext != NULL ) { int len = pNext - pFirst; if( len <= 0 ) continue; char szCmd[30] = {0}; memcpy( szCmd, "AT+CMGD=", 8 ); memcpy( szCmd + 8, pFirst, len ); szCmd[8+len] = '\r'; Submit( szCmd, len + 9 ); } } pNext = strstr( szBuffer, "+CMGR:" ); if( pNext != NULL ) { pFirst = strchr( pNext, '\n' ); while( pFirst[0] == '\r' || pFirst[0] == '\n' ) pFirst ++; if( pFirst != NULL ) { pNext = strchr( pFirst, '\r' ); if( pNext != NULL ) { pNext[0] = '\0'; DWORD dwWaitRet = WaitForMultipleObjects( m_dwSMContentPoolNum, m_phSMPIDLE, FALSE, 1000 ); if( dwWaitRet != WAIT_TIMEOUT ) { DWORD dwMsgLen = strlen( pFirst ); m_pSMPool[dwWaitRet].pData = new char[dwMsgLen]; CopyMemory( m_pSMPool[dwWaitRet].pData, pFirst, dwMsgLen ); m_pSMPool[dwWaitRet].dwSize = dwMsgLen; SetEvent( m_pSMPool[dwWaitRet].hSMPHaveData ); InterlockedIncrement( &m_dwSMNumberInPool ); if( m_hWnd != NULL ) ::SendMessage( m_hWnd, PHONE_SMS_RECV, 0, 0 ); } else { if( m_hWnd != NULL ) ::SendMessage( m_hWnd, PHONE_SMS_RECV_BUF_OVERFLOW, 0, 0 ); } } } } } else if( strstr( szBuffer, "AT+" ) != NULL ) { DWORD dwWaitRet = WaitForMultipleObjects( m_dwThreadPoolNum + 1, m_phDPIDLE, FALSE, 1000 ); if( dwWaitRet == WAIT_OBJECT_0 + m_dwThreadPoolNum ) break; if( dwWaitRet != WAIT_TIMEOUT ) { m_pDPool[dwWaitRet].pData = new char[dwReadRet]; CopyMemory( m_pDPool[dwWaitRet].pData, szBuffer, dwReadRet ); m_pDPool[dwWaitRet].dwSize = dwReadRet; SetEvent( m_pDPool[dwWaitRet].hDPDeliver ); } } } } catch( ... ) { break; } if( WaitForSingleObject( m_hSystemExit, 0 ) != WAIT_TIMEOUT ) return; } }
bool CGSMPhone::NumberDecode(char *szNumber, int len) { if( len == 0 || szNumber == NULL ) return( false );
char c; for( int n = 0; n < len; n += 2 ) { c = szNumber[n]; szNumber[n] = szNumber[n+1]; szNumber[n+1] = c; } return( true ); }
char* CGSMPhone::NumberEncode(char *pPhoneNumber) { char* szData; szData = new char[40]; memset( szData, 0, 40 );
if( pPhoneNumber[0] == '+' ) { memcpy( szData, pPhoneNumber+1, strlen(pPhoneNumber) - 1 ); } else { memcpy( szData, pPhoneNumber, strlen(pPhoneNumber) ); }
if( strlen( szData ) % 2 != 0 ) { szData[strlen(szData)] = 'F'; }
char c; for( int n = 0; n < int(strlen(szData)); n += 2 ) { c = szData[n]; szData[n] = szData[n+1]; szData[n+1] = c; }
return szData; }
DWORD CGSMPhone::PDUDecodeChn(char *pMsg, char *&pResultData) { if( pMsg == NULL ) return( 0 ); int len = strlen( pMsg ); if( len % 2 != 0 ) return( 0 );
LPWSTR lpszW = new WCHAR[len/2+1]; memset( lpszW, 0, len + 2 ); BYTE* p = (BYTE *)lpszW; int i = 0, j = 0; char szTemp[3] = {0};
while( i < len ) { if( j % 2 ) { strncpy( szTemp, pMsg + i - 2, 2 ); } else { strncpy( szTemp, pMsg + i + 2, 2 ); } sscanf( szTemp, "%x", &p[j++] ); i += 2; }
len = j; pResultData = new char[len + 1]; memset( pResultData, 0, len + 1 ); WideCharToMultiByte( CP_ACP, 0, lpszW, -1, pResultData, len, NULL, FALSE ); delete [] lpszW;
return( len ); }
DWORD CGSMPhone::PDUDecodeEng(char *pMsg, char *&pResultData) { if( pMsg == NULL ) return( 0 ); int len = strlen( pMsg ); if( len % 2 != 0 ) return( 0 );
char psz[3] = {0}; BYTE b; int i = 0, j = 0; BYTE* pTemp; pTemp = new BYTE[len / 2]; memset( pTemp, 0, len / 2 );
while( i < len ) { strncpy( psz, pMsg + i, 2 ); sscanf( psz, "%x", &b ); pTemp[j++] = b; i += 2; }
len = j; i = 0; j = 0; pResultData = new char[len+20]; memset( pResultData, 0, len+20 );
char* pCur = pResultData; while( i < len ) { if( i == 0 ) { pCur[0] = pTemp[i] & 0x7F; } else { pCur[0] = ( pTemp[i] << j | pTemp[i-1] >> (8 - j) ) & 0x7F; } pCur ++; i += 1; j = ( j + 1 ) % 8; if( j == 0 ) i --; } pCur[0] = pTemp[i-1] >> (8 - j); delete [] pTemp;
return( pCur - pResultData ); }
DWORD CGSMPhone::PDUEncodeChn(char *pMsg, char *&pResultData) { int nLen = MultiByteToWideChar(CP_ACP, 0, pMsg, -1, NULL, NULL); LPWSTR lpszW = new WCHAR[nLen]; MultiByteToWideChar(CP_ACP, 0, pMsg, -1, lpszW, nLen);
DWORD dwResultSize = (nLen-1)*sizeof(WCHAR)*2; pResultData = new char[dwResultSize]; char szTemp[3] = {0}; for( int i = 0, j = 0; j < nLen-1; j++ ) { sprintf( szTemp, "%.2X", HIBYTE(lpszW[j]) ); CopyMemory( pResultData + i, szTemp, 2 ); i += 2; sprintf( szTemp, "%.2X", LOBYTE(lpszW[j]) ); CopyMemory( pResultData + i, szTemp, 2 ); i += 2; } delete [] lpszW; return( dwResultSize / 2 ); }
DWORD CGSMPhone::PDUEncodeEng(char *pMsg, char *&pResultData) { if( pMsg == NULL ) return( 0 ); int nMsgLen = strlen( pMsg ); pResultData = new char[nMsgLen * 2]; memset( pResultData, 0, nMsgLen * 2 );
char* pCur = pResultData; int i = 0, j = 0; while( i < nMsgLen ) { if( i < nMsgLen ) sprintf( pCur, "%.2X", BYTE(pMsg[i] >> j | pMsg[i+1] << ( 7 - j )) ); else sprintf( pCur, "%.2X", BYTE(pMsg[i] >> j) ); pCur += 2; i ++; j = ( j + 1 ) % 7; if( j == 0 ) i ++; } return( pCur - pResultData ); }
void CGSMPhone::Str2StrArr(CString strTemp, CStringArray &sa, char cDelimiter) { sa.RemoveAll(); for( ;; ) { int nPos;
if( ( nPos = strTemp.Find( cDelimiter ) ) != -1 ) { sa.Add( strTemp.Left( nPos ) ); strTemp = strTemp.Mid( nPos + 1 ); } else { if( !strTemp.IsEmpty() ) sa.Add( strTemp ); break; } } }
bool CGSMPhone::Open(int nPort, int nBaud) { char szPort[15]; wsprintf( szPort, "COM%d", nPort ); m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL ); if( m_hIDComDev == NULL ) return( false );
memset( &m_Overlapped, 0, sizeof( OVERLAPPED ) ); m_Overlapped.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
DCB dcb; dcb.DCBlength = sizeof( DCB ); GetCommState( m_hIDComDev, &dcb ); dcb.BaudRate = nBaud; dcb.ByteSize = 8; if( !SetCommState( m_hIDComDev, &dcb ) || !SetupComm( m_hIDComDev, 10000, 10000 ) || m_Overlapped.hEvent == NULL ) { DWORD dwError = GetLastError(); if( m_Overlapped.hEvent != NULL ) CloseHandle( m_Overlapped.hEvent ); CloseHandle( m_hIDComDev ); return( false ); }
m_bOpened = true; InitializeCriticalSection( &m_csComm ); Sleep( 2000 ); char szBuffer[1024] = {0}; DWORD dwRet = 0;
try { sprintf( szBuffer, "AT\r" ); WriteComm( szBuffer, 3 ); Sleep( 200 ); memset( szBuffer, 0, 1024 ); if( ReadStringFromComm( szBuffer, 1024 ) == 0 ) { CloseHandle( m_Overlapped.hEvent ); CloseHandle( m_hIDComDev ); DeleteCriticalSection( &m_csComm ); return( false ); }
memset( szBuffer, 0, 1024 ); sprintf( szBuffer, "AT&F E1\r" ); WriteComm( szBuffer, 8 ); Sleep( 200 ); memset( szBuffer, 0, 1024 ); if( ReadStringFromComm( szBuffer, 1024 ) == 0 ) { CloseHandle( m_Overlapped.hEvent ); CloseHandle( m_hIDComDev ); DeleteCriticalSection( &m_csComm ); return( false ); }
memset( szBuffer, 0, 1024 ); sprintf( szBuffer, "AT+CNMI=1,1,0,2,1\r" ); WriteComm( szBuffer, 18 ); Sleep( 200 ); memset( szBuffer, 0, 1024 ); if( ReadStringFromComm( szBuffer, 1024 ) == 0 ) { CloseHandle( m_Overlapped.hEvent ); CloseHandle( m_hIDComDev ); DeleteCriticalSection( &m_csComm ); return( false ); }
memset( szBuffer, 0, 1024 ); sprintf( szBuffer, "AT+CPMS?\r" ); WriteComm( szBuffer, 9 ); Sleep( 200 ); memset( szBuffer, 0, 1024 ); dwRet = ReadStringFromComm( szBuffer, 1024 ); if( dwRet > 0 ) { char* pDest = strstr( szBuffer, "+CPMS:" ); if( pDest != NULL ) { CString strTemp = CString( pDest + 7, 15 ); CStringArray saTemp; Str2StrArr( strTemp, saTemp, ',' ); if( saTemp.GetSize() > 3 ) m_dwSMContent = atoi( saTemp.GetAt( 2 ) ); } }
if( m_dwSMContent > 0 && m_dwSMContent < 50 ) { m_dwSMContentPoolNum = m_dwSMContent; } else { m_dwSMContentPoolNum = 30; }
memset( szBuffer, 0, 1024 ); sprintf( szBuffer, "AT+CGMM\r" ); WriteComm( szBuffer, 8 ); Sleep( 200 ); memset( szBuffer, 0, 1024 ); if( ReadStringFromComm( szBuffer, 1024 ) > 0 ) { char* pFirst = strchr( szBuffer, '\r' ); char* pNext = NULL; while( pFirst[0] == '\r' || pFirst[0] == '\n' ) pFirst ++; if( pFirst != NULL ) pNext = strchr( pFirst, '\r' ); if( pNext != NULL ) pNext[0] = '\0'; m_strMobileName = pFirst; } } catch( ... ) { CloseHandle( m_Overlapped.hEvent ); CloseHandle( m_hIDComDev ); DeleteCriticalSection( &m_csComm ); return( false ); }
m_hSystemExit = CreateEvent( NULL, TRUE, FALSE, NULL ); CreateSubmitPool( m_dwThreadPoolNum ); CreateDeliverPool( m_dwThreadPoolNum ); CreateShortMsgPool( m_dwSMContentPoolNum ); _beginthread( (void (__cdecl*)(void *))SubmitThreadFun,0,this ); _beginthread( (void (__cdecl*)(void *))DeliverThreadFun,0,this ); m_bStarted = true; // OutputDebugString( "Start OK." ); return( m_bStarted ); }
bool CGSMPhone::Close() { SetEvent( m_hSystemExit ); Sleep( 1200 ); CloseHandle( m_hSystemExit ); CloseHandle( m_Overlapped.hEvent ); CloseHandle( m_hIDComDev ); DeleteCriticalSection( &m_csComm ); FreeSubmitPool(); FreeDeliverPool(); FreeShortMsgPool(); return( true ); }
long CGSMPhone::Send(char *pNo, char *pMsg, BOOL bReport, BOOL bHandFree, BOOL bAsyn) { if( IsOpened() == false ) return( -4 ); if( pNo == NULL ) return( -5 ); if( pMsg == NULL ) return( -5 ); if( m_strSMCenter.IsEmpty() ) return( -1 );
char szSendBuf[1024] = {0}; char szTemp[20] = {0}; char* pReceiveData = NULL; int len = 0;
sprintf( szSendBuf, "AT+CMGS=60\r\n" ); Submit( szSendBuf, strlen(szSendBuf) ); memset( szSendBuf, 0, 1024 );
DWORD dwRet = Deliver( pReceiveData ); if( dwRet == 0 || strstr( pReceiveData, ">" ) == NULL ) { return( -5 ); } delete [] pReceiveData; pReceiveData = NULL;
char* p = NumberEncode( (char*)(LPCTSTR)m_strSMCenter ); // sprintf( szTemp, "%.2X", strlen( p ) ); memcpy( szSendBuf+len, "0891", 4 );// 91代表国际、ISDN/电话号码,没有必要选取其他的值 len += 4;
if( strncmp( p, "68", 2 ) != 0 ) { if( strlen( p ) != 12 ) return( -5 ); memcpy( szSendBuf+len, "68", 2 ); len += 2; } else { if( strlen( p ) != 14 ) return( -5 ); } memcpy( szSendBuf+len, p, strlen( p ) ); len += strlen( p ); delete [] p;
memcpy( szSendBuf+len, "1100", 4 );// 文件头字节,具体有很多设置,没有特别必要选取其他值 len += 4;
sprintf( szTemp, "%.2X", strlen( pNo ) ); memcpy( szSendBuf+len, szTemp, 2 ); len += 2;
memcpy( szSendBuf+len, "81", 2 );// 未知、ISDN/电话号码,没有必要选取其他值 len += 2;
p = NumberEncode( pNo ); memcpy( szSendBuf+len, p, strlen( p ) ); len += strlen( p ); delete [] p;
if( bHandFree ) {// 00代表TP_PID值, 18或08代表TP_DCS,A7代表短消息保存24小时 memcpy( szSendBuf+len, "0018A7", 6 ); } else { memcpy( szSendBuf+len, "0008A7", 6 ); } len += 6;
DWORD dw = PDUEncodeChn( pMsg, p ); sprintf( szTemp, "%.2X", dw ); memcpy( szSendBuf+len, szTemp, 2 ); len += 2;
memcpy( szSendBuf+len, p, dw * 2 ); len += dw * 2; delete [] p;
szSendBuf[len] = 0x1A;// 1A代表短消息结束 len += 1;
memcpy( szSendBuf+len, "\r", 1 ); len += 1;
Submit( szSendBuf, len ); dwRet = Deliver( pReceiveData ); if( dwRet > 0 ) { if( strstr( pReceiveData, szSendBuf ) != NULL ) { if( m_hWnd != NULL ) ::SendMessage( m_hWnd, PHONE_SMS_SUB, 0, 0 ); return( len ); } delete [] pReceiveData; pReceiveData = NULL; } return( 0 ); }
long CGSMPhone::GetShortMsg(SMS_Recv *pSms) { if( m_bStarted == false ) return( -1 ); DWORD dwWaitRet = WaitForMultipleObjects( m_dwSMContentPoolNum, m_phSMPHaveData, FALSE, 1000 ); if( dwWaitRet != WAIT_TIMEOUT ) { DWORD dwMsgLen = m_pSMPool[dwWaitRet].dwSize; char* pszBuffer; pszBuffer = new char[dwMsgLen + 1]; ZeroMemory( pszBuffer, dwMsgLen + 1 ); CopyMemory( pszBuffer, m_pSMPool[dwWaitRet].pData, dwMsgLen ); delete [] m_pSMPool[dwWaitRet].pData; SetEvent( m_pSMPool[dwWaitRet].hSMPIDLE ); InterlockedDecrement( &m_dwSMNumberInPool );
int len = 0; char* p = pszBuffer; char szTemp[1024] = {0}; bool bEng = false;
ZeroMemory( pSms, sizeof( SMS_Recv ) ); pSms->lMsgType = MSGTYPE_SMS;
CopyMemory( szTemp, p, 2 ); int nNumLen = atoi( szTemp ); p += 2; if( nNumLen <= 16 ) { CopyMemory( pSms->szSmsc, p, nNumLen * 2 ); NumberDecode( pSms->szSmsc, nNumLen * 2 ); if( pSms->szSmsc[nNumLen * 2 - 1] == 'F' ) pSms->szSmsc[nNumLen * 2 - 1] = '\0'; } p += nNumLen * 2; p += 4;
NumberDecode( p, 16 ); CopyMemory( pSms->szSender, "+", 1 ); CopyMemory( pSms->szSender + 1, p + 2, 13 ); p += 16;
if( strncmp( p, "0000", 4 ) ) bEng = true; p += 4;
NumberDecode( p, 10 ); sprintf( pSms->szTime, "20%.2s.%.2s.%.2s %.2s:%.2s", p, p + 2, p + 4, p + 6, p + 8 ); p += 10;
p += 4;
CopyMemory( szTemp, p, 2 ); int nMsgLen = atoi( szTemp ); p += 2;
char* pMsg = NULL; if( bEng ) { len = PDUDecodeEng( p, pMsg ); } else { len = PDUDecodeChn( p, pMsg ); } CopyMemory( pSms->szMsg, pMsg, len ); delete [] pszBuffer; return( 0 ); } return( -1 ); }
long CGSMPhone::GetShortMsg2(char *pNo, char *pMsg, char *pTime) { if( m_bStarted == false ) return( -1 ); DWORD dwWaitRet = WaitForMultipleObjects( m_dwSMContentPoolNum, m_phSMPHaveData, FALSE, 1000 ); if( dwWaitRet != WAIT_TIMEOUT ) { DWORD dwMsgLen = m_pSMPool[dwWaitRet].dwSize; char* pszBuffer; pszBuffer = new char[dwMsgLen + 1]; ZeroMemory( pszBuffer, dwMsgLen + 1 ); CopyMemory( pszBuffer, m_pSMPool[dwWaitRet].pData, dwMsgLen ); delete [] m_pSMPool[dwWaitRet].pData; SetEvent( m_pSMPool[dwWaitRet].hSMPIDLE ); InterlockedDecrement( &m_dwSMNumberInPool );
int len = 0; char* p = pszBuffer; char szTemp[1024] = {0}; bool bEng = false;
CopyMemory( szTemp, p, 2 ); int nNumLen = atoi( szTemp ); p += nNumLen * 2; p += 6;
NumberDecode( p, 16 ); ZeroMemory( pNo, 15 ); CopyMemory( pNo, "+", 1 ); CopyMemory( pNo + 1, p + 2, 13 ); p += 18;
if( strncmp( p, "00", 4 ) == 0 ) bEng = true; p += 2;
NumberDecode( p, 10 ); ZeroMemory( pTime, 17 ); sprintf( pTime, "20%.2s.%.2s.%.2s %.2s:%.2s", p, p + 2, p + 4, p + 6, p + 8 ); p += 10; p += 4;
CopyMemory( szTemp, p, 2 ); int nMsgLen = atoi( szTemp ); p += 2;
char* pResult = NULL; if( bEng ) { len = PDUDecodeEng( p, pResult ); } else { len = PDUDecodeChn( p, pResult ); } if( len > 0 ) { ZeroMemory( pMsg, len + 1 ); CopyMemory( pMsg, pResult, len ); delete [] pResult; } delete [] pszBuffer; return( 0 ); } return( -1 ); }
long CGSMPhone::GetMobileName(char *pName) { if( m_strMobileName.IsEmpty() ) { return( -1 ); } else { ZeroMemory( pName, m_strMobileName.GetLength() + 1 ); CopyMemory( pName, (LPCTSTR)m_strMobileName, m_strMobileName.GetLength() ); return( 0 ); } }

|