📄 mobilecontrol.cpp
字号:
// MobileControl.cpp: implementation of the CMobileControl class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MobileControl.h"
#ifndef _SMS_DISABLE
// Callgle 短信帮助信息
#define CALLGLE_HELP_INFO1 "\
#<PMAccount1,2,...>#<Content>\n\
[{for example}]:\n\
#101,102#Hello!\n\
"
#define CALLGLE_HELP_INFO2 "\
##<Type Code>#[GroupName1,2, ...]#<Content>\n\
[{for example}]:\n\
##Bulletin#PerDept,MarketDept#Hello!\n\
"
// 是否是电话号码字符
#define IS_PHONE_CHAR(ch) (((ch)>=_T('0') && (ch)<=_T('9')) || (ch)==_T('*') || (ch)==_T('#') || (ch)==_T('+'))
//
// 获取正确的电话号码字符串
// 如:输入"+12ab*d#()982", 输出"+12*#982"
// ret : 处理后字符串长度
//
int GetRightPhoneNOString ( IN OUT TCHAR* szPhoneNO, TCHAR cExtra=_T('\0') )
{
if ( !szPhoneNO ) return 0;
int nLen = lstrlen ( szPhoneNO );
int count = 0;
for ( int i=0; i<nLen; i++ )
{
if ( IS_PHONE_CHAR ( szPhoneNO[i] ) || ( cExtra!=_T('\0') && szPhoneNO[i] == cExtra ) )
{
szPhoneNO [ count++ ] = szPhoneNO[i];
}
}
szPhoneNO [ count ] = _T('\0');
return count;
}
//
// 手机工作线程
//
DWORD WINAPI ThreadProc_Mobile (
LPVOID lpParameter // thread data
)
{
ASSERT ( lpParameter );
CMobileControl *pMobileControl = (CMobileControl*)lpParameter;
BOOL bRet = pMobileControl->ThreadProc_Mobile();
pMobileControl->ClearSendQueue ();
return bRet;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMobileControl::CMobileControl()
: m_Proc_ReceivedSMS ( NULL )
, m_wParam ( NULL )
, m_lParam ( NULL )
, m_hEvt_TerminateSys ( NULL )
, m_hThread_Mobile ( NULL )
, m_bRunAsServer ( FALSE )
, m_bRecvSMSEnable ( FALSE )
, m_eRunState ( ENUM_RunState_Start )
, m_InitializeInterfaceInterval ( INITIALIZE_INTERFACE_INTERVAL )
, m_nComNO_UserDefine ( 0 )
, m_eMobileStatus ( ENUM_ERROR_TYPE_INVALID_DATA )
, m_eMobileStatus_Real ( ENUM_ERROR_TYPE_INVALID_DATA )
, m_Proc_HandleMobileStatusChange ( NULL )
, m_paraHandleMobileStatusChange ( 0 )
, m_pdwSentSMSCount ( NULL )
, m_pMobileParameter ( NULL )
, m_bMustRegistered ( TRUE )
{
m_hEvt_SMSSendQueue = NULL;
m_Ary_SMS_SendQueue.SetSize ( 0, 10*sizeof(t_SMS_SendQueue) );
m_csSMSHead = _T("SMS:\n");
m_csSMSTail = _T("\nSent by chrys");
HwDbgLog ( L_DEBUG, _T("CMobileControl 构造完成") );
}
CMobileControl::~CMobileControl()
{
RestoreRecvSMSNotifyMode ();
ChangeMobileStatus ( ENUM_ERROR_TYPE_NoneMobile );
if ( m_hEvt_TerminateSys )
::SetEvent ( m_hEvt_TerminateSys );
WaitForThreadEnd ( &m_hThread_Mobile );
m_CSFor_SMSSendQueue.Lock ();
m_Ary_SMS_SendQueue.RemoveAll();
m_CSFor_SMSSendQueue.Unlock ();
m_Ary_MobileNOHead.RemoveAll ();
// 关闭事件对象
if ( m_hEvt_SMSSendQueue && m_hEvt_SMSSendQueue != INVALID_HANDLE_VALUE )
::CloseHandle ( m_hEvt_SMSSendQueue );
m_hEvt_SMSSendQueue = NULL;
Log ( L_VERBOSE, _T("Mobile module be uninit") );
}
BOOL CMobileControl::Init (
BOOL bRunAsServer, // 是否当作服务器运行
BOOL bRecvSMSEnable, // 是否允许自动收取手机短信
HANDLE hEvt_TerminateSys,
int nComNO,
int nBaudRate
)
{
if ( m_hThread_Mobile && m_hThread_Mobile != INVALID_HANDLE_VALUE )
{
return TRUE;
}
m_hEvt_TerminateSys = hEvt_TerminateSys;
ASSERT ( m_hEvt_TerminateSys && m_hEvt_TerminateSys != INVALID_HANDLE_VALUE );
m_bRunAsServer = bRunAsServer;
m_bRecvSMSEnable = bRecvSMSEnable;
CHwMobile::SetModulePara ( nComNO, nBaudRate );
m_nComNO_UserDefine = nComNO;
m_eRunState = ENUM_RunState_Init;
// 做服务器运行时就创建一个手机工作线程
if ( m_bRunAsServer )
{
if ( !m_hEvt_SMSSendQueue )
{
m_hEvt_SMSSendQueue = ::CreateEvent ( NULL, FALSE, FALSE, NULL );
if ( !m_hEvt_SMSSendQueue || m_hEvt_SMSSendQueue == INVALID_HANDLE_VALUE )
return FALSE;
}
if ( !m_hThread_Mobile )
{
m_hThread_Mobile = ::CreateThread ( NULL, 0, ::ThreadProc_Mobile, this, 0, NULL );
if ( !m_hThread_Mobile || m_hThread_Mobile == INVALID_HANDLE_VALUE )
return FALSE;
}
else
{
::ResumeThread ( m_hThread_Mobile );
}
}
else
{
return InitMobileControl ();
}
return TRUE;
}
//
// 初始化手机模块
//
BOOL CMobileControl::InitMobileControl ()
{
static DWORD dwStartTime = 0;
if ( !TimeIntervalArrived ( dwStartTime, m_InitializeInterfaceInterval ) )
{
return FALSE;
}
#ifndef _DEBUG
m_InitializeInterfaceInterval += INITIALIZE_INTERFACE_INTERVAL;
if ( m_InitializeInterfaceInterval > 30 )
m_InitializeInterfaceInterval = 30;
#endif
BOOL bRet = FALSE;
int nComNO = 0;
for ( int i=0; i<3; i++ )
{
if ( InitMobileModule ( nComNO ) )
{
bRet = TRUE;
break;
}
if ( ::WaitForSingleObject ( m_hEvt_TerminateSys, 100 ) == WAIT_OBJECT_0 )
{
return FALSE;
}
}
if ( m_bInitMobileLastRes != bRet )
{
if ( bRet )
{
Log ( L_VERBOSE | L_OUT_UI, _T("Initialize mobile module [COM%d] successfully"), nComNO );
}
else
{
Log ( L_WARNING | L_OUT_UI, _T("Initialize mobile module failed") );
}
m_bInitMobileLastRes = bRet;
}
if ( bRet )
{
if ( !m_pMobileParameter || lstrlen(m_pMobileParameter->szLocalCountryCode) < 1 || lstrlen(m_pMobileParameter->szLocalAreaCode) < 1 )
{
Log ( L_WARNING | L_OUT_UI, _T("Please set country code") );
ChangeMobileStatus ( ENUM_ERROR_TYPE_ConfigNotRight );
}
else
{
ChangeMobileStatus ( ENUM_ERROR_TYPE_SUCCESS );
}
}
else
{
ChangeMobileStatus ( ENUM_ERROR_TYPE_NotInitialized );
}
return bRet;
}
//
// 只做初始化手机模块的操作
//
BOOL CMobileControl::InitMobileModule ( int &nComNO )
{
BOOL bRet = FALSE;
nComNO = 0;
// 指定一个串口
if ( m_nComNO_UserDefine >= 1 && m_nComNO_UserDefine <= MAX_COM_NO )
{
nComNO = m_nComNO_UserDefine;
bRet = InitMobileOneCOM ( nComNO );
}
// 自动
else
{
for ( nComNO = 1; nComNO <= MAX_COM_NO; nComNO ++ )
{
if ( InitMobileOneCOM ( nComNO ) )
{
bRet = TRUE;
break;
}
if ( ::WaitForSingleObject ( m_hEvt_TerminateSys, 0 ) == WAIT_OBJECT_0 )
return FALSE;
}
}
return bRet;
}
//
// 用一个串口初始化手机模块
//
BOOL CMobileControl::InitMobileOneCOM ( int nComNO )
{
SetModulePara ( nComNO );
if ( CHwMobile::Init () )
{
if ( m_bMustRegistered )
{
BOOL bIsRegistered = FALSE;
for ( int i=0; i<3; i++ )
{
if ( GSMModuleIsRegistered () )
{
bIsRegistered = TRUE;
break;
}
if ( ::WaitForSingleObject ( m_hEvt_TerminateSys, 3*1000 ) == WAIT_OBJECT_0 )
return FALSE;
}
if ( !bIsRegistered )
{
Log ( L_ERROR | L_OUT_UI, _T("Please use [HOWA] mobile module") );
return FALSE;
}
}
ShowGSMModuleInfo ();
if ( !GetSMSCNO () )
{
Log ( L_ERROR | L_OUT_UI, _T("Get SMSC Failed") );
if ( ::WaitForSingleObject ( m_hEvt_TerminateSys, 5*1000 ) == WAIT_OBJECT_0 )
return FALSE;
}
else
{
// 将手机中收到的短信全部读出来
ReadExistSMSInMobile ();
return TRUE;
}
}
CloseCOM ();
return FALSE;
}
//
// 手机工作线程
//
BOOL CMobileControl::ThreadProc_Mobile()
{
// 等待线程执行通知
if ( m_EvtThreadCanRun && m_EvtThreadCanRun != INVALID_HANDLE_VALUE )
{
HANDLE EvtAry[] = { m_EvtThreadCanRun, m_hEvt_TerminateSys };
if ( ::WaitForMultipleObjects ( COUNT(EvtAry), EvtAry, FALSE, INFINITE ) - WAIT_OBJECT_0 == 1 )
return FALSE;
}
int nRet = 0;
for ( ;; )
{
if ( m_eMobileStatus != ENUM_ERROR_TYPE_MobileDisable )
{
switch ( m_eRunState )
{
case ENUM_RunState_Start:
{
m_eRunState = ENUM_RunState_Init;
break;
}
case ENUM_RunState_Init:
{
// 初始化手机模块
if ( InitMobileControl () )
{
m_eRunState = ENUM_RunState_Runing;
}
else
{
if ( ::WaitForSingleObject ( m_hEvt_TerminateSys, INITIALIZE_INTERFACE_INTERVAL*1000 ) == WAIT_OBJECT_0 )
return TRUE;
}
break;
}
case ENUM_RunState_Runing:
{
nRet = Runing ();
if ( nRet == 1 ) // 系统要终止
return TRUE;
break;
}
default:
return FALSE;
}
}
else if ( ::WaitForSingleObject ( m_hEvt_TerminateSys, 3000 ) == WAIT_OBJECT_0 )
{
return FALSE;
}
}
return TRUE;
}
//
// 正在运行
// return : -----------------------------------------------------
// 1 - 系统要终止
// 0 - 运行出错,需要重新来过
//
int CMobileControl::Runing()
{
ASSERT ( m_hEvt_TerminateSys );
HANDLE hEvtAry[] = { m_hEvt_TerminateSys, m_hEvt_SMSSendQueue };
for ( ;; )
{
DWORD dwRet = ::WaitForMultipleObjects ( COUNT(hEvtAry), hEvtAry, FALSE, MOBILE_THREAD_SLEEP_TIME );
if ( m_eMobileStatus != ENUM_ERROR_TYPE_MobileDisable )
{
switch ( dwRet - WAIT_OBJECT_0 )
{
// 系统要终止咯
case 0:
{
return 1;
}
// 请求发送手机短信
case 1:
{
SendSMSQueue ();
break;
}
// 定时时间
default:
{
ReadNewSMS ();
break;
}
}
}
if ( m_eRunState != ENUM_RunState_Runing )
{
break;
}
}
return 0;
}
//
// 发送短信,过长的短信处理:这个函数处理成多条短信;
//
ENUM_ERROR_TYPE CMobileControl::SendSMS (
ENUM_MOBILESMSTYPE eMobileSMSType,
LPCTSTR lpszReceiverMobileNO, // 接收者手机号
char* szSMSContent_Byte, // 单字节短信内容
DWORD dwSMSSenderID_Sender/*=INVALID_SMSSenderID*/, // 发送者的 PM 号码
FUNC_SendSMSEnd Proc_SendSMSEnd/*=NULL*/, // 发送完成时通过该回调函数来通知请求者
WPARAM wParam/*=NULL*/,
LPARAM lParam/*=NULL*/
)
{
#ifndef _DEBUG
ENUM_ERROR_TYPE eMobileStatus = GetMobileStatus();
if ( eMobileStatus != ENUM_ERROR_TYPE_SUCCESS )
return eMobileStatus;
#endif
// 超过最大SIM卡发送短信条数
if ( m_pMobileParameter && m_pdwSentSMSCount && m_pMobileParameter->dwSMSCountPerSIM > 0 &&
*m_pdwSentSMSCount >= m_pMobileParameter->dwSMSCountPerSIM )
{
return ENUM_ERROR_TYPE_OverSMSCountPerSIM;
}
// int nRetTemp = IsMobileNO ( lpszReceiverMobileNO );
// CString csTemp = SimplifyMobileNO ( lpszReceiverMobileNO );
CString csReceiverMobileNO = GET_SAFE_STRING( lpszReceiverMobileNO );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -