📄 mobilecontrol.cpp
字号:
// MobileControl.cpp: implementation of the CMobileControl class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MobileControl.h"
#include "..\\..\\PublicOpt.h"
#ifndef _2Lines
// 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\
"
//
// 手机工作线程
//
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(LOG_FUNC ExternLog)
: CHwMobile ( ExternLog )
, 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_pHwMysql_PMData ( NULL )
, m_pHwMysql_PMMsg ( NULL )
, m_pHwMysql_PMFullPN ( NULL )
, m_pdwSentSMSCount ( NULL )
, m_pMobileParameter ( NULL )
{
m_hEvt_SMSSendQueue = NULL;
m_Ary_SMS_SendQueue.SetSize ( 0, 10*sizeof(t_SMS_SendQueue) );
DbgLog ( L_DEBUG, "CMobileControl 构造完成" );
}
CMobileControl::~CMobileControl()
{
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;
LogML ( L_VERBOSE, "Mobile module be(#2) 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 time_t tStartTime = 0;
if ( !TimeIntervalArrived ( tStartTime, 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;
}
}
static BOOL bLastRes = -1;
if ( bLastRes != bRet )
{
if ( bRet )
{
LogML ( L_VERBOSE | L_OUT_DLG, "Initialize mobile module [COM%d] successfully", nComNO );
}
else
{
LogML ( L_VERBOSE | L_OUT_DLG, "Initialize mobile module failed" );
}
bLastRes = bRet;
}
if ( bRet )
{
if ( m_pHwMysql_PMFullPN->GetLocalCodeHead () )
{
ChangeMobileStatus ( ENUM_ERROR_TYPE_SUCCESS );
}
else
{
LogML ( L_WARNING | L_OUT_DLG, "Please set country code" );
ChangeMobileStatus ( ENUM_ERROR_TYPE_ConfigNotRight );
}
}
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 ( !GetSMSCNO () )
{
LogML ( L_ERROR | L_OUT_DLG, "Get SMSC Failed" );
}
// 将手机中收到的短信全部读出来
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 ( LENGTH(EvtAry), EvtAry, FALSE, INFINITE ) - WAIT_OBJECT_0 == 1 )
return FALSE;
}
int nRet = 0;
for ( ;; )
{
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;
}
}
return TRUE;
}
//
// 正在运行
// return : -----------------------------------------------------
// 1 - 系统要终止
// 0 - 运行出错,需要重新来过
//
int CMobileControl::Runing()
{
ASSERT ( m_hEvt_TerminateSys );
HANDLE hEvtAry[] = { m_hEvt_TerminateSys, m_hEvt_SMSSendQueue };
for ( ;; )
{
DWORD dwRet = ::WaitForMultipleObjects ( LENGTH(hEvtAry), hEvtAry, FALSE, MOBILE_THREAD_SLEEP_TIME );
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;
}
//
// 发送短信,过长的短信处理:如果未指定 wzSMSContent_Wide 时会被这个函数处理成多条短信;
// 如果指定了 wzSMSContent_Wide 请在调用本函数前做先做好分条(超过长度的短信被分为多条)处理
//
ENUM_ERROR_TYPE CMobileControl::SendSMS (
ENUM_MOBILESMSTYPE eMobileSMSType,
LPCTSTR lpszReceiverMobileNO, // 接收者手机号
LPCTSTR lpszSMSContent_Byte, // 单字节短信内容
WCHAR *wzSMSContent_Wide/*=NULL*/, // 宽字符短信内容
DWORD dwPMAccount_Sender/*=INVALID_PMACCOUNT*/, // 发送者的 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卡发送短信条数
ASSERT ( m_pMobileParameter );
if ( 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 );
BOOL bInternationalMobileNO = TRUE;
ENUM_ERROR_TYPE eErrorType = ENUM_ERROR_TYPE_SUCCESS;
eErrorType = StandardMobileNO ( csReceiverMobileNO, &bInternationalMobileNO );
if ( !eErrorType == ENUM_ERROR_TYPE_SUCCESS )
return eErrorType;
// 指定了宽字符短信内容时就不要做分条(超过长度的短信被分为多条)处理了
if ( wzSMSContent_Wide && wcslen(wzSMSContent_Wide) > 0 )
{
return SendOnePartSMS ( eMobileSMSType, csReceiverMobileNO, bInternationalMobileNO, lpszSMSContent_Byte,
wzSMSContent_Wide, dwPMAccount_Sender, Proc_SendSMSEnd, wParam, lParam );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -