www.pudn.com > SMS.rar > MobileControl.cpp
// MobileControl.cpp: implementation of the CMobileControl class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MobileControl.h" #ifndef _SMS_DISABLE // Callgle 短信帮助信息 #define CALLGLE_HELP_INFO1 "\ ## \n\ [{for example}]:\n\ #101,102#Hello!\n\ " #define CALLGLE_HELP_INFO2 "\ ## #[GroupName1,2, ...]# \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 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 ); BOOL bInternationalMobileNO = TRUE; ENUM_ERROR_TYPE eErrorType = ENUM_ERROR_TYPE_SUCCESS; if ( ENUM_ERROR_TYPE_SUCCESS != StandardMobileNO ( csReceiverMobileNO, &bInternationalMobileNO ) ) { Log ( L_WARNING, _T("Standard MobileNO failed") ); } // 发送短信前做分条处理 ASSERT ( szSMSContent_Byte && strlen(szSMSContent_Byte) > 0 ); CStringArray *pAryStr = PartMessengerOrSMSText ( GetCompatibleString(szSMSContent_Byte,FALSE), 0, TRUE, NULL, NULL ); if ( !pAryStr ) return ENUM_ERROR_TYPE_PARAMETER; for ( int i=0; i GetSize(); i++ ) { CString csTextOne = pAryStr->GetAt ( i ); csTextOne.TrimLeft(); csTextOne.TrimRight(); ENUM_ERROR_TYPE eErrorTypeTemp = SendOnePartSMS ( eMobileSMSType, csReceiverMobileNO, bInternationalMobileNO, CMultiByteString(csTextOne).GetBuffer(), dwSMSSenderID_Sender, Proc_SendSMSEnd, wParam, lParam ); if ( eErrorTypeTemp != ENUM_ERROR_TYPE_SUCCESS ) { eErrorType = eErrorTypeTemp; } } pAryStr->RemoveAll(); delete pAryStr; return eErrorType; } ENUM_ERROR_TYPE CMobileControl::InfillSMParam ( OUT SM_PARAM &SmParam, IN CString csReceiverMobileNO // 接收者手机号 ) { memset ( &SmParam, 0, sizeof(SM_PARAM) ); if ( !m_nInitOK ) return ENUM_ERROR_TYPE_NoneMobile; GetSMSCNO (); if ( m_csSMSC.GetLength() <= MIN_MOBILENO_LENGTH ) { Log ( L_ERROR, _T("SMSC Error, Cancel send SMS to [%s]"), csReceiverMobileNO ); return ENUM_ERROR_TYPE_ConfigNotRight; } CString csSMSC = m_csSMSC; // 填充短消息结构 StandardMobileNOHead ( csSMSC ); CMultiByteString ( csSMSC, STRING_IS_SOFTCODE, SmParam.SCA, sizeof(SmParam.SCA) ); CMultiByteString ( csReceiverMobileNO, STRING_IS_SOFTCODE, SmParam.TPA, sizeof(SmParam.TPA) ); SmParam.TP_PID = 0; return ENUM_ERROR_TYPE_SUCCESS; } // // 发送短信,过长的短信,这个模块不会处理,请在调用前先处理 // ENUM_ERROR_TYPE CMobileControl::SendOnePartSMS ( ENUM_MOBILESMSTYPE eMobileSMSType, LPCTSTR lpszReceiverMobileNO, // 接收者手机号 BOOL bInternationalMobileNO, char* szSMSContent_Byte, // 单字节短信内容 DWORD dwSMSSenderID_Sender/*=INVALID_SMSSenderID*/, // 发送者的 PM 号码 FUNC_SendSMSEnd Proc_SendSMSEnd/*=NULL*/, // 发送完成时通过该回调函数来通知请求者 WPARAM wParam/*=NULL*/, LPARAM lParam/*=NULL*/ ) { if ( !szSMSContent_Byte || strlen(szSMSContent_Byte) <= 0 ) return ENUM_ERROR_TYPE_INVALID_DATA; // 完全相同(短信内容和接收者手机号相同)的短信在 SAME_SMS_INTERVAL_TIMELONG 秒内不允许发送 // 防止短信炸弹,也防止 UDP 通信时收到重发的短信包 #ifndef _DEBUG static CString csReceiverMobileNO_Last, csSMSContent_Last; static time_t tTimeLast = 0; if ( csReceiverMobileNO_Last == lpszReceiverMobileNO && csSMSContent_Last == szSMSContent_Byte ) { if ( difftime ( time(NULL), tTimeLast ) < SAME_SMS_INTERVAL_TIMELONG ) { return ENUM_ERROR_TYPE_RepeatedRequest; } } csReceiverMobileNO_Last = GET_SAFE_STRING ( lpszReceiverMobileNO ); csSMSContent_Last = GET_SAFE_STRING ( szSMSContent_Byte ); tTimeLast = time(NULL); #endif // 队列是否满了? m_CSFor_SMSSendQueue.Lock (); if ( m_Ary_SMS_SendQueue.GetSize() > MAX_SMSQUEUE_NUM ) { m_CSFor_SMSSendQueue.Unlock (); return ENUM_ERROR_TYPE_BufferQueueFill; } m_CSFor_SMSSendQueue.Unlock (); // 创建一个队列节点 t_SMS_SendQueue SMS_SendQueue; memset ( &SMS_SendQueue, 0, sizeof(t_SMS_SendQueue) ); SMS_SendQueue.dwSMSSenderID_Sender = dwSMSSenderID_Sender; SMS_SendQueue.Proc_SendSMSEnd = Proc_SendSMSEnd; SMS_SendQueue.wParam = wParam; SMS_SendQueue.lParam = lParam; SMS_SendQueue.eMobileSMSType = eMobileSMSType; ENUM_ERROR_TYPE eErrorType = InfillSMParam ( SMS_SendQueue.sm, GET_SAFE_STRING(lpszReceiverMobileNO) ); strncpy ( SMS_SendQueue.sm.TP_UD_Byte, szSMSContent_Byte, COUNT(SMS_SendQueue.sm.TP_UD_Byte) ); SMS_SendQueue.sm.bInternationalMobileNO = bInternationalMobileNO; if ( eErrorType != ENUM_ERROR_TYPE_SUCCESS ) return eErrorType; // 做服务器运行时,将要发送的短信包添加到队列中 BOOL bRes = TRUE; if ( m_bRunAsServer ) { m_CSFor_SMSSendQueue.Lock (); m_Ary_SMS_SendQueue.Add ( SMS_SendQueue ); m_CSFor_SMSSendQueue.Unlock (); // 然后通知手机工作线程 ASSERT ( m_hEvt_SMSSendQueue && m_hEvt_SMSSendQueue != INVALID_HANDLE_VALUE ); ::SetEvent ( m_hEvt_SMSSendQueue ); } // 单机版时直接发送短信 else { bRes = SendOneSMSQueue ( SMS_SendQueue ); } return ( bRes ? ENUM_ERROR_TYPE_SUCCESS : ENUM_ERROR_TYPE_SendSMSFailed ); } // // 发送短信队列里的短信 // BOOL CMobileControl::SendSMSQueue () { ASSERT ( m_bRunAsServer ); // 发送队列里的一条短消息 m_CSFor_SMSSendQueue.Lock (); if ( m_Ary_SMS_SendQueue.GetSize() <= 0 ) { m_CSFor_SMSSendQueue.Unlock (); return TRUE; } t_SMS_SendQueue &SMS_SendQueue_Refer = m_Ary_SMS_SendQueue.GetAt ( 0 ); t_SMS_SendQueue SMS_SendQueue; memcpy ( &SMS_SendQueue, &SMS_SendQueue_Refer, sizeof(t_SMS_SendQueue) ); m_Ary_SMS_SendQueue.RemoveAt ( 0 ); m_CSFor_SMSSendQueue.Unlock (); BOOL bRes = SendOneSMSQueue ( SMS_SendQueue ); // 系统要退出了 if ( ::WaitForSingleObject ( m_hEvt_TerminateSys, 0 ) == WAIT_OBJECT_0 ) return TRUE; else { m_CSFor_SMSSendQueue.Lock (); // 还有短信需要发送 if ( m_Ary_SMS_SendQueue.GetSize() > 0 ) { ::SetEvent ( m_hEvt_SMSSendQueue ); } m_CSFor_SMSSendQueue.Unlock (); } return TRUE; } BOOL CMobileControl::AppTextToSMSContent ( SM_PARAM &sm, LPCTSTR lpszAppText, int &nFreeCharNum, BOOL bAddToHead ) { ASSERT ( lpszAppText ); int nAppTextTotalCharNum = 0; ParseSMSContentAttr ( CMultiByteString(lpszAppText).GetBuffer(), &nAppTextTotalCharNum ); if ( nAppTextTotalCharNum < nFreeCharNum ) { CString csTD_UD_Byte = GetCompatibleString(sm.TP_UD_Byte,FALSE); if ( bAddToHead ) csTD_UD_Byte.Insert ( 0, lpszAppText ); else csTD_UD_Byte += lpszAppText; CMultiByteString ( csTD_UD_Byte, STRING_IS_SOFTCODE, sm.TP_UD_Byte, sizeof(sm.TP_UD_Byte) ); nFreeCharNum -= nAppTextTotalCharNum; return TRUE; } return FALSE; } BOOL CMobileControl::SendOneSMSQueue ( t_SMS_SendQueue &SMS_SendQueue ) { ASSERT ( m_nInitOK ); ASSERT ( m_pMobileParameter ); ASSERT ( m_handleCOM && m_handleCOM!=INVALID_HANDLE_VALUE ); // 系统要退出了 if ( ::WaitForSingleObject ( m_hEvt_TerminateSys, 0 ) == WAIT_OBJECT_0 ) { if ( SMS_SendQueue.Proc_SendSMSEnd ) { SMS_SendQueue.Proc_SendSMSEnd ( ENUM_ERROR_TYPE_SysTerminate, &SMS_SendQueue.sm, SMS_SendQueue.wParam, SMS_SendQueue.lParam ); } return FALSE; } int nTotalCharNum = 0, nFreeCharNum = 0, nTP_DCS = 0; int nOneSMSByteCount = ParseSMSContentAttr ( SMS_SendQueue.sm.TP_UD_Byte, &nTotalCharNum, &nFreeCharNum, &nTP_DCS ); SMS_SendQueue.sm.TP_DCS = nTP_DCS; ASSERT ( nFreeCharNum >= 0 ); CString csSMSContent; // 发送以“#howa!#”开头的短信,不附加短信头和尾 if ( strstr(SMS_SendQueue.sm.TP_UD_Byte,"#howa!#") == SMS_SendQueue.sm.TP_UD_Byte ) { Log ( L_VERBOSE, _T("Not append SMS head and tail") ); char TP_UD_Byte_Temp[ONE_SMS_TEXT_LENGTH+1] = {0}; memset ( SMS_SendQueue.sm.TP_UD_Byte, 0, sizeof(SMS_SendQueue.sm.TP_UD_Byte) ); strcpy ( TP_UD_Byte_Temp, &SMS_SendQueue.sm.TP_UD_Byte[7] ); strcpy ( SMS_SendQueue.sm.TP_UD_Byte, TP_UD_Byte_Temp ); csSMSContent = GetCompatibleString(SMS_SendQueue.sm.TP_UD_Byte,FALSE); } // 附加短信“#760815# [短信内容] Sent by "callgle" ” else { csSMSContent = GetCompatibleString(SMS_SendQueue.sm.TP_UD_Byte,FALSE); if ( AppTextToSMSContent ( SMS_SendQueue.sm, m_csSMSTail, nFreeCharNum, FALSE ) ) { AppTextToSMSContent ( SMS_SendQueue.sm, m_csSMSHead, nFreeCharNum, TRUE ); } } BOOL bRet = FALSE; CStringArray StrAry_MobileNO; ASSERT ( m_pMobileParameter ); bRet = SendOneSMSPkt ( &(SMS_SendQueue.sm) ); StrAry_MobileNO.Add ( SimplifyMobileNO(GetCompatibleString(SMS_SendQueue.sm.TPA,FALSE)) ); if ( SMS_SendQueue.Proc_SendSMSEnd ) { SMS_SendQueue.Proc_SendSMSEnd ( bRet?ENUM_ERROR_TYPE_SUCCESS:ENUM_ERROR_TYPE_SendSMSFailed, &(SMS_SendQueue.sm), SMS_SendQueue.wParam, SMS_SendQueue.lParam ); } if ( bRet && m_pdwSentSMSCount ) { (*m_pdwSentSMSCount) ++; } // 将发送完的短信保存到数据库 for ( int i=0; i SaveSMSToHistoryRecord ( SMS_SendQueue.dwSMSSenderID_Sender, StrAry_MobileNO.GetAt(i), SMS_SendQueue.eMobileSMSType, ENUM_SMSOrientation_Send, (bRet?ENUM_BOOL_TRUE:ENUM_BOOL_FALSE), NULL, csSMSContent );*/ //u } return bRet; } void CMobileControl::ClearSendQueue () { // 还有短信需要发送 while ( TRUE ) { m_CSFor_SMSSendQueue.Lock (); if ( m_Ary_SMS_SendQueue.GetSize() <= 0 ) { m_CSFor_SMSSendQueue.Unlock (); break; } t_SMS_SendQueue &SMS_SendQueue_Refer = m_Ary_SMS_SendQueue.GetAt ( 0 ); t_SMS_SendQueue SMS_SendQueue; memcpy ( &SMS_SendQueue, &SMS_SendQueue_Refer, sizeof(t_SMS_SendQueue) ); m_Ary_SMS_SendQueue.RemoveAt ( 0 ); m_CSFor_SMSSendQueue.Unlock (); SendOneSMSQueue ( SMS_SendQueue ); } } BOOL CMobileControl::HandleRecvSMS(SM_PARAM *pSMRecv) { ASSERT ( pSMRecv ); if ( GetMobileStatus() == ENUM_ERROR_TYPE_MobileDisable ) { Log ( L_WARNING, _T("Discard recevied SMS [%s : %s], because Mobile mobule disable"), GetCompatibleString(pSMRecv->TPA,FALSE), GetCompatibleString(pSMRecv->TP_UD_Byte,FALSE) ); return FALSE; } if ( !CHwMobile::HandleRecvSMS ( pSMRecv ) ) return FALSE; CString csTemp = SimplifyMobileNO ( GetCompatibleString(pSMRecv->TPA,FALSE) ); CMultiByteString ( csTemp, STRING_IS_SOFTCODE, pSMRecv->TPA, sizeof(pSMRecv->TPA) ); ASSERT ( m_Proc_ReceivedSMS ); return m_Proc_ReceivedSMS ( pSMRecv, m_wParam, m_lParam ); } // // 读最新收到的短信 // BOOL CMobileControl::ReadNewSMS () { if ( !m_bRecvSMSEnable ) return TRUE; if ( HANDLE_IS_VALID(m_hEvt_IsBusy) && ::WaitForSingleObject(m_hEvt_IsBusy,0)==WAIT_OBJECT_0 ) return TRUE; ASSERT ( m_nInitOK ); // 系统要退出了 if ( ::WaitForSingleObject ( m_hEvt_TerminateSys, 0 ) == WAIT_OBJECT_0 ) return TRUE; ASSERT ( m_handleCOM && m_handleCOM!=INVALID_HANDLE_VALUE ); if ( !QueryDeviceExist () ) { return FALSE; } // 收短信通知 return gsmReadMessageContent ( "+CMT:" ); } // // 读取手机中已经存在的所有短信 // BOOL CMobileControl::ReadExistSMSInMobile() { if ( !m_bRecvSMSEnable ) return TRUE; if ( Write ( "AT+CMGL=4\r" ) < 1 ) return FALSE; if ( !WaitForDataToRead ( 2, 5*WAIT_DATA_TIMEOUT ) ) return FALSE; return gsmReadMessageContent ( "+CMGL:" ); } // // 读取手机所有电话本。 // 注意:及时删除返回的指针 // t_Ary_PhoneBook* CMobileControl::ReadPhoneBook() { t_Ary_PhoneBook *pAry_PhoneBook = new t_Ary_PhoneBook; if ( !pAry_PhoneBook ) { ::AfxThrowMemoryException (); return NULL; } pAry_PhoneBook->SetSize ( 0, 10*sizeof(t_PhoneBook) ); if ( !gsmReadPhoneBook ( _T("SM"), pAry_PhoneBook ) ) return pAry_PhoneBook; if ( !gsmReadPhoneBook ( _T("ME"), pAry_PhoneBook ) ) return pAry_PhoneBook; return pAry_PhoneBook; } LPCTSTR CMobileControl::GetObjectName() { return _T("Mobile control module"); } // // 检测字符串 lpszStr 的是否以字符串 lpszHead1 或 lpszHead2 或 lpszHead3 开头 // LPCTSTR CMobileControl::CheckHeadStr ( LPCTSTR lpszStr, LPCTSTR lpszHead1, LPCTSTR lpszHead2, LPCTSTR lpszHead3 ) { if ( !lpszStr || !lpszHead1 || lstrlen(lpszStr) <= 0 ) return NULL; if ( strstr_hw ( lpszStr, lpszHead1 ) == lpszStr ) return lpszHead1; if ( lpszHead2 && strstr_hw ( lpszStr, lpszHead2 ) == lpszStr ) return lpszHead2; if ( lpszHead3 && strstr_hw ( lpszStr, lpszHead3 ) == lpszStr ) return lpszHead3; return NULL; } // // 根据 Callgle 手机短信协议解析收到的短信 // return : ----------------------------------------------------------- // 1 : 成功 // 其他数据 : 发生错误 // -2 : 在本函数处理已经结束,不需要再处理 // 注意: // 要及时删除 *ppStrAry_GroupName_Recver 和 *ppStrAry_SMSSenderID_Recver 指针 // int CMobileControl::ParseSMSRecved ( IN LPCTSTR lpszSMSContent, IN LPCTSTR lpszSenderMobileNO, OUT CStringArray **ppStrAry_GroupName_Recver, // 接收短信者名字或PM帐号,如果是输入控制命令时,这里存放了操作指令和控制命令 OUT CStringArray **ppStrAry_SMSSenderID_Recver, OUT TCHAR *tchSMSContent, int nSMSContentSize, BOOL &bRequireEchoSMS, LPCTSTR lpszSendTime ) { m_csPartString = _T(""); bRequireEchoSMS = FALSE; // 无效的短信内容,所以我也返回一个无效的消息类型 if ( !lpszSMSContent || lstrlen(lpszSMSContent) < 2 ) return -1; int nRet = -1; ENUM_MOBILESMSTYPE eMobileSMSType = ENUM_MOBILESMSTYPE_Invalid; CString csSMSContent = GET_SAFE_STRING ( lpszSMSContent ); CString csSMSContent_Org = csSMSContent; BOOL bMultiSplitSMS = FALSE; // 以三个'?'开头的短信表示该短信是分多次发送过来的,需要将前面的三个'?'去掉 if ( csSMSContent.GetLength() > 3 && csSMSContent.GetAt(0)=='?' && csSMSContent.GetAt(1)=='?' && csSMSContent.GetAt(2)=='?' ) { bMultiSplitSMS = TRUE; while ( !csSMSContent.IsEmpty() && csSMSContent.GetAt(0) == '?' ) csSMSContent.Delete ( 0, 1 ); csSMSContent_Org = csSMSContent; if ( !m_csMultiSplitSMSHead.IsEmpty() && !CheckHeadStr ( csSMSContent, _T("#"), _T("#"), _T("…") ) ) csSMSContent.Insert ( 0, m_csMultiSplitSMSHead ); } else { m_csMultiSplitSMSHead = ""; } // 非普通短信,而是一个控制命令,处理后的控制命令保存在 “tchSMSContent” 中 LPCTSTR pStr = CheckHeadStr ( csSMSContent, _T("%"), _T("%"), _T("") ); if ( pStr ) { m_csPartString = pStr; nRet = HandleSMSCtrlCode ( csSMSContent, ppStrAry_SMSSenderID_Recver, tchSMSContent, nSMSContentSize ); eMobileSMSType = ENUM_MOBILESMSTYPE_CtrlCmd; } // 普通的短信 else { LPCTSTR pSMSContent = csSMSContent.GetBuffer(0); // 是否需要回应 if ( pStr = CheckHeadStr ( pSMSContent, _T("#!"), _T("#!"), _T("…") ) ) { pSMSContent += lstrlen ( pStr ); bRequireEchoSMS = TRUE; } nRet = HandleSMSCommon ( pSMSContent, lpszSenderMobileNO, ppStrAry_GroupName_Recver, ppStrAry_SMSSenderID_Recver, tchSMSContent, nSMSContentSize, eMobileSMSType ); } if ( bMultiSplitSMS ) { CString csMultiSplitSMSHead = csSMSContent.Left ( csSMSContent_Org.GetLength() - (int)lstrlen(tchSMSContent) ); if ( !csMultiSplitSMSHead.IsEmpty () ) { m_csMultiSplitSMSHead = csMultiSplitSMSHead; } } DWORD dwSMSSenderID = 0; if ( ppStrAry_SMSSenderID_Recver && *ppStrAry_SMSSenderID_Recver && (*ppStrAry_SMSSenderID_Recver)->GetSize() > 0 ) { dwSMSSenderID = atoi(CMultiByteString((*ppStrAry_SMSSenderID_Recver)->GetAt ( 0 )).GetBuffer()); } // 将收到的短信保存起来 /* if ( m_pHwMysql_PMMsg ) { m_pHwMysql_PMMsg->SaveSMSToHistoryRecord ( dwSMSSenderID, lpszSenderMobileNO, eMobileSMSType, ENUM_SMSOrientation_Recv, ENUM_BOOL_TRUE, lpszSendTime, csSMSContent_Org ); } */ //u return nRet; } // // 处理普通短信 // int CMobileControl::HandleSMSCommon ( IN LPCTSTR lpszSMSContent, IN LPCTSTR lpszSenderMobileNO, OUT CStringArray **ppStrAry_GroupName_Recver, OUT CStringArray **ppStrAry_SMSSenderID_Recver, OUT TCHAR *tchSMSContent, int nSMSContentSize, ENUM_MOBILESMSTYPE &eMobileSMSType ) { m_csPartString = _T(""); eMobileSMSType = ENUM_MOBILESMSTYPE_Invalid; // 第一个字符是不是“#”或者“#”或者繁体的“#” LPCTSTR pStr = CheckHeadStr ( lpszSMSContent, _T("#"), _T("#"), _T("…") ); if ( pStr ) { m_csPartString = pStr; pStr = CheckHeadStr ( lpszSMSContent+m_csPartString.GetLength(), _T("#"), _T("#"), _T("…") ); // 连续两个“#”表示群发短信(发送给多人) if ( pStr ) { m_csPartString = pStr; eMobileSMSType = ENUM_MOBILESMSTYPE_ClusterAD; return HandleSMSMultiRecver ( lpszSMSContent, lpszSenderMobileNO, ppStrAry_GroupName_Recver, tchSMSContent, nSMSContentSize ); } else { CString csTemp = lpszSMSContent+m_csPartString.GetLength(); csTemp = csTemp.Left ( 4 ); // 寻求帮助 if ( ( csTemp.GetLength() > 0 ) && ( CheckHeadStr ( csTemp, _T("?"), _T("?"), _T("") ) || csTemp.CompareNoCase ( _T("help") ) ==0 ) ) { eMobileSMSType = ENUM_MOBILESMSTYPE_Personal; SendSMS ( ENUM_MOBILESMSTYPE_SysAutoSent, lpszSenderMobileNO, CALLGLE_HELP_INFO1 ); SendSMS ( ENUM_MOBILESMSTYPE_SysAutoSent, lpszSenderMobileNO, CALLGLE_HELP_INFO2 ); return -2; } } } // 个人短信(私聊) eMobileSMSType = ENUM_MOBILESMSTYPE_Personal; return HandleSMSSingleRecver ( lpszSMSContent, lpszSenderMobileNO, ppStrAry_SMSSenderID_Recver, tchSMSContent, nSMSContentSize ); } // // 把处理到只剩下“接收者(群组编号或PM帐号或用户名)”和“短信本身”的短信交给这个函数处理 // BOOL CMobileControl::ParseRecverAndContent ( TCHAR *pHandlePos, OUT CStringArray **ppStrAry_Recver, OUT TCHAR *tchSMSContent, int nSMSContentSize ) { ASSERT ( pHandlePos ); if ( *pHandlePos == _T('\0') ) return FALSE; pHandlePos = strstr_hw ( pHandlePos, m_csPartString ); if ( !pHandlePos ) return FALSE; pHandlePos += m_csPartString.GetLength(); // 跳过 “#” CString csHandleRemain = pHandlePos; CString csSMSContent = csHandleRemain; int nFindPos = csHandleRemain.Find ( m_csPartString, 0 ); if ( nFindPos >= 0 ) { CString csRecver = csHandleRemain.Left ( nFindPos ); csSMSContent = csHandleRemain.Mid ( nFindPos+m_csPartString.GetLength() ); ASSERT ( ppStrAry_Recver ); *ppStrAry_Recver = new CStringArray; if ( !(*ppStrAry_Recver) ) return FALSE; CStringArray StrAry; PartStringAndAddToStrAry ( csRecver.GetBuffer(0), StrAry, GROUP_NAME_ILLEGAL ); StrAry.RemoveAll (); } // 获取短信内容本身 lstrcpyn ( tchSMSContent, csSMSContent, nSMSContentSize ); tchSMSContent[nSMSContentSize-1] = _T('\0'); return TRUE; } // // 处理群发短信 // int CMobileControl::HandleSMSMultiRecver ( IN LPCTSTR lpszSMSContent, IN LPCTSTR lpszSenderMobileNO, OUT CStringArray **ppStrAry_GroupName_Recver, OUT TCHAR *tchSMSContent, int nSMSContentSize ) { ASSERT ( lpszSMSContent && lstrlen(lpszSMSContent) > 0 ); ASSERT ( nSMSContentSize > 0 ); if ( !m_pMobileParameter ) return FALSE; ASSERT_ADDRESS ( tchSMSContent, nSMSContentSize ); TCHAR* pHandlePos = (TCHAR*)lpszSMSContent; int nSMSContentLen = lstrlen(lpszSMSContent); int nRet = -1; // 跳过前面的俩“#”号 pHandlePos += 2*m_csPartString.GetLength(); // 获取接收群组编号 if ( !ParseRecverAndContent ( pHandlePos, ppStrAry_GroupName_Recver, tchSMSContent, nSMSContentSize ) ) return -1; return 1; } // // 处理个人短信 // int CMobileControl::HandleSMSSingleRecver ( IN LPCTSTR lpszSMSContent, IN LPCTSTR lpszSenderMobileNO, OUT CStringArray **ppStrAry_SMSSenderID_Recver, OUT TCHAR *tchSMSContent, int nSMSContentSize ) { ASSERT ( lpszSMSContent && lstrlen(lpszSMSContent) > 0 ); ASSERT_ADDRESS ( tchSMSContent, nSMSContentSize ); ASSERT ( m_pMobileParameter ); // 发送给指定的用户 LPCTSTR pStr = CheckHeadStr ( lpszSMSContent, _T("#"), _T("#"), _T("…") ); if ( pStr ) { m_csPartString = pStr; // 获取接收者PM帐号 ParseRecverAndContent ( (TCHAR*)lpszSMSContent, ppStrAry_SMSSenderID_Recver, tchSMSContent, nSMSContentSize ); } // 无 callgle 短信脚本,发送给短信服务者 if ( !ppStrAry_SMSSenderID_Recver || !(*ppStrAry_SMSSenderID_Recver) || (*ppStrAry_SMSSenderID_Recver)->GetSize() < 1 ) { lstrcpyn ( tchSMSContent, lpszSMSContent, nSMSContentSize ); tchSMSContent [nSMSContentSize-1] = _T('\0'); if ( !(*ppStrAry_SMSSenderID_Recver) ) { (*ppStrAry_SMSSenderID_Recver) = new CStringArray; } if ( *ppStrAry_SMSSenderID_Recver && (*ppStrAry_SMSSenderID_Recver)->GetSize() < 1 ) { //u } } return 1; } // // 处理控制代码的短信 // int CMobileControl::HandleSMSCtrlCode ( IN LPCTSTR lpszSMSContent, OUT CStringArray **ppStrAry_SMSSenderID_Recver, OUT TCHAR *tchSMSContent, int nSMSContentSize ) { ASSERT ( lpszSMSContent && lstrlen(lpszSMSContent) > 0 ); ASSERT_ADDRESS ( tchSMSContent, nSMSContentSize ); LPCTSTR pStart = lpszSMSContent + m_csPartString.GetLength(); if ( pStart[0] == _T('\0') ) return -1; LPCTSTR pEnd = strstr_hw ( pStart, m_csPartString ); if ( !pEnd ) pEnd = pStart + lstrlen(pStart); int nCtrlCodeLen = (int)((ULONGLONG)pEnd - (ULONGLONG)pStart); if ( nCtrlCodeLen < 1 ) return -1; nCtrlCodeLen = MIN ( nCtrlCodeLen, nSMSContentSize ); memcpy ( tchSMSContent, pStart, nCtrlCodeLen ); tchSMSContent[nCtrlCodeLen] = _T('\0'); ASSERT ( ppStrAry_SMSSenderID_Recver ); *ppStrAry_SMSSenderID_Recver = new CStringArray; if ( !(*ppStrAry_SMSSenderID_Recver) ) return -1; if ( PartDigitOrSpecifyCharAndAddToStrAry ( tchSMSContent, **ppStrAry_SMSSenderID_Recver, _T("*#") ) < 2 ) return -1; return 1; } int CMobileControl::HandleCOMRW(int nRet) { if ( ::WaitForSingleObject ( m_hEvt_TerminateSys, 0 ) == WAIT_OBJECT_0 ) return -3; // COM got way if ( nRet < 0 ) { m_eRunState = ENUM_RunState_Init; ChangeMobileStatus ( ENUM_ERROR_TYPE_NoneMobile ); } return CHwMobile::HandleCOMRW ( nRet ); } LRESULT CMobileControl::ChangeMobileStatus( ENUM_ERROR_TYPE eMobileStatus_New ) { ENUM_ERROR_TYPE eMobileStatus_Old = GetMobileStatus(); if ( eMobileStatus_Old == eMobileStatus_New ) return FALSE; // 新状态不是禁用也不是启用时,应该属于手机实际的状态了 if ( eMobileStatus_New != ENUM_ERROR_TYPE_MobileDisable && eMobileStatus_New != ENUM_ERROR_TYPE_MobileEnable ) { m_eMobileStatus_Real = eMobileStatus_New; } // 模块被禁用了,只有收到启用码才处理后面的动作,否则直接返回。 if ( eMobileStatus_Old == ENUM_ERROR_TYPE_MobileDisable && eMobileStatus_New != ENUM_ERROR_TYPE_MobileEnable ) { return FALSE; } // 模块被启用了,应该将真实的状态当作当前的手机状态 if ( eMobileStatus_New == ENUM_ERROR_TYPE_MobileEnable ) { eMobileStatus_New = m_eMobileStatus_Real; } m_CSFor_MobileStatus.Lock (); m_eMobileStatus = eMobileStatus_New; m_CSFor_MobileStatus.Unlock (); LRESULT lRes = TRUE; if ( m_Proc_HandleMobileStatusChange ) { lRes = m_Proc_HandleMobileStatusChange ( eMobileStatus_Old, eMobileStatus_New ); } else { Log ( L_VERBOSE, _T("Mobile status change to [%s]"), g_pErrorTypeDesc[eMobileStatus_New] ); } return lRes; } ENUM_ERROR_TYPE CMobileControl::GetMobileStatus () { ENUM_ERROR_TYPE eMobileStatus; m_CSFor_MobileStatus.Lock (); eMobileStatus = m_eMobileStatus; m_CSFor_MobileStatus.Unlock (); return eMobileStatus; } BOOL CMobileControl::SMSEnable(BOOL bEnable) { // 启用手机短信 if ( bEnable ) { ChangeMobileStatus ( ENUM_ERROR_TYPE_MobileEnable ); m_InitializeInterfaceInterval = INITIALIZE_INTERFACE_INTERVAL; } // 禁用手机短信 else { Log ( L_NORMAL | L_OUT_UI, _T("Disable ") ); ChangeMobileStatus ( ENUM_ERROR_TYPE_MobileDisable ); } return TRUE; } BOOL CMobileControl::GetLocalCodeHead ( CString &csLocalCountryCode, CString &csLocalAreaCode ) { if ( m_pMobileParameter ) { csLocalCountryCode = m_pMobileParameter->szLocalCountryCode; csLocalAreaCode = m_pMobileParameter->szLocalAreaCode; csLocalCountryCode.Replace ( _T("+"), _T("00") ); csLocalAreaCode.Replace ( _T("+"), _T("00") ); if ( !csLocalCountryCode.IsEmpty() && !csLocalAreaCode.IsEmpty() ) return TRUE; } return FALSE; } // // 输入的号码是否为手机号码,如果是,那返回他的字头出现在数组 m_Ary_MobileNOHead 中的位置,如果 // 不是就返回-1;不管国内号码还是国外号码,本函数都会处理它 // // return : ---------------------------------------------------------------------------------------------- // >=0 - 是手机号码,字头在数组中的位置 // -1 - 不是手机号码 // int CMobileControl::IsMobileNO ( LPCTSTR lpszPhoneNO, OUT t_MobileNOHead *pMobileNOHead/*=NULL*/, OUT CString *pShortMobileNO/*=NULL*/ ) { if ( !lpszPhoneNO ) return -1; CString csPhoneNO = lpszPhoneNO; csPhoneNO.Replace ( _T("+"), _T("00") ); if ( csPhoneNO.GetLength() < 1 ) return -1; CString csLocalCountryCode, csLocalAreaCode; if ( !GetLocalCodeHead ( csLocalCountryCode, csLocalAreaCode ) ) return -1; // 分析国家代码和区号 CString csCountryCode, csAreaCode; BOOL bHaveCountryCode = ( csPhoneNO.Find ( _T("00"), 0 ) == 0 ); int nRetLen = FindFromMobileNOHeadAry ( csPhoneNO, csCountryCode, csAreaCode ); CString csShortMobileNO; if ( nRetLen > 0 ) csShortMobileNO = csPhoneNO.Mid ( nRetLen ); else csShortMobileNO = csPhoneNO; int nRet = -1; for ( int i=0; i 0 && csCountryCode == MobileNOHead.szCountryCode ) || // 电话号码中没有国家代码,且 MobileNOHead 中也没有国家代码或者就是本国的国家代码 ( !bHaveCountryCode && csCountryCode.GetLength() == 0 && ( lstrlen(MobileNOHead.szCountryCode) == 0 || csLocalCountryCode == MobileNOHead.szCountryCode ) ) ) && // 区号 ( // 电话号码中有区号,且和 MobileNOHead 中的区号相等 ( csAreaCode.GetLength() > 0 && ( csAreaCode == MobileNOHead.szAreaCode ) ) || // 电话号码中没有区号,且 MobileNOHead 中也没有区号或者就是本地的区号 ( csAreaCode.GetLength() == 0 && ( lstrlen(MobileNOHead.szAreaCode) == 0 || csLocalAreaCode == MobileNOHead.szAreaCode ) ) ) && // 手机字头 ( CompareNOHead ( csShortMobileNO, MobileNOHead.szMobileNoHead, (lstrlen(MobileNOHead.szAreaCode)==0 || SWITCH_IS_FLAG ( SMS_MobileNO_Format_AreaCode, MobileNOHead.dwMobileNOFormat )), TRUE ) > 0 ) ) { if ( pMobileNOHead ) memcpy ( pMobileNOHead, &MobileNOHead, sizeof(t_MobileNOHead) ); nRet = i; StandardShortMobileNO ( csShortMobileNO, MobileNOHead.szMobileNoHead ); break; } } if ( pShortMobileNO ) *pShortMobileNO = csShortMobileNO; return nRet; } // // 从 m_Ary_MobileNOHead 字头列表中找,手机号码 lpszPhoneNO 的国家代码或区号 // return : ---------------------------------------------------------------------------------- // > 0 - 号码头(国家代码+区号)的长度 // <= 0 - 没有号码头 // int CMobileControl::FindFromMobileNOHeadAry ( LPCTSTR lpszPhoneNO, CString &csCountryCode, CString &csAreaCode ) { if ( !lpszPhoneNO ) return -1; int nMobileNOLen = (int)lstrlen(lpszPhoneNO); if ( nMobileNOLen < 1 ) return -1; int nCountryCodeLen = 0, nAreaCodeLen = 0, nPrepositiveNOLen = 0; int nCountryCodeLen_Ret = 0, nAreaCodeLen_Ret = 0, nPrepositiveNOLen_Ret = 0; for ( int i=0; i 0 && nMobileNOLen > nPrepositiveNOLen_Ret && strstr_hw(p,MobileNOHead.szPrepositiveNO) == p ) { nPrepositiveNOLen = nPrepositiveNOLen_Ret; p += nPrepositiveNOLen; } // 找国家代码 if ( lstrlen(MobileNOHead.szCountryCode) > 0 ) { nCountryCodeLen_Ret = CompareNOHead ( p, MobileNOHead.szCountryCode, TRUE, TRUE ); if ( nCountryCodeLen_Ret > 0 && lstrlen(p+nCountryCodeLen_Ret)>=MIN_MOBILENO_LENGTH ) { nCountryCodeLen = nCountryCodeLen_Ret; csCountryCode = MobileNOHead.szCountryCode; p += nCountryCodeLen_Ret; } } // 找区号 if ( lstrlen(MobileNOHead.szAreaCode) > 0 ) { nAreaCodeLen_Ret = CompareNOHead ( p, MobileNOHead.szAreaCode, nCountryCodeLen_Ret>0, nCountryCodeLen_Ret>0 ); if ( nAreaCodeLen_Ret > 0 && lstrlen(p+nAreaCodeLen_Ret)>=MIN_MOBILENO_LENGTH ) { nAreaCodeLen = nAreaCodeLen_Ret; nCountryCodeLen = nCountryCodeLen_Ret; csCountryCode = MobileNOHead.szCountryCode; csAreaCode = MobileNOHead.szAreaCode; p += nAreaCodeLen_Ret; break; } } } return ( nPrepositiveNOLen + nCountryCodeLen + nAreaCodeLen ); } // // 比较俩号码,是否 lpszPhoneNO 是以 lpszPhoneNOHead 做字头的号码,并自动跳过号码前的“0” // return : ----------------------------------------------------------------------------------------- // > 0 - TRUE, lpszPhoneNO 中多少个字符为字头 // = 0 - FALSE // int CMobileControl::CompareNOHead(LPCTSTR lpszPhoneNO, LPCTSTR lpszPhoneNOHead, BOOL bIgnoreHeadZero_PhoneNO, BOOL bIgnoreHeadZero_PhoneNOHead) { if ( !lpszPhoneNO || lstrlen(lpszPhoneNO) < 1 ) return 0; if ( !lpszPhoneNOHead || lstrlen(lpszPhoneNOHead) < 1 ) return 0; if ( strstr_hw ( lpszPhoneNO, lpszPhoneNOHead ) == lpszPhoneNO ) return (int)lstrlen(lpszPhoneNOHead); // 台湾的手机号码以“0”开头,来电显示有时又收不到这个“0”,所有手机字头跳过这个“0”再来比对 // 大陆手机是以“13”开头,但长途漫游之后的来电显示会变成“013”,所以应该跳过来电显示的第一个“0”再比对 CString csPhoneNO = lpszPhoneNO; CString csPhoneNOHead = lpszPhoneNOHead; int nPhoneNODeleZeroNum = 0; if ( bIgnoreHeadZero_PhoneNO ) { while ( csPhoneNO.GetLength() > 0 && csPhoneNO.GetAt (0) == '0' ) { csPhoneNO.Delete ( 0 ); nPhoneNODeleZeroNum ++; } } if ( bIgnoreHeadZero_PhoneNOHead ) { while ( csPhoneNOHead.GetLength() > 0 && csPhoneNOHead.GetAt (0) == '0' ) csPhoneNOHead.Delete ( 0 ); } if ( csPhoneNO.Find ( csPhoneNOHead, 0 ) == 0 ) return ( csPhoneNOHead.GetLength() + nPhoneNODeleZeroNum ); return 0; } // // 配置 国家代码、手机字头等参数 // void CMobileControl::ConfigParameter ( t_Ary_MobileNOHead *pAry_MobileNOHead ) { if ( pAry_MobileNOHead ) { m_Ary_MobileNOHead.Append ( *pAry_MobileNOHead ); } } // // 获取精简的手机号码 ( 不带任何国家代码的手机号码 ) // CString CMobileControl::SimplifyMobileNO ( LPCTSTR lpszMobileNO ) { CString csMobileNO = GET_SAFE_STRING ( lpszMobileNO ); CString csSimplifyMobileNO; if ( StandardMobileNO ( csMobileNO, NULL, &csSimplifyMobileNO ) != ENUM_ERROR_TYPE_SUCCESS ) csSimplifyMobileNO = GET_SAFE_STRING ( lpszMobileNO ); return csSimplifyMobileNO; } // // 标准化干净的手机号码 // void CMobileControl::StandardShortMobileNO ( IN OUT CString &csShortMobileNO, IN LPCTSTR lpszMobileNOHead ) { CString csMobileNOHead = GET_SAFE_STRING(lpszMobileNOHead); // 手机字头从号码的第二位开始出现,且号码是以‘0’开头,那么这个多余的‘0’应该去掉 if ( csMobileNOHead.GetLength() > 0 && csShortMobileNO.Find ( csMobileNOHead, 0 ) == 1 && csShortMobileNO.GetAt(0) == '0' ) { csShortMobileNO.Delete ( 0 ); } // 有些国家的手机字头以‘0’开头(如:台湾是“09”开头),有时来电显示会丢掉前面的‘0’,所以应该把丢掉的‘0’补上 if ( csMobileNOHead.GetLength() >= 2 && csMobileNOHead.GetAt(0) == '0' && csShortMobileNO.GetAt(0) != '0' && csShortMobileNO.GetAt(0) == csMobileNOHead.GetAt(1) ) { csShortMobileNO.Insert ( 0, '0' ); } } // // 标准化手机号码,国外的号码只处理字头,国内的号码会处理国家代码区号等,而且也会处理前置号码 // ENUM_ERROR_TYPE CMobileControl::StandardMobileNO ( CString &csMobileNO, BOOL *pbInternationalMobileNO/*=NULL*/, CString *pSimplifyMobileNO/*=NULL*/ ) { if ( pbInternationalMobileNO ) *pbInternationalMobileNO = FALSE; if ( pSimplifyMobileNO ) *pSimplifyMobileNO = ""; CString csMobileNORes, csShortPhoneNO, csLocalCountryCode, csLocalAreaCode, csPrepositiveNO, csMobileNOHead; t_MobileNOHead MobileNOHead = {0}; // 取得合法的电话号码数字 CString csHandleMobileNO = csMobileNO; GetRightPhoneNOString ( csHandleMobileNO.GetBuffer(0) ); csHandleMobileNO.ReleaseBuffer (); if ( csHandleMobileNO.GetLength() < 1 ) return ENUM_ERROR_TYPE_INVALID_DATA; csHandleMobileNO.Replace ( _T("+"), _T("00") ); if ( !GetLocalCodeHead ( csLocalCountryCode, csLocalAreaCode ) ) return ENUM_ERROR_TYPE_ConfigNotRight; // 手机号码为国外的号码,只需对号码进行简单地处理,且不对手机字头进行判断 if ( csHandleMobileNO.GetAt(0)=='0' && csHandleMobileNO.GetAt(1)=='0' && csHandleMobileNO.Find ( csLocalCountryCode, 0 ) != 0 ) { if ( pbInternationalMobileNO ) *pbInternationalMobileNO = TRUE; if ( pSimplifyMobileNO ) *pSimplifyMobileNO = csHandleMobileNO; StandardMobileNOHead ( csMobileNO ); return ENUM_ERROR_TYPE_SUCCESS; } // 根据字头来判断该号码是否为手机号码 if ( IsMobileNO ( csHandleMobileNO, &MobileNOHead, &csShortPhoneNO ) < 0 ) return ENUM_ERROR_TYPE_IsNotMobileNO; csMobileNOHead = MobileNOHead.szMobileNoHead; StandardShortMobileNO ( csShortPhoneNO, csMobileNOHead ); csPrepositiveNO = MobileNOHead.szPrepositiveNO; // 按照手机号码格式来组建一个标准的手机号码 CString csCountryCode = MobileNOHead.szCountryCode; CString csAreaCode = MobileNOHead.szAreaCode; if ( csPrepositiveNO.GetLength() > 0 ) { csMobileNORes += csPrepositiveNO; // 前置号码 } if ( MobileNOHead.dwMobileNOFormat & SMS_MobileNO_Format_CountryCode ) { if ( csCountryCode.GetLength() < 1 ) csCountryCode = csLocalCountryCode; StandardMobileNOHead ( csCountryCode ); csMobileNORes += csCountryCode; // 添加国家代码 while ( csAreaCode.GetLength() > 0 && csAreaCode.GetAt(0) == '0' ) csAreaCode.Delete ( 0 ); // 由于要添加国家代码,所以区号前面的“0”应该去掉 if ( pbInternationalMobileNO ) *pbInternationalMobileNO = TRUE; if ( pSimplifyMobileNO && csLocalCountryCode != MobileNOHead.szCountryCode ) *pSimplifyMobileNO += MobileNOHead.szCountryCode; } if ( MobileNOHead.dwMobileNOFormat & SMS_MobileNO_Format_AreaCode ) { if ( csAreaCode.GetLength() < 1 ) { csAreaCode = csLocalAreaCode; if ( csMobileNORes.GetLength() > 0 ) { while ( csAreaCode.GetLength() > 0 && csAreaCode.GetAt(0) == '0' ) csAreaCode.Delete ( 0 ); } } csMobileNORes += csAreaCode; // 添加区号 if ( pSimplifyMobileNO && (pSimplifyMobileNO->GetLength() > 0 || csLocalAreaCode != MobileNOHead.szAreaCode) ) *pSimplifyMobileNO += MobileNOHead.szAreaCode; } CString csNoneZeroPhoneNO = csShortPhoneNO; while ( csNoneZeroPhoneNO.GetLength() > 0 && csNoneZeroPhoneNO.GetAt(0) == '0' ) csNoneZeroPhoneNO.Delete ( 0 ); if ( csMobileNORes.GetLength() > 0 ) csMobileNORes += csNoneZeroPhoneNO; else csMobileNORes = csShortPhoneNO; if ( pSimplifyMobileNO ) { if ( pSimplifyMobileNO->GetLength() > 0 ) *pSimplifyMobileNO += csNoneZeroPhoneNO; else *pSimplifyMobileNO = csShortPhoneNO; } TRACE ( _T("标准化手机号码 ( %s ) 为 ( %s )\n"), csMobileNO, csMobileNORes ); csMobileNO = csMobileNORes; return ENUM_ERROR_TYPE_SUCCESS; } // // 标准化手机号码头,把 '+'、"00" 去掉 // ENUM_ERROR_TYPE CMobileControl::StandardMobileNOHead ( CString &csMobileNOHead ) { if ( csMobileNOHead.GetLength() < 3 ) return ENUM_ERROR_TYPE_IsNotMobileNO; csMobileNOHead.Remove ( _T('+') ); if ( csMobileNOHead.Find ( _T("00"), 0 ) == 0 ) { csMobileNOHead.Delete ( 0, 2 ); } if ( csMobileNOHead.GetLength() < 1 ) return ENUM_ERROR_TYPE_IsNotMobileNO; return ENUM_ERROR_TYPE_SUCCESS; } void CMobileControl::GetRegisterPhoneBookInfo ( CStringArray &StrAry_PhoneNO, CStringArray &StrAry_Name ) { StrAry_PhoneNO.Add ( _T("111") ); StrAry_Name.Add ( _T("HOWASZ") ); StrAry_PhoneNO.Add ( _T("222") ); StrAry_Name.Add ( _T("HOWAFAX") ); StrAry_PhoneNO.Add ( _T("333") ); StrAry_Name.Add ( _T("CHRYS") ); } // // 短信模块是否已注册过了,查看本机电话本里是否含有以下几条电话纪录: // BOOL CMobileControl::GSMModuleIsRegistered() { t_Ary_PhoneBook Ary_PhoneBook; CString csPhoneBook = _T("ME"); Ary_PhoneBook.SetSize ( 0, 10*sizeof(t_PhoneBook) ); if ( !gsmReadPhoneBook ( csPhoneBook, &Ary_PhoneBook ) ) { Log ( L_WARNING, _T("Read phone book [%s] failed"), csPhoneBook ); return FALSE; } CStringArray StrAry_PhoneNO, StrAry_Name; GetRegisterPhoneBookInfo ( StrAry_PhoneNO, StrAry_Name ); CStringArray StrAry_PhoneNO_ME, StrAry_Name_ME; ASSERT ( StrAry_PhoneNO.GetSize() == StrAry_Name.GetSize() ); for ( int i=0; i 1 && csPhoneNO.GetLength () > 1 ); if ( !InsertPhoneBook ( csName, csPhoneNO, NULL ) ) { return 0; } } return 1; } // // 注册短信模块,给本机电话本里添加以下几条电话纪录: // return : ---------------------------------------------------- // 0 - 失败 // 1 - 成功 // 2 - 还没注册 // int CMobileControl::UnregisterGSMModule() { CString csPhoneBook = _T("ME"); if ( !gsmSelectPhoneBook ( csPhoneBook ) ) return 0; CStringArray StrAry_PhoneNO, StrAry_Name; GetRegisterPhoneBookInfo ( StrAry_PhoneNO, StrAry_Name ); ASSERT ( StrAry_PhoneNO.GetSize() == StrAry_Name.GetSize() ); for ( int i=1; i<=3*StrAry_PhoneNO.GetSize(); i++ ) { if ( !gsmDeleteOneRecordFromPhoneBook ( i ) ) { return 0; } } return 1; } #endif