📄 eons.cpp
字号:
int cs = ( 0x07 & ( cptr[2] >> 4 ) );
int ci = ( 0x01 & ( cptr[2] >> 3 ) );
int spr = ( 0x07 & cptr[2] );
#if 0
DEBUGMSG(ZONE_EONS,(TEXT("RILDrv : i : iei [%d]\r\n"), iei ));
DEBUGMSG(ZONE_EONS,(TEXT("RILDrv : i : len [%d]\r\n"), len ));
DEBUGMSG(ZONE_EONS,(TEXT("RILDrv : i : ext [%d] cs [%d] ci [%d] spr [%d]\r\n"), ext, cs, ci, spr ));
#endif
if ( len > 0 )
{
TCHAR szBuf[128];
memset( szBuf, 0, sizeof(szBuf) );
if ( cs == 0 )
{
/* cell broadcast data coding scheme, GSM default alphabet */
/* GSM 03.38 */
int offset = 3;
const char *pcszA = cptr+offset;
/* adjust */
--len;
UINT lenZ = 0;
ConvertToUnicode( ENCODING_GSMDEFAULT, pcszA, (UINT)len, szBuf, ARRAY_LENGTH(szBuf), lenZ );
ASSERT( lenZ < ARRAY_LENGTH(szBuf) );
szBuf[ ( lenZ < ARRAY_LENGTH(szBuf) ? lenZ : ARRAY_LENGTH(szBuf)-1 ) ] = 0;
StringCchPrintfA( pszOUT, dwOut, "%ls", szBuf );
}
else if ( cs == 1 )
{
/* UCS2 (16bit) */
int offset = 3;
const char *pcszA = cptr+offset;
/* adjust */
--len;
ASSERT( len % 2 == 0 );
int iNum = ( len / 2 );
for( int i = 0; i < iNum && i < ARRAY_LENGTH(szBuf)-1; i++ )
{
szBuf[i] = (TCHAR)( ( 0x0ff00 & ( pcszA[i*2] << 8 ) ) | ( 0x0ff & pcszA[i*2+1] ) );
}
szBuf[ARRAY_LENGTH(szBuf)-1] = 0;
StringCchPrintfA( pszOUT, dwOut, "%ls", szBuf );
}
else
{
/* reserved coding scheme */
ASSERT( FALSE );
pszOUT[0] = 0;
}
fOk = ( pszOUT[0] != NULL );
}
}
return fOk;
}
BOOL
EONS::Match( DWORD dwPLMN, DWORD dwLAC, RILOPERATORNAMES *pRON ) const
{
BOOL fMatched = FALSE;
BOOL fHasLAC = ( dwLAC != 0xFFFFFFFF );
ASSERT( dwPLMN <= 999999 );
ASSERT( dwLAC <= 0x0ffff || dwLAC == 0xFFFFFFFF );
/* only support 6-digit PLMN */
if ( dwPLMN <= 999999 && ( dwLAC <= 0x0ffff || dwLAC == 0xFFFFFFFF ) )
{
SYNCBLOCK( m_cs );
if ( m_fDoneReading )
{
DWORD entries[2] = { dwPLMN, 0xFFFFFFFF };
if ( dwPLMN <= 99999 )
{
/* normalize to 6-digit PLMN */
/* this follows how network.cpp:GetLongOperatorName() expands 5-digit PLMN to 6-digit */
DWORD YYY = ( dwPLMN / 100 );
DWORD XX = ( dwPLMN % 100 );
entries[0] = ( YYY * 1000 + XX ); /* YYY0XX */
entries[1] = ( dwPLMN * 10 ); /* YYYXX0 */
}
for( int i = 0; i < ARRAY_LENGTH(entries) && entries[i] != 0xFFFFFFFF && !fMatched; i++ )
{
DWORD dwEntry = entries[i];
int digits[] =
{
( dwEntry / 100000 ),
( ( dwEntry / 10000 ) % 10 ),
( ( dwEntry / 1000 ) % 10 ),
( ( dwEntry / 100 ) % 10 ),
( ( dwEntry / 10 ) % 10 ),
( dwEntry % 10 )
};
#ifdef DEBUG
/* at least as large as dwPLMN to catch problem with normalizing */
ASSERT( dwEntry >= dwPLMN );
/* should not process this marker entry */
ASSERT( dwEntry != 0xFFFFFFFF );
/* enforce 6-digit PLMN */
ASSERT( dwEntry <= 999999 );
/* ensure digits[] is setup right */
ASSERT( ARRAY_LENGTH(digits) == 6 );
for( int j = 0; j < ARRAY_LENGTH(digits); j++ )
{
ASSERT( 0 <= digits[j] && digits[j] <= 9 );
}
#endif
int iPNN = -1;
int c = const_cast<GrowableThingCollection<OPLStruct>*>( &m_opl )->GetSize();
for( int j = 0; j < c && !fMatched; j++ )
{
OPLStruct opl = const_cast<GrowableThingCollection<OPLStruct>*>( &m_opl )->GetThingAtIndex( j );
/* PLMN match */
BOOL fMatchedPLMN = TRUE;
for( int k = 0; k < 6 && fMatchedPLMN; k++ )
{
if ( opl.szPLMN[k] == WILDCARD )
{
/* always match */
}
else if ( opl.szPLMN[k] == DONTCARE )
{
/* 3GPP TS 24.008 version 3.2.1 Release 1999 Table 10.5.3 */
/* handling the case for YYYXX0 */
fMatchedPLMN = ( k == 5 && dwPLMN <= 99999 && digits[k] == 0 );
}
else
{
/* match exact digit */
fMatchedPLMN = ( opl.szPLMN[k]-'0' == digits[k] );
}
}
/* LAC match */
BOOL fMatchedLAC = ( opl.dwLACa == 0x0000 && opl.dwLACz == 0xfffe );
if ( !fMatchedLAC && fHasLAC )
{
fMatchedLAC = ( opl.dwLACa <= dwLAC && dwLAC <= opl.dwLACz );
}
fMatched = ( fMatchedPLMN && fMatchedLAC );
if ( fMatched )
{
iPNN = static_cast<int>( opl.dwIndex );
/* skip deleted entry */
fMatched = ( iPNN != 0 );
}
}
if ( fMatched )
{
if ( iPNN > 0 )
{
int c2 = const_cast<GrowableThingCollection<RILOPERATORNAMES>*>( &m_pnn )->GetSize();
if ( iPNN-1 < c2 )
{
RILOPERATORNAMES ron = const_cast<GrowableThingCollection<RILOPERATORNAMES>*>( &m_pnn )->GetThingAtIndex( iPNN-1 );
/* consider matched IFF there is a long name */
fMatched = ( ( ron.dwParams & RIL_PARAM_ON_LONGNAME ) != 0 );
if ( fMatched && pRON != NULL )
{
memcpy( pRON, &ron, sizeof(RILOPERATORNAMES) );
}
}
else
{
ASSERT( FALSE );
fMatched = FALSE;
}
}
else
{
ASSERT( FALSE );
fMatched = FALSE;
}
}
}
}
}
return fMatched;
}
void
EONS::Validate() const
{
#ifdef DEBUG
/* normally everything from SIM should be fine, right? */
{
SYNCBLOCK( m_cs );
int iOPL = const_cast<GrowableThingCollection<OPLStruct>*>( &m_opl )->GetSize();
int iPNN = const_cast<GrowableThingCollection<RILOPERATORNAMES>*>( &m_pnn )->GetSize();
if ( iOPL > 0 )
{
ASSERT( iPNN > 0 );
}
/* 3GPP TS 31.102 version 5.7.0 release 5 section 4.2.59 EFOPL */
/* PNN record identifier is of size 1 byte -- maximum 2^8 PNN entries */
ASSERT( 0 <= iPNN && iPNN < 256 );
for( int i = 0; i < iOPL; i++ )
{
OPLStruct opl = const_cast<GrowableThingCollection<OPLStruct>*>( &m_opl )->GetThingAtIndex( i );
for( int j = 0; j < (int)strlen(opl.szPLMN); j++ )
{
/* make sure the DONTCARE is in the MNC3 position */
if ( opl.szPLMN[j] == DONTCARE )
{
ASSERT( j == 5 );
}
}
}
#ifdef CHECK
for( int i = 0; i < iOPL; i++ )
{
OPLStruct opl = const_cast<GrowableThingCollection<OPLStruct>*>( &m_opl )->GetThingAtIndex( i );
/* 6-digit PLMN for not-deleted entry */
if ( opl.dwIndex != 0 )
{
ASSERT( strlen(opl.szPLMN) == 6 );
}
/* lacA <= lacZ */
ASSERT( opl.dwLACa <= opl.dwLACz );
/* lacZ <= 0x0ffff */
ASSERT( opl.dwLACz <= 0x0ffff );
/* PLMN should not be all WILDCARDs */
BOOL fAllWildcards = TRUE;
for( int j = 0; j < (int)strlen(opl.szPLMN) && fAllWildcards; j++ )
{
fAllWildcards = ( opl.szPLMN[j] == WILDCARD );
}
ASSERT( !fAllWildcards );
/* index to PNN list */
ASSERT( opl.dwIndex <= 256 );
/* index can only be either 0 (deleted entry) or within [1,num-of-PNN-entry] */
ASSERT( opl.dwIndex == 0 || ( 1 <= opl.dwIndex && opl.dwIndex <= static_cast<DWORD>( iPNN ) ) );
}
for( int i = 0; i < iPNN; i++ )
{
RILOPERATORNAMES ron = const_cast<GrowableThingCollection<RILOPERATORNAMES>*>( &m_pnn )->GetThingAtIndex( i );
/* dont exist */
ASSERT( ! ( ron.dwParams & RIL_PARAM_ON_COUNTRY_CODE ) );
ASSERT( ! ( ron.dwParams & RIL_PARAM_ON_NUMNAME ) );
}
#endif
}
#endif
}
/****************************************************************************/
/****************************************************************************/
const TCHAR EONSCache::RegistryPath[] = RIL_SECURE_REGISTRY_KEY TEXT("\\EONS.cache");
EONSCache::EONSCache()
{
}
EONSCache::EONSCache( const EONS& ref )
: EONS(ref)
{
}
EONSCache::~EONSCache()
{
}
HRESULT
EONSCache::Read()
{
/* override to make the read synchronous */
HRESULT hr = ReadData();
return hr;
}
HRESULT
EONSCache::Write()
{
HRESULT hr = WriteOPLData();
if ( SUCCEEDED( hr ) )
{
hr = WritePNNData();
}
return hr;
}
void
EONSCache::Invalidate()
{
Clear();
}
HRESULT
EONSCache::ReadOPLData()
{
HRESULT hr = E_FAIL;
HKEY hkey = NULL;
StringBuffer key;
key.Set( RegistryPath );
key.Append( TEXT("\\opl") );
LONG lResult = RegOpenKeyEx( RIL_REGISTRY_ROOT, key, 0, 0, &hkey );
if ( lResult == ERROR_SUCCESS )
{
hr = S_OK;
TCHAR subkey[16];
BOOL fDone = FALSE;
for( int i = 1; !fDone; i++ )
{
StringCchPrintf( subkey, ARRAY_LENGTH(subkey), TEXT("%d"), i );
HKEY hkey2 = NULL;
lResult = RegOpenKeyEx( hkey, subkey, 0, 0, &hkey2 );
if ( lResult == ERROR_SUCCESS )
{
OPLStruct opl;
memset( &opl, 0, sizeof(opl) );
BOOL fError = FALSE;
DWORD dwSize = 0;
DWORD dwType = 0;
{
TCHAR szBuf[ARRAY_LENGTH(opl.szPLMN)];
dwSize = sizeof(szBuf);
lResult = RegQueryValueEx( hkey2, TEXT("PLMN"), NULL, &dwType, (BYTE*)szBuf, &dwSize );
fError = ( lResult != ERROR_SUCCESS || dwType != REG_SZ );
if ( !fError )
{
StringCchPrintfA( opl.szPLMN, ARRAY_LENGTH(opl.szPLMN), "%ls", szBuf );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -