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

📄 hwmobile.cpp

📁 基于vc++6.0的收发手机短信、读写手机电话本的平台
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		csSCTS.Delete ( 10, 1 );
	csSCTS += _T("00");
	strncpy ( szSCTS, CMultiByteString(csSCTS).GetBuffer(), nSize );
	return szSCTS;
}

BOOL CHwMobile::gsmDeleteSMS ( int nIndex )
{
	char szCmd[1024] = {0};
	hwSnprintfA ( szCmd, sizeof(szCmd)/sizeof(char), "AT+CMGD=%d\r", nIndex );
	if ( Write ( szCmd ) < 1 ) return FALSE;

	if ( ReadResponse ( "OK\r\n" ) )
		return TRUE;
	return FALSE;
}

//
// 选择电话本
//
BOOL CHwMobile::gsmSelectPhoneBook ( LPCTSTR lpszPhoneBookName )
{
	ASSERT ( lpszPhoneBookName && lstrlen(lpszPhoneBookName) > 0 );
	if ( m_csCurPhoneBookName == lpszPhoneBookName )
		return TRUE;
	HwDbgLog ( L_DEBUG, _T("选择电话本 [%s]"), lpszPhoneBookName );
	// 两次选择电话本的时间间隔必须大于 SELECT_PHONEBOOK_INTVERVAL 秒
	static DWORD dwStartTime = GetTickCount();
	while ( !TimeIntervalArrived ( dwStartTime, SELECT_PHONEBOOK_INTVERVAL ) )
		Sleep ( 100 );

	// 选择电话本
	char szCmd[1024] = {0};
	sprintf ( szCmd, "AT+CPBS=\"%s\"\r", CMultiByteString(lpszPhoneBookName).GetBuffer() );
	if ( Write ( szCmd ) < 1 )
		return FALSE;
	if ( !ReadResponse ( "OK\r\n" ) )
		return FALSE;

	m_csCurPhoneBookName = lpszPhoneBookName;
	return TRUE;
}

//
// 读一个电话本
// “FD” 固定拨号电话本
// “SM” SIM 卡电话本
// “ON” 本机电话号码列表
// “ME” 手机电话本
// “LD” 最近已拨电话(SIM)
// “MC” 最近来电未接电话本
// “RC” 最近来电已接电话本
// “DC” 最近拨号电话本
//
BOOL CHwMobile::gsmReadPhoneBook ( LPCTSTR lpszPhoneBookName, t_Ary_PhoneBook *pAry_PhoneBook)
{
	if ( HANDLE_IS_VALID(m_hEvt_IsBusy) )
		::SetEvent ( m_hEvt_IsBusy );
	BOOL bRet = FALSE;
	int nMaxRecNum = 0;
	char szCmd[1024] = {0};
	int nStoreStartPos = 0;
	int nStoreEndPos = 0;
	int nMaxPhoneNOSize = 0; 
	int nMaxInfoSize = 0;
	int nMaxRecSize = 0;
	ASSERT ( pAry_PhoneBook );
	if ( !gsmSelectPhoneBook ( lpszPhoneBookName ) )
		goto finished;

	if ( !gmsGetPhoneBookInfo (
		nStoreStartPos,
		nStoreEndPos,
		nMaxPhoneNOSize, 
		nMaxInfoSize,
		nMaxRecSize ) )
		goto finished;

	HwDbgLog ( L_DEBUG, _T(" [%s].nStoreEndPos = %d"), lpszPhoneBookName, nStoreEndPos );
	// 发送“读”当前选择电话本所有电话纪录的 AT 指令
	hwSnprintfA ( szCmd, sizeof(szCmd)/sizeof(char), "AT+CPBR=%d,%d\r", nStoreStartPos, nStoreEndPos );
	if ( Write ( szCmd ) < 1 ) goto finished;

	// 取回所有读到的电话纪录
	nMaxRecNum = nStoreEndPos - nStoreStartPos + 1;
	gsmGetAllPhoneBookRec ( nMaxRecSize, nMaxRecNum, lpszPhoneBookName, pAry_PhoneBook );

	bRet = TRUE;
finished:
	if ( HANDLE_IS_VALID(m_hEvt_IsBusy) )
		::ResetEvent ( m_hEvt_IsBusy );
	return bRet;
}

//
// 从电话本中删除一条纪录
//
BOOL CHwMobile::gsmDeleteOneRecordFromPhoneBook ( int nIndex )
{
	if ( HANDLE_IS_VALID(m_hEvt_IsBusy) )
		::SetEvent ( m_hEvt_IsBusy );
	BOOL bRet = FALSE;
	char szCmd[1024] = {0};
	sprintf ( szCmd, "AT+CPBW=%d\r", nIndex );
	if ( Write ( szCmd ) < 1 )
		goto finished;
	if ( !ReadResponse ( "OK\r\n" ) )
		goto finished;

	bRet = TRUE;
finished:
	if ( HANDLE_IS_VALID(m_hEvt_IsBusy) )
		::ResetEvent ( m_hEvt_IsBusy );
	return bRet;
}

//
// 获取电话本的基本信息
//
BOOL CHwMobile::gmsGetPhoneBookInfo (
		int &nStoreStartPos,
		int &nStoreEndPos,
		int &nMaxPhoneNOSize, 
		int &nMaxInfoSize,
		int &nMaxRecSize
	)
{
	if ( Write ( "AT+CPBR=?\r" ) < 1 )
		return FALSE;
	if ( !WaitForDataToRead ( 10, WAIT_GSM_DATA_TIME_SLOW ) )
		return FALSE;

	char szRead[MAX_COM_BUFSIZE] = {0};
	int nReadLen = Read ( szRead, sizeof(szRead) );
	char *pStr = strstr ( szRead, "+CPBR: (" );
	if ( !pStr ) return FALSE;
	pStr += 8;
	if ( pStr - szRead >= nReadLen )
		return FALSE;

	sscanf ( pStr, "%d", &nStoreStartPos );		// 电话本起始位置

	pStr = strstr ( pStr, "-" );
	if ( !pStr ) return FALSE;
	pStr += 1;
	if ( pStr - szRead >= nReadLen )
		return FALSE;
	sscanf ( pStr, "%d", &nStoreEndPos );		// 电话本结束位置

	pStr = strstr ( pStr, ")," );
	if ( !pStr ) return FALSE;
	pStr += 2;
	if ( pStr - szRead >= nReadLen )
		return FALSE;
	sscanf ( pStr, "%d", &nMaxPhoneNOSize );	// 电话号码最大长度

	pStr = strstr ( pStr, "," );
	if ( !pStr ) return FALSE;
	pStr += 1;
	if ( pStr - szRead >= nReadLen )
		return FALSE;
	sscanf ( pStr, "%d", &nMaxInfoSize );		// 相关信息最大长度

	nMaxRecSize = nMaxPhoneNOSize +				// 一条纪录的最大长度
		nMaxInfoSize + 30;
	return TRUE;
}

//
// 获取所有电话本纪录
//
BOOL CHwMobile::gsmGetAllPhoneBookRec ( int nMaxRecSize, int nMaxRecNum, LPCTSTR lpszPhoneBookName, OUT t_Ary_PhoneBook *pAry_PhoneBook )
{
	ASSERT ( pAry_PhoneBook );
	// 读所有电话本纪录,结果存入 pAry_PhoneBook 数组中
	if ( !WaitForDataToRead ( 10, WAIT_GSM_DATA_TIME_SLOW ) )
		return FALSE;
	// 要一次全部读入到内存来,否则可能会漏掉一些纪录,为什么会这样我也不知道。
	const int nDataBufferSize = nMaxRecSize * ( nMaxRecNum + 5 );
	char *pPhoneBookData = new char[nDataBufferSize+1];
	if ( !pPhoneBookData )
	{
		::AfxThrowMemoryException();
		return FALSE;
	}
	memset ( pPhoneBookData, 0, nDataBufferSize+1 );
	int nRet = Read ( pPhoneBookData, nDataBufferSize );
	if ( nRet > 0 )
	{
		char szRemainData[MAX_COM_BUFSIZE+1] = {0};
		int nRemainBytes = gsmDecodePhoneBook ( lpszPhoneBookName, pPhoneBookData,
			pAry_PhoneBook, szRemainData, MAX_COM_BUFSIZE );
		if ( nRemainBytes > 0 )
		{
			memcpy ( pPhoneBookData, szRemainData, nRemainBytes );
			pPhoneBookData[nRemainBytes] = '\0';
		}
	}
	delete[] pPhoneBookData;

	return TRUE;
}

//
// 解码所有电话纪录, 返回处理完后剩余的字节数
//
int CHwMobile::gsmDecodePhoneBook (
		LPCTSTR lpszPhoneBookName,
		char *szPhoneBookRec,
		OUT t_Ary_PhoneBook *pAry_PhoneBook,
		OUT char *szRemainData,					// 处理后剩下的数据放到这里
		const int nRemainSize
	)
{
	ASSERT ( szPhoneBookRec );
	CStringArray StrAry;
	PartStringAndAddToStrAry ( GetCompatibleString(szPhoneBookRec,FALSE), StrAry, _T('\r') );
	int nRemainCount = 0;
	for ( int i=0; i<StrAry.GetSize(); i++ )
	{
		CString csTemp = StrAry.GetAt ( i );
		CMultiByteString MultiByteString_Temp(csTemp);
		t_PhoneBook PhoneBook;
		memset ( &PhoneBook, 0, sizeof(t_PhoneBook) );
		if ( gsmDecodeOnePhoneBook ( MultiByteString_Temp.GetBuffer(), PhoneBook ) )
		{
			lstrcpyn ( PhoneBook.szPhoneBookName, lpszPhoneBookName, COUNT(PhoneBook.szPhoneBookName) );
			pAry_PhoneBook->Add ( PhoneBook );
//			HwDbgLog ( L_DEBUG, _T("得到电话本纪录如下:\r\nNO.%d - [%s] - %s - %s"),
//				PhoneBook.nIndex, PhoneBook.szPhoneBookName, PhoneBook.szName, PhoneBook.szPhoneNO );
		}
		else
		{
			int nLen = MIN ( MultiByteString_Temp.GetLength(), nRemainSize-nRemainCount );
			if ( nLen < 0 ) nLen = 0;
			memcpy ( szRemainData, MultiByteString_Temp.GetBuffer(), nLen );
			nRemainCount += nLen;
		}
	}

	return nRemainCount;
}

//
// 解码一条电话纪录
//
BOOL CHwMobile::gsmDecodeOnePhoneBook ( char *szPhoneBookRec, OUT t_PhoneBook &PhoneBook )
{
	ASSERT ( szPhoneBookRec );
	char *pStr = strstr ( szPhoneBookRec, "+CPBR: " );
	if ( !pStr ) return FALSE;
	pStr += 7;
	CString csTemp;
	CStringArray StrAry;
	PartStringAndAddToStrAry ( GetCompatibleString(pStr,FALSE), StrAry, _T(',') );
	if ( StrAry.GetSize() < 4 ) return FALSE;
	
	csTemp = StrAry.GetAt(0);			// 序号
	PhoneBook.nIndex = atoi ( CMultiByteString(csTemp).GetBuffer() );

	csTemp = StrAry.GetAt(1);			// 电话号码
	csTemp.TrimLeft ( _T("\"") ); csTemp.TrimRight ( _T("\"") );
	lstrcpyn ( PhoneBook.szPhoneNO, csTemp, COUNT(PhoneBook.szPhoneNO) );

	csTemp = StrAry.GetAt(2);			// 类型

	csTemp = StrAry.GetAt(3);			// 姓名
	csTemp.TrimLeft ( _T("\"") ); csTemp.TrimRight ( _T("\"") );
	int nPos = csTemp.Find ( _T('\"'), 0 );
	if ( nPos >= 0 ) csTemp = csTemp.Left ( nPos );
	char szName[1024] = {0};
	CMultiByteString ( csTemp, STRING_IS_SOFTCODE, szName, sizeof(szName) );

	// UCS2解码
	char szTempBuf[4096] = {0};
	int nRet = gsmString2Bytes ( szName, (BYTE*)szTempBuf, (int)strlen(szName), COUNT(szTempBuf) );	// 格式转换
	gsmDecodeUcs2 ( (BYTE*)szTempBuf, (char*)PhoneBook.szName, nRet, sizeof(PhoneBook.szName) );		// 转换到TP-DU
	CString csName = GetCompatibleString ( PhoneBook.szName, FALSE );
	lstrcpyn ( PhoneBook.szName, csName, COUNT(PhoneBook.szName) );
	return TRUE;
}

//
// 编码一条电话纪录
// return : 编码后的字节长度
//
int CHwMobile::gsmPhoneBookEncode (
		OUT char *szPhoneBookRec,
		int nPhoneBookRecSize,
		IN LPCTSTR lpszType,
		IN t_PhoneBook &PhoneBook
	)
{
	ASSERT_ADDRESS ( szPhoneBookRec, nPhoneBookRecSize );
	ASSERT ( lpszType );
	memset ( szPhoneBookRec, 0, nPhoneBookRecSize );

	// UCS2编码
	char szUCS2Name[1024] = {0}, szStrName[1024] = {0};
	CMultiByteString MultiByteString_Name(PhoneBook.szName);
	int nRet = gsmEncodeUcs2 ( MultiByteString_Name.GetBuffer(), (BYTE*)szUCS2Name, MultiByteString_Name.GetLength(), sizeof(szUCS2Name) );
	gsmBytes2String ( (BYTE*)szUCS2Name, szStrName, nRet, sizeof(szStrName) );

	int nCount = 0;
	// 写电话本,向当前的电话本存储区某一位置处写入记录
	nCount += hwSnprintfA ( szPhoneBookRec+nCount, (nPhoneBookRecSize-nCount)/sizeof(char), "AT+CPBW=,\"%s\",%s,\"%s\"\r",
		CMultiByteString(PhoneBook.szPhoneNO).GetBuffer(), CMultiByteString(lpszType).GetBuffer(), szStrName );

	return nCount;
}

//
// 插入一条电话本纪录
//
BOOL CHwMobile::InsertPhoneBook(LPCTSTR lpszName, LPCTSTR lpszPhoneNO, LPCTSTR lpszPhoneBookName)
{
	if ( !lpszName || lstrlen(lpszName) < 1 ) return FALSE;
	if ( !lpszPhoneNO || lstrlen(lpszPhoneNO) < 1 ) return FALSE;

	BOOL bRet = FALSE;
	char szCmd[1024] = {0};
	t_PhoneBook PhoneBook = {0};
	char *pStr = NULL;
	int nRet = 0;
	char szReadBuf[MAX_COM_BUFSIZE+1] = {0};
	memset ( &PhoneBook, 0, sizeof(t_PhoneBook) );
	CString csTypeDesc;
	if ( HANDLE_IS_VALID(m_hEvt_IsBusy) )
		::SetEvent ( m_hEvt_IsBusy );
	if ( lpszPhoneBookName && lstrlen(lpszPhoneBookName) > 0 )
	{
		if ( !gsmSelectPhoneBook ( lpszPhoneBookName ) )
			goto finished;
	}

	// 获取电话纪录类型
	if ( Write ( "AT+CPBW=?\r" ) < 1 ) goto finished;
	if ( !WaitForDataToRead ( 10, WAIT_GSM_DATA_TIME_SLOW ) )
		goto finished;

	nRet = Read ( szReadBuf, MAX_COM_BUFSIZE );
	if ( nRet < 10 ) goto finished;

	pStr = strstr ( szReadBuf, "+CPBW: (" );
	if ( !pStr ) goto finished;
	pStr += 8;
	if ( (pStr = strstr ( pStr, "(" )) == NULL )
		goto finished;
	pStr += 1;
	
	for ( ; *pStr != '\0' && isdigit(*pStr); pStr++ )
	{
		if ( pStr-szReadBuf >= MAX_COM_BUFSIZE )
			break;
		csTypeDesc += *pStr;
	}

	lstrcpyn ( PhoneBook.szName, lpszName, COUNT(PhoneBook.szName) );
	lstrcpyn ( PhoneBook.szPhoneNO, lpszPhoneNO, COUNT(PhoneBook.szPhoneNO) );
	lstrcpyn ( PhoneBook.szPhoneBookName, lpszPhoneBookName, COUNT(PhoneBook.szPhoneBookName) );

	// 产生插入命令,并将电话纪录插入
	nRet = gsmPhoneBookEncode ( szCmd, sizeof(szCmd), csTypeDesc, PhoneBook );
	if ( Write ( szCmd ) < 1 ) goto finished;
	if ( !ReadResponse ( "OK", FALSE ) ) goto finished;
	bRet = TRUE;

finished:
	if ( HANDLE_IS_VALID(m_hEvt_IsBusy) )
		::ResetEvent ( m_hEvt_IsBusy );
	HwDbgLog ( L_DEBUG, _T("Insert PhoneNO [%s] %s"), lpszPhoneNO, bRet?_T("successfully"):_T("failed") );
	return bRet;
}

void CHwMobile::SMSBeep(BOOL bRecv)
{
	if ( !m_bSoundPrompt ) return;
	DWORD dwFreq_Start = 1000, dwFreq_Interval=800;
	DWORD dwDuration = 100;
	for ( int i=0; i<5; i++ )
	{
		Beep ( dwFreq_Start+dwFreq_Interval*( bRecv?(5-i):i ), dwDuration );
	}
}

//
// 检测设备是否存在,通过发送命令和读取回应的办法来实现
//
BOOL CHwMobile::QueryDeviceExist()
{
	for ( int i=0; ; i++ )
	{
		if ( HANDLE_IS_VALID(m_hEvt_IsBusy) &&
			::WaitForSingleObject(m_hEvt_IsBusy,0)==WAIT_OBJECT_0 )
			return TRUE;
		if ( QueryExistByRWCmd () )
			return TRUE;
		if ( i<MAX_RWERROR_TIMES )
			::Sleep ( 10 );
		else
			break;
	}

	HandleCOMRW ( -2 );
	return FALSE;
}

//
// 读写命令来检测设备的存在
//
BOOL CHwMobile::QueryExistByRWCmd()
{
	if ( Write("AT\r" ) > 0 &&
		ReadResponse ( "OK" ) )
	{
		return TRUE;
	}

	return FALSE;
}

//
// 恢复短信通知方式: 
//
void CHwMobile::RestoreRecvSMSNotifyMode()
{
	if ( m_nInitOK && m_handleCOM && m_handleCOM != INVALID_HANDLE_VALUE )
	{
		Write("AT+CNMI=0,0\r" );
	}
}

void CHwMobile::ShowGSMModuleInfo()
{
	// 获取手机信息
	CString csMobileInfo;
	for ( int i=0; i<3; i++ )
	{
		if ( DemandMobileInfo ( "AT+CGMI\r", csMobileInfo ) )
			break;
		Sleep ( 1000 );
	}
	Log ( L_NORMAL | L_OUT_UI, _T("SMS Module Brand : [ %s ]"),
		#ifdef _DEBUG
			csMobileInfo
		#else
			COMPANY_PRINCIPAL_NAME
		#endif
		);

	for ( i=0; i<3; i++ )
	{
		if ( DemandMobileInfo ( "AT+CGMM\r", csMobileInfo ) )
			break;
		Sleep ( 1000 );
	}
	
	Log ( L_NORMAL | L_OUT_UI, _T("SMS Module Model : [ %s ]"), 
		#ifdef _DEBUG
			csMobileInfo
		#else
			_T("HW-MB32A")
		#endif
		);
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -