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

📄 mobilecontrol.cpp

📁 基于vc++6.0的收发手机短信、读写手机电话本的平台
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -