📄 hwmobile.cpp
字号:
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 + -