⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mobilecontrol.cpp

📁 短信收发的程序源代码。能自动检测手机是否连接好
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -