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

📄 eons.cpp

📁 windows mobile RIL软件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            {
                for( int i = 1; i <= (int)dwItemCount; i++ )
                {
                    DWORD dw = 0;
                    memset( pBuf, 0, dwSize );

                    CRSMRecord kk( EFopl, i, dwSize );
                    hr2 = kk.Read();
                    kk.Dump();

                    if ( SUCCEEDED( hr2 ) )
                    {
                        dw = dwSize;
                        BOOL fOk = kk.GetRecord( (BYTE*)pBuf, dw );
                        hr2 = ( fOk ? S_OK : E_FAIL );
                    }

                    if ( SUCCEEDED( hr2 ) && pBuf[0] != (char)0xff )
                    {
                        const char *cptr = pBuf;

                        /* 3GPP TS 31.102 version 5.7.0 section 4.2.59 */

                        int b[6];
                        for( int j = 0; j < 3; j++ )
                        {
                            char x = pBuf[j];

                            b[j*2]   = ( 0x0f & ( x >> 4 ) );
                            b[j*2+1] = ( 0x0f & x );
                        }

                        /* BCD offset */
                        int bindex[] = { 1, 0, 3, 5, 4, 2 };

                        BOOL fDeleted = FALSE;

                        char szPLMN[ARRAY_LENGTH(b)+1];
                        for( int j = 0; j < ARRAY_LENGTH(b) && !fDeleted; j++ )
                        {
                            szPLMN[j] = NULL;
                            if ( 0 <= b[bindex[j]] && b[bindex[j]] < 10 )
                            {
                                /* digits 0-9 */
                                szPLMN[j] = ( '0'+b[bindex[j]] );
                            }
                            else if ( b[bindex[j]] == 0x0d )
                            {
                                /* wildcard */
                                szPLMN[j] = WILDCARD;
                            }
                            else if ( b[bindex[j]] == 0x0f )
                            {
                                /* dontcare */
                                szPLMN[j] = DONTCARE;
                            }
                            else
                            {
                                /* deleted entry */
                                fDeleted = TRUE;
                            }
                        }
                        szPLMN[ARRAY_LENGTH(szPLMN)-1] = NULL;

                        OPLStruct opl;
                        memset( &opl, 0, sizeof(opl) );

                        if ( !fDeleted )
                        {
                            long lacA = ( ( 0x0ff & pBuf[3] ) << 8 ) + ( 0x0ff & pBuf[4] );
                            long lacZ = ( ( 0x0ff & pBuf[5] ) << 8 ) + ( 0x0ff & pBuf[6] );
                            long idx  = ( 0x0ff & pBuf[7] );

                            ASSERT( idx > 0 );

                            strncpyz( opl.szPLMN, szPLMN, ARRAY_LENGTH(opl.szPLMN) );
                            opl.dwLACa  = lacA;
                            opl.dwLACz  = lacZ;
                            opl.dwIndex = idx;
                        }
                        else
                        {
                            /* index of 0 means deleted entry */
                            opl.dwIndex = 0;
                        }

                        m_opl.AddThing( opl );
                    }
                }

                hr = S_OK;
            }
            else
            {
                hr = E_OUTOFMEMORY;
            }

            if ( pBuf != NULL )
            {
                delete[] pBuf;
                pBuf = NULL;
            }
        }
    }

    return hr;
}

HRESULT
EONS::ReadPNNData()
{
    /* assumption -- m_cs has been acquired */

    HRESULT hr = E_FAIL;

    CRSMStatus k( EFpnn );
    HRESULT hr2 = k.Read();
    k.Dump();
    if ( SUCCEEDED( hr2 ) )
    {
        RILSIMRECORDSTATUS rsrs = k.GetStatus();
        if ( ( rsrs.dwParams & RIL_PARAM_SRS_SIZE ) &&
            ( rsrs.dwParams & RIL_PARAM_SRS_ITEMCOUNT ) )
        {
            const DWORD dwSize = rsrs.dwSize;
            const DWORD dwItemCount = rsrs.dwItemCount;

            char *pBuf = new char[ dwSize ];
            if ( pBuf != NULL )
            {
                for( int i = 1; i <= (int)dwItemCount; i++ )
                {
                    DWORD dw = 0;
                    memset( pBuf, 0, dwSize );

                    CRSMRecord kk( EFpnn, i, dwSize );
                    hr2 = kk.Read();
                    kk.Dump();

                    if ( SUCCEEDED( hr2 ) )
                    {
                        dw = dwSize;
                        BOOL fOk = kk.GetRecord( (BYTE*)pBuf, dw );
                        hr2 = ( fOk ? S_OK : E_FAIL );
                    }

                    RILOPERATORNAMES ron;
                    memset( &ron, 0, sizeof(ron) );
                    ron.cbSize = sizeof(ron);

                    if ( SUCCEEDED( hr2 ) && pBuf[0] != (char)0xff )
                    {
                        const char *cptr = pBuf;

                        /* 3GPP TS 31.102 version 5.7.0 section 4.2.58 */

                        const char *Ftlv = NULL;
                        int Fiei = 0;
                        int Flen = 0;

                        if ( cptr != NULL && dw >= 2 )
                        {
                            Fiei = (int)( 0x0ff & cptr[0] );
                            Flen = (int)( 0x0ff & cptr[1] );
                            if ( (int)dw >= 2+Flen )
                            {
                                Ftlv = cptr;

                                cptr += ( 2+Flen );
                                dw   -= ( 2+Flen );
                            }
                            else
                            {
                                cptr = NULL;
                                dw = 0;
                            }
                        }

                        const char *Stlv = NULL;
                        int Siei = 0;
                        int Slen = 0;

                        if ( cptr != NULL && dw >= 2 )
                        {
                            Siei = (int)( 0x0ff & cptr[0] );
                            Slen = (int)( 0x0ff & cptr[1] );
                            if ( (int)dw >= 2+Slen )
                            {
                                Stlv = cptr;
                            }
                        }

                        /* long name */
                        if ( Fiei == IEIfullname && Ftlv != NULL )
                        {
                            BOOL fLong = DecodeNetworkNameTLV( Ftlv, ron.szLongName, ARRAY_LENGTH(ron.szLongName) );
                            if ( fLong )
                            {
                                ron.dwParams |= RIL_PARAM_ON_LONGNAME;
                            }
                        }

                        /* short name */
                        if ( Siei == IEIshortname && Stlv != NULL )
                        {
                            BOOL fShort = DecodeNetworkNameTLV( Stlv, ron.szShortName, ARRAY_LENGTH(ron.szShortName) );
                            if ( fShort )
                            {
                                ron.dwParams |= RIL_PARAM_ON_SHORTNAME;
                            }
                        }
                    }

                    /* add to maintain PNN order regardless of read/parse status */
                    m_pnn.AddThing( ron );
                }

                hr = S_OK;
            }
            else
            {
                hr = E_OUTOFMEMORY;
            }

            if ( pBuf != NULL )
            {
                delete[] pBuf;
                pBuf = NULL;
            }
        }
    }

    return hr;
}

BOOL
EONS::DecodeNetworkNameTLV( const char *cptr, char *pszOUT, DWORD dwOut ) const
{
    BOOL fOk = FALSE;
    if ( cptr[0] != (char)0xff )
    {
        /* 3GPP TS 24.008 version 3.2.1 section 10.5.3.5a */

        int iei = ( 0x07f & cptr[0] );
        int len = ( 0x0ff & cptr[1] );
        int ext = ( 0x01 & ( cptr[2] >> 7 ) );
        int cs  = ( 0x07 & ( cptr[2] >> 4 ) );
        int ci  = ( 0x01 & ( cptr[2] >> 3 ) );
        int spr = ( 0x07 & cptr[2] );

#if 0
        _tprintf(TEXT("iei [%d]"), iei );
        _tprintf(TEXT("len [%d]"), len );
        _tprintf(TEXT("ext [%d] cs [%d] ci [%d] spr [%d]"), 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 );
                pszOUT[lenZ] = 0;

                AnsiString as(szBuf);
                strncpyz( pszOUT, (const char *)as, dwOut );
            }
            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] ) );
                }

                AnsiString as(szBuf);
                strncpyz( pszOUT, (const char *)as, dwOut );
            }
            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 )
            {

⌨️ 快捷键说明

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