// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// Name : CBerTlv.cpp
// Part of : Series 60 / utility
// Based on 3GPP TS 11.14 V8.8.0
// Version : 1.0
// EXTERNAL RESOURCES
//
// Include Files
#include "CBerTlv.h" // Header of this class
#include "tflogger.h" // For logging
// External Data Structures
// none
// External Function Prototypes
// none
// LOCAL CONSTANTS AND MACROS
// none
// MODULE DATA STRUCTURES
// none
// Local Data Structures
// none
// Local Function Prototypes
// none
// LOCAL FUNCTIONS
// none
// MEMBER FUNCTIONS
//=============================================================================
// -----------------------------------------------------------------------------
// CBerTlv::CBerTlv
// Constructor
// -----------------------------------------------------------------------------
//
EXPORT_C CBerTlv::CBerTlv
(
// None
)
{
// None
}
// -----------------------------------------------------------------------------
// CBerTlv::TlvByTagValue
// Find TLV by tag value. aTlv is set to point to found TLV. If there are more
// than one TLV with the same tag then itemNbr can be used to select which one
// is returned. If no tags are found return KErrNotFound else KErrNone.
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CBerTlv::TlvByTagValue
(
CTlv* aTlv, // TLV
TUint8 aTlvTagValue, // TLV identifier
TInt itemNbr // Item number
)
{
TFLOGSTRING("UTILITY: CBerTlv::TlvByTagValue");
TInt currentTlv( 0 );
TInt tlvLength( 0 );
TInt index( 0 );
// TLV start index
TInt ind( KCommonTlvHeaderLength );
TUint8 berTlvLength( 0 );
if ( KTwoByteLengthCoding == iData[KTlvLengthStartPosition] )
{
berTlvLength = iData[KTlvLengthStartPosition + 1];
ind = ind + 1;
}
else
{
berTlvLength = iData[KTlvLengthStartPosition];
}
for ( TInt i = 0; i < berTlvLength; i += tlvLength )
{
// First determine if the length of the TLV is coded with 1 or 2 bytes.
if ( KTwoByteLengthCoding == iData[ind + 1] )
{
// Length is coded with 2 bytes -> 1 extra byte required to be
// added to total length. Also TLV header bytes (2) must be added
// to total length
tlvLength = iData[ind + 2] + KTlvHeaderLength + 1;
}
else
{
// TLV header bytes (2) must be added to total length
tlvLength = iData[ind + 1] + KTlvHeaderLength;
}
currentTlv = iData[ind]&KTagValueMask;
// Check if TLV in current index is the one that we are searching for
if ( aTlvTagValue == currentTlv )
{
if( index == itemNbr)
{
TPtrC8 data = ( iData.Mid( ind , tlvLength ) );
aTlv->SetData( data );
return KErrNone;
}
else
{
index++;
}
}
ind += tlvLength;
}
return KErrNotFound;
}
// -----------------------------------------------------------------------------
// CBerTlv::TlvByTagValueMulti
// Find several TLVs by tag value. It is assumed that TLVs are sequential. aTlv
// is set to point to TLV sequence. If no tags are found return KErrNotFound
// else KErrNone.
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CBerTlv::TlvByTagValueMulti
(
CTlv* aTlv, // TLV to fill
TUint8 aTlvTagValue // Tag of TLV to find
)
{
TFLOGSTRING("UTILITY: CBerTlv::TlvByTagValueMulti");
TInt currentTlv( 0 );
TInt16 tlvLength( 0 );
TInt indMulti( 0 );
TInt16 multiLength( 0 );
// TLV start index
TInt ind( KCommonTlvHeaderLength );
TUint8 berTlvLength;
// First determine if the length of the BerTLV is coded with 1 or 2 bytes.
if ( KTwoByteLengthCoding == iData[KTlvLengthStartPosition] )
{
berTlvLength = iData[KTlvLengthStartPosition + 1];
ind = ind + 1;
}
else
{
berTlvLength = iData[KTlvLengthStartPosition];
}
for ( TInt i = 0; i < berTlvLength; i+= tlvLength )
{
// First determine if the length of the TLV is coded with 1 or 2 bytes.
if ( KTwoByteLengthCoding == iData[ind + 1] )
{
// Length is coded with 2 bytes -> real length is in second byte.
// first byte is 81 and it is tag for 2 byte length coding.
tlvLength = static_cast<TInt16>( iData[ind + 0x02] +
KTlvHeaderLength + 1 );
}
else
{
// TLV header bytes (2) must be added to total length
tlvLength = static_cast<TInt16>( iData[ind + 1] +
KTlvHeaderLength );
}
currentTlv = iData[ind]&KTagValueMask;
// Check if TLV in current index is the one that we are searching for
if ( aTlvTagValue == currentTlv && multiLength == 0x00 )
{
// Save first tag position
indMulti = ind;
multiLength = tlvLength;
}
// Add length
if ( aTlvTagValue == currentTlv && indMulti != ind )
{
multiLength = static_cast<TInt16>( multiLength + tlvLength );
}
// If last tag, return
if ( (i + tlvLength) >= berTlvLength )
{
TPtrC8 data = ( iData.Mid( indMulti , multiLength ) );
aTlv->SetData( data );
break;
}
ind += tlvLength;
}
if( 0 == indMulti)
{
return KErrNotFound;
}
else
{
return KErrNone;
}
}
//End Of File