--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/natplugins/natpnatfwsdpprovider/src/nspcontentparser.cpp Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,1303 @@
+/*
+* Copyright (c) 2007 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: Class implementation for Sdp content parser.
+*
+*/
+
+#include <e32cmn.h>
+#include <in_sock.h>
+#include <sdpcodecstringpool.h>
+#include <sdpcodecstringconstants.h>
+#include <sdpdocument.h>
+#include <sdpconnectionfield.h>
+#include <sdpattributefield.h>
+#include <sdpmediafield.h>
+#include "natfwcandidate.h"
+#include "natfwcredentials.h"
+#include "nspcontentparser.h"
+#include "nspdefs.h"
+
+const TInt KAttributesNumber = 7;
+static const TText8* const AttributeArray[ KAttributesNumber ] =
+ {
+ _S8("candidate"),
+ _S8("remote-candidates"),
+ _S8("ice-lite"),
+ _S8("ice-passive"),
+ _S8("ice-ufrag"),
+ _S8("ice-pwd"),
+ _S8("ice-mismatch")
+ };
+const TInt KIceAttrCandidateIndex = 0;
+const TInt KIceAttrRemoteCandidatesIndex = 1;
+const TInt KIceAttrLiteIndex = 2;
+const TInt KIceAttrPassiveIndex = 3;
+const TInt KIceAttrUfragIndex = 4;
+const TInt KIceAttrPwdIndex = 5;
+const TInt KIceAttrMismatchIndex = 6;
+
+_LIT8( KAttrRtcp, "rtcp" );
+_LIT8( KAttrEmpty, " " );
+_LIT8( KFieldSeparator, " " );
+
+const TInt KTypeAttrNumber = 9;
+static const TText8* const CandidateTypeArray[ KTypeAttrNumber ] =
+ {
+ _S8( "typ" ),
+ _S8( "host" ),
+ _S8( "local" ),
+ _S8( "srflx" ),
+ _S8( "prflx" ),
+ _S8( "relay" ),
+ _S8( "tcp-so" ),
+ _S8( "tcp-act" ),
+ _S8( "tcp-pass" )
+ };
+const TInt KTypeAttrIndexType = 0;
+const TInt KTypeAttrIndexHost = 1;
+const TInt KTypeAttrIndexLocal = 2;
+const TInt KTypeAttrIndexServerReflex = 3;
+const TInt KTypeAttrIndexPeerReflex = 4;
+const TInt KTypeAttrIndexRelay = 5;
+
+const TUint KRejecPort = 0;
+
+const TInt KMaxCandidateLength = 200; // Max for candidate creation.
+const TInt KMaxLengthNumberConversion = 40; // Priority field max length.
+const TInt KMaxLengthTInetAddr = 40; // Must support IPv4/IPv6
+const TInt KMaxLengthOfFQDN = 255; // For FQDNs
+const TInt KMaxLengthRtcpField = 60; // Max for rctp attr. value
+
+#define FINDFIELD_L( aField, aMediafield, aFieldarray ) \
+ User::LeaveIfNull( aField = CNSPContentParser::FindMediaField( aMediafield, aFieldarray ) )
+
+// ======== MEMBER FUNCTIONS ========
+// ---------------------------------------------------------------------------
+// CNSPContentParser::CNSPContentParser
+// ---------------------------------------------------------------------------
+//
+CNSPContentParser::CNSPContentParser()
+ {
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::ConstructL()
+ {
+ RStringPool pool = SdpCodecStringPool::StringPoolL();
+
+ // ICE attributes
+ iCandidate = pool.OpenFStringL(
+ TPtrC8( AttributeArray[ KIceAttrCandidateIndex ] ) );
+ iRemoteCandidates = pool.OpenFStringL(
+ TPtrC8( AttributeArray[ KIceAttrRemoteCandidatesIndex ] ) );
+ iLite = pool.OpenFStringL(
+ TPtrC8( AttributeArray[ KIceAttrLiteIndex ] ) );
+ iPassive = pool.OpenFStringL(
+ TPtrC8( AttributeArray[ KIceAttrPassiveIndex ] ) );
+ iUfrag = pool.OpenFStringL(
+ TPtrC8( AttributeArray[ KIceAttrUfragIndex ] ) );
+ iPwd = pool.OpenFStringL(
+ TPtrC8( AttributeArray[ KIceAttrPwdIndex ] ) );
+ iMismatch = pool.OpenFStringL(
+ TPtrC8( AttributeArray[ KIceAttrMismatchIndex ] ) );
+
+ // Other
+ iRTCP = pool.OpenFStringL( KAttrRtcp() );
+ iUdp = pool.StringF( SdpCodecStringConstants::EProtocolUdp,
+ SdpCodecStringPool::StringTableL() );
+ iTcp = pool.StringF( SdpCodecStringConstants::EProtocolTcp,
+ SdpCodecStringPool::StringTableL() );
+ iIN = pool.StringF( SdpCodecStringConstants::ENetType,
+ SdpCodecStringPool::StringTableL() );
+ iIPv4 = pool.StringF( SdpCodecStringConstants::EAddressTypeIP4,
+ SdpCodecStringPool::StringTableL() );
+ iIPv6 = pool.StringF( SdpCodecStringConstants::EAddressType,
+ SdpCodecStringPool::StringTableL() );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::NewL
+// ---------------------------------------------------------------------------
+//
+CNSPContentParser* CNSPContentParser::NewL()
+ {
+ CNSPContentParser* self = CNSPContentParser::NewLC();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::NewLC
+// ---------------------------------------------------------------------------
+//
+CNSPContentParser* CNSPContentParser::NewLC()
+ {
+ CNSPContentParser* self = new( ELeave ) CNSPContentParser;
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::CNSPContentParser
+// ---------------------------------------------------------------------------
+//
+CNSPContentParser::~CNSPContentParser()
+ {
+ iCandidate.Close();
+ iRemoteCandidates.Close();
+ iLite.Close();
+ iPassive.Close();
+ iUfrag.Close();
+ iPwd.Close();
+ iMismatch.Close();
+ iRTCP.Close();
+ iUdp.Close();
+ iTcp.Close();
+ iIN.Close();
+ iIPv4.Close();
+ iIPv6.Close();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::IsIceSupported
+// ---------------------------------------------------------------------------
+//
+TBool CNSPContentParser::IsIceSupported( CSdpDocument& aDocument ) const
+ {
+ RPointerArray<CSdpMediaField>& mediafields = aDocument.MediaFields();
+
+ const TInt mediafieldcount( mediafields.Count() );
+ for ( TInt index = 0; index < mediafieldcount; index++ )
+ {
+ RPointerArray<CSdpAttributeField>& attributes =
+ mediafields[index]->AttributeFields();
+
+ const TInt attributecount( attributes.Count() );
+ for ( TInt jndex = 0; jndex < attributecount; jndex++ )
+ {
+ if ( iCandidate == attributes[jndex]->Attribute() )
+ {
+ return ETrue;
+ }
+ }
+ }
+
+ return EFalse;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::IsMismatchL
+// ---------------------------------------------------------------------------
+//
+TBool CNSPContentParser::IsMismatchL( CSdpDocument& aDocument ) const
+ {
+ const CSdpConnectionField* connField = aDocument.ConnectionField();
+ const TDesC8& address = ( connField ? connField->Address() : KNullDesC8 );
+ RPointerArray<CSdpMediaField>& mediafields = aDocument.MediaFields();
+
+ TBool mismatch( EFalse );
+ const TInt mediafieldcount( mediafields.Count() );
+ for ( TInt index = 0; index < mediafieldcount && !mismatch; index++ )
+ {
+ const TDesC8& addr = CONN_ADDR( *mediafields[index], address );
+ mismatch = IsMismatchAttribute( *mediafields[index] );
+
+ if ( !mismatch && IsMismatchL( *mediafields[index], addr ) )
+ {
+ AddMismatchL( *mediafields[index] );
+ mismatch = ETrue;
+ }
+ }
+
+ return mismatch;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::IsMismatchL
+// ---------------------------------------------------------------------------
+//
+TBool CNSPContentParser::IsMismatchL( CSdpMediaField& aMediaField,
+ const TDesC8& aAddress ) const
+ {
+ const TDesC8& rtpAddr = CONN_ADDR( aMediaField, aAddress );
+ const TUint rtpPort = aMediaField.Port();
+
+ RBuf8 rtcpAddr;
+ rtcpAddr.CreateL( KMaxLengthOfFQDN );
+ rtcpAddr.CleanupClosePushL();
+ rtcpAddr = rtpAddr;
+ TUint rtcpPort = rtpPort;
+ TBool isRtcp = FindRTCP( aMediaField, rtcpAddr, rtcpPort );
+
+ RPointerArray<CNATFWCandidate> remotecand;
+ CleanupStack::PushL( TCleanupItem(
+ CNSPContentParser::CleanupArrayItem, &remotecand ) );
+
+ GetCandidatesL( aMediaField, remotecand );
+
+ const TInt candidatecount( remotecand.Count() );
+ TBool mismatch = ( candidatecount ? ETrue : EFalse );
+ for ( TInt index = 0; index < candidatecount; index++ )
+ {
+ const TDesC8& addr = remotecand[index]->TransportDomainAddr();
+ const TUint port = remotecand[index]->TransportDomainPort();
+
+ if ( ( !rtpAddr.Compare( addr ) && port == rtpPort ) ||
+ ( isRtcp && !rtcpAddr.Compare( addr ) && port == rtcpPort ) )
+ {
+ mismatch = EFalse;
+ break;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( &remotecand );
+ CleanupStack::PopAndDestroy( &rtcpAddr );
+
+ NSPLOG_INT( "CNSPContentParser::IsMismatchL, ret:", mismatch )
+ return mismatch;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::IsMismatchAttribute
+// ---------------------------------------------------------------------------
+//
+TBool CNSPContentParser::IsMismatchAttribute( CSdpMediaField& aMediaField ) const
+ {
+ RPointerArray<CSdpAttributeField>& attributes = aMediaField.AttributeFields();
+
+ const TInt attributecount( attributes.Count() );
+ for ( TInt index = 0; index < attributecount; index++ )
+ {
+ if ( iMismatch == attributes[index]->Attribute() )
+ {
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::IsLiteAttribute
+// ---------------------------------------------------------------------------
+//
+TBool CNSPContentParser::IsLiteAttribute( CSdpDocument& aDocument ) const
+ {
+ const RPointerArray<CSdpAttributeField>& attributes =
+ aDocument.AttributeFields();
+
+ const TInt attributecount( attributes.Count() );
+ for ( TInt index = 0; index < attributecount; index++ )
+ {
+ if ( iLite == attributes[index]->Attribute() )
+ {
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::FindRTCP
+// ---------------------------------------------------------------------------
+//
+TBool CNSPContentParser::FindRTCP( CSdpMediaField& aMediaField,
+ TDes8& aAddress, TUint& aPort ) const
+ {
+ const RPointerArray<CSdpAttributeField>& attributes =
+ aMediaField.AttributeFields();
+
+ const TInt attributecount( attributes.Count() );
+ for ( TInt index = 0; index < attributecount; index++ )
+ {
+ if ( iRTCP == attributes[index]->Attribute() )
+ {
+ TLex8 lexer( attributes[index]->Value() );
+
+ TUint port( KRejecPort );
+ TRAPD( error, LexTDesC8ToTUintL( lexer.NextToken(), port ) );
+ aPort = ( KErrNone == error ? port : aPort );
+
+ if ( KErrNone == error && !lexer.Eos() )
+ {
+ lexer.NextToken(); // nettype, not needed
+ lexer.NextToken(); // addresstype, not needed
+ aAddress = lexer.NextToken();
+ }
+
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::ModifyRTCPL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::ModifyRTCPL( CSdpMediaField& aMediaField,
+ const TDesC8& aAddress, TUint aPort ) const
+ {
+ TInetAddr address;
+ CSdpAttributeField* attr = NULL;
+ const RPointerArray<CSdpAttributeField>& attributes =
+ aMediaField.AttributeFields();
+
+ const TInt attributecount( attributes.Count() );
+ for ( TInt index = 0; index < attributecount; index++ )
+ {
+ attr = attributes[index];
+
+ if ( iRTCP == attr->Attribute() )
+ {
+ HBufC8* newattribute = HBufC8::NewLC( KMaxLengthRtcpField );
+ TPtr8 ptr( newattribute->Des() );
+
+ AppendNumToTDes8L( ptr, aPort );
+ AppendTDesC8ToTDes8L( ptr, iIN.DesC() );
+ InputTDesC8ToTInetAddrL( aAddress, address );
+ AppendTDesC8ToTDes8L( ptr, KAfInet == address.Family() ?
+ iIPv4.DesC() : iIPv6.DesC() );
+ AppendTDesC8ToTDes8L( ptr, aAddress, EFalse );
+
+ attr->SetL( attr->Attribute(), newattribute->Des() );
+ CleanupStack::PopAndDestroy( newattribute );
+ break;
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::AddLiteL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::AddLiteL( CSdpDocument& aDocument ) const
+ {
+ CSdpAttributeField* attr = CSdpAttributeField::NewLC( iLite, KNullDesC8 );
+ User::LeaveIfError( aDocument.AttributeFields().Append( attr ) );
+ CleanupStack::Pop( attr );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::AddMismatchL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::AddMismatchL( CSdpDocument& aMismatch,
+ CSdpDocument& aMismatched ) const
+ {
+ CSdpMediaField* field = NULL;
+ RPointerArray<CSdpMediaField>& mismatchmedia = aMismatch.MediaFields();
+ RPointerArray<CSdpMediaField>& mismatchedmedia = aMismatched.MediaFields();
+
+ const TInt mediacount( mismatchmedia.Count() );
+ for ( TInt index = 0; index < mediacount; index++ )
+ {
+ if ( IsMismatchAttribute( *mismatchmedia[index] ) )
+ {
+ FINDFIELD_L( field, *mismatchmedia[index], mismatchedmedia );
+ AddMismatchL( *field );
+ RemoveIceContent( *mismatchmedia[index] );
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::AddMismatchL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::AddMismatchL( CSdpMediaField& aMediaField ) const
+ {
+ CSdpAttributeField* attr = CSdpAttributeField::NewLC( iMismatch, KNullDesC8 );
+ User::LeaveIfError( aMediaField.AttributeFields().Append( attr ) );
+ CleanupStack::Pop( attr );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::AddCandidatesL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::AddCandidatesL( CSdpMediaField& aMediaField,
+ const RPointerArray<CNATFWCandidate>& aCandidates ) const
+ {
+ CSdpAttributeField* attr = NULL;
+ RPointerArray<CSdpAttributeField>& attributeArray =
+ aMediaField.AttributeFields();
+
+ const TInt candidatecount( aCandidates.Count() );
+ for ( TInt index = 0; index < candidatecount; index++ )
+ {
+ TRAPD( error, attr = EncodeCandidateLineL( *aCandidates[index] ) )
+ User::LeaveIfError( KErrNone == error ?
+ attributeArray.Append( attr ) : error );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::AddRemoteCandidatesL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::AddRemoteCandidatesL( CSdpMediaField& aMediaField,
+ const RPointerArray<CNATFWCandidate>& aCandidates ) const
+ {
+ RPointerArray<CSdpAttributeField>& attributeArray =
+ aMediaField.AttributeFields();
+
+ CSdpAttributeField* attribute = EncodeRemoteCandidatesL( aCandidates );
+ CleanupStack::PushL( attribute );
+ User::LeaveIfError( attributeArray.Append( attribute ) );
+ CleanupStack::Pop( attribute );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::AddCredentialsL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::AddCredentialsL( CSdpMediaField& aMediaField,
+ const CNATFWCredentials& aCredentials ) const
+ {
+ RPointerArray<CSdpAttributeField>& attributeArray =
+ aMediaField.AttributeFields();
+
+ CSdpAttributeField* user = EncodeUfragL( aCredentials );
+ CleanupStack::PushL( user );
+ User::LeaveIfError( attributeArray.Append( user ) );
+ CleanupStack::Pop( user );
+
+ CSdpAttributeField* pwd = EncodePwdL( aCredentials );
+ CleanupStack::PushL( pwd );
+ User::LeaveIfError( attributeArray.Append( pwd ) );
+ CleanupStack::Pop( pwd );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::AddCredentialsL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::AddCredentialsL( CSdpDocument& aDocument,
+ const CNATFWCredentials& aCredentials ) const
+ {
+ RPointerArray<CSdpAttributeField>& attributeArray =
+ aDocument.AttributeFields();
+
+ CSdpAttributeField* user = EncodeUfragL( aCredentials );
+ CleanupStack::PushL( user );
+ User::LeaveIfError( attributeArray.Append( user ) );
+ CleanupStack::Pop( user );
+
+ CSdpAttributeField* pwd = EncodePwdL( aCredentials );
+ CleanupStack::PushL( pwd );
+ User::LeaveIfError( attributeArray.Append( pwd ) );
+ CleanupStack::Pop( pwd );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::GetCandidatesL
+// ---------------------------------------------------------------------------
+//
+TInt CNSPContentParser::GetCandidatesL( CSdpMediaField& aMediaField,
+ RPointerArray<CNATFWCandidate>& aCandidates ) const
+ {
+ TInt warning = KErrNone;
+ CNATFWCandidate* cand = NULL;
+ const RPointerArray<CSdpAttributeField>& attrArray =
+ aMediaField.AttributeFields();
+
+ const TInt attributecount( attrArray.Count() );
+ for ( TInt index = 0; index < attributecount; index++ )
+ {
+ if ( iCandidate == attrArray[index]->Attribute() )
+ {
+ cand = CNATFWCandidate::NewLC();
+
+ TRAPD( error, DecodeCandidateLineL( *attrArray[index], *cand ) );
+
+ if ( KErrNone == error )
+ {
+ User::LeaveIfError( aCandidates.Append( cand ) );
+ CleanupStack::Pop( cand );
+ }
+ else if ( KErrNoMemory == error )
+ {
+ User::Leave( KErrNoMemory );
+ }
+ else
+ {
+ warning = error;
+ CleanupStack::PopAndDestroy( cand );
+ }
+ }
+ }
+
+ return warning;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::GetRemoteCandidatesL
+// ---------------------------------------------------------------------------
+//
+TInt CNSPContentParser::GetRemoteCandidatesL( CSdpDocument& aDocument,
+ RPointerArray<CNATFWCandidate>& aRemoteCands ) const
+ {
+ const RPointerArray<CSdpMediaField>& mediafieldArray =
+ aDocument.MediaFields();
+
+ const TInt mediafieldcount( mediafieldArray.Count() );
+ for ( TInt index = 0; index < mediafieldcount; index++ )
+ {
+ GetRemoteCandidatesL( *mediafieldArray[index], aRemoteCands );
+ }
+
+ return KErrNone;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::GetRemoteCandidatesL
+// ---------------------------------------------------------------------------
+//
+TInt CNSPContentParser::GetRemoteCandidatesL( CSdpMediaField& aMediaField,
+ RPointerArray<CNATFWCandidate>& aRemoteCands ) const
+ {
+ const RPointerArray<CSdpAttributeField>& attributeArray =
+ aMediaField.AttributeFields();
+
+ const TInt attributecount( attributeArray.Count() );
+ for ( TInt index = 0; index < attributecount; index++ )
+ {
+ if ( iRemoteCandidates == attributeArray[index]->Attribute() )
+ {
+ DecodeRemoteCandidatesL( attributeArray[index]->Value(),
+ aRemoteCands );
+ }
+ }
+
+ return KErrNone;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::GetCredentialsL
+// ---------------------------------------------------------------------------
+//
+TInt CNSPContentParser::GetCredentialsL( CSdpMediaField& aMediaField,
+ CNATFWCredentials& aCredentials ) const
+ {
+ const RPointerArray<CSdpAttributeField>& attributeArray =
+ aMediaField.AttributeFields();
+
+ const TInt attributecount( attributeArray.Count() );
+ for ( TInt index = 0; index < attributecount; index++ )
+ {
+ if ( iUfrag == attributeArray[index]->Attribute() )
+ {
+ DecodeUfragL( *attributeArray[index], aCredentials );
+ }
+ else if ( iPwd == attributeArray[index]->Attribute() )
+ {
+ DecodePwdL( *attributeArray[index], aCredentials );
+ }
+ else
+ {
+ // Nothing to do here
+ }
+ }
+
+ return KErrNone;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::GetCredentialsL
+// ---------------------------------------------------------------------------
+//
+TInt CNSPContentParser::GetCredentialsL( CSdpDocument& aDocument,
+ CNATFWCredentials& aCredentials ) const
+ {
+ const RPointerArray<CSdpAttributeField>& attributeArray =
+ aDocument.AttributeFields();
+
+ const TInt attributecount( attributeArray.Count() );
+ for ( TInt index = 0; index < attributecount; index++ )
+ {
+ if ( iUfrag == attributeArray[index]->Attribute() )
+ {
+ DecodeUfragL( *attributeArray[index], aCredentials );
+ }
+ else if ( iPwd == attributeArray[index]->Attribute() )
+ {
+ DecodePwdL( *attributeArray[index], aCredentials );
+ }
+ else
+ {
+ // Nothing to do here
+ }
+ }
+
+ return KErrNone;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::RemoveIceContent
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::RemoveIceContent( CSdpDocument& aDocument ) const
+ {
+ RPointerArray<CSdpAttributeField>& attributes = aDocument.AttributeFields();
+
+ for ( TInt index = 0; index < attributes.Count() ; )
+ {
+ RStringF attribute = attributes[index]->Attribute();
+
+ if ( iCandidate == attribute ||
+ iRemoteCandidates == attribute ||
+ iLite == attribute ||
+ iPassive == attribute ||
+ iUfrag == attribute ||
+ iPwd == attribute ||
+ iMismatch == attribute )
+ {
+ delete ( attributes[index] );
+ attributes.Remove( index );
+ attributes.Compress();
+ }
+ else
+ {
+ index++;
+ }
+ }
+
+ RPointerArray<CSdpMediaField>& mediafields = aDocument.MediaFields();
+
+ const TInt mediafieldcount( mediafields.Count() );
+ for ( TInt index = 0; index < mediafieldcount ; index++ )
+ {
+ RemoveIceContent( *mediafields[index] );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::RemoveIceContent
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::RemoveIceContent( CSdpMediaField& aMediaField ) const
+ {
+ RPointerArray<CSdpAttributeField>& attributes = aMediaField.AttributeFields();
+
+ for ( TInt index = 0; index < attributes.Count() ; )
+ {
+ RStringF attribute = attributes[index]->Attribute();
+
+ if ( iCandidate == attribute ||
+ iRemoteCandidates == attribute ||
+ iLite == attribute ||
+ iPassive == attribute ||
+ iUfrag == attribute ||
+ iPwd == attribute ||
+ iMismatch == attribute )
+ {
+ delete ( attributes[index] );
+ attributes.Remove( index );
+ attributes.Compress();
+ }
+ else
+ {
+ index++;
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::EncodeCandidateLineL
+// ---------------------------------------------------------------------------
+//
+CSdpAttributeField* CNSPContentParser::EncodeCandidateLineL(
+ const CNATFWCandidate& aCandidate ) const
+ {
+ HBufC8* content = HBufC8::NewLC( KMaxCandidateLength );
+ TPtr8 ptr( content->Des() );
+
+ // 1. Foundation
+ AppendTDesC8ToTDes8L( ptr, aCandidate.Foundation() );
+
+ // 2. Component Id
+ AppendNumToTDes8L( ptr, aCandidate.ComponentId() );
+
+ // 3. Protocol
+ AppendProtocolToTDes8L( ptr, aCandidate.TransportProtocol() );
+
+ // 4. Priority
+ AppendNumToTDes8L( ptr, aCandidate.Priority() );
+
+ // 5. IP address & Port
+ AppendTDesC8ToTDes8L( ptr, aCandidate.TransportDomainAddr() );
+ AppendNumToTDes8L( ptr, aCandidate.TransportDomainPort() );
+
+ // 6. Type
+ AppendTypeToTDes8L( ptr, aCandidate.Type(), EFalse );
+
+ // 7. Optional information, i.e. related address and etc.
+
+ CSdpAttributeField* attribute = CSdpAttributeField::NewL( iCandidate, *content );
+ CleanupStack::PopAndDestroy( content );
+
+ return attribute;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::DecodeCandidateLineL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::DecodeCandidateLineL(
+ const CSdpAttributeField& aAttribute, CNATFWCandidate& aCandidate ) const
+ {
+ TLex8 lex( aAttribute.Value() );
+ TUint unsignedInteger( 0 );
+
+ // 1. Foundation( char(s) )
+ aCandidate.SetFoundationL( lex.NextToken() );
+
+ // 2. Component Id( single digit )
+ LexTDesC8ToTUintL( lex.NextToken(), unsignedInteger );
+ aCandidate.SetComponentId( unsignedInteger );
+
+ // 3. Protocol( string: UDP, TCP )
+ TUint protocol( KProtocolInetUdp );
+ SolveTransportProtocolL( lex.NextToken(), protocol );
+ aCandidate.SetTransportProtocol( protocol );
+
+ // 4. Priority( multiple digits, positive large integer )
+ LexTDesC8ToTUintL( lex.NextToken(), unsignedInteger );
+ aCandidate.SetPriority( unsignedInteger );
+
+ // 5. IP address & Port
+ TPtrC8 address = lex.NextToken();
+ LexTDesC8ToTUintL( lex.NextToken(), unsignedInteger );
+ aCandidate.SetTransportDomainAddrL( address, unsignedInteger );
+
+ // 6. Type( typ "value" )
+ CNATFWCandidate::TCandidateType type;
+ TPtrC8 typ = lex.NextToken();
+ TPtrC8 value = lex.NextToken();
+ SolveCandidateTypeL( typ, value, type );
+ aCandidate.SetType( type );
+
+ // 7. Optional information, i.e. related address and etc.
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::EncodeRemoteCandidatesL
+// ---------------------------------------------------------------------------
+//
+CSdpAttributeField* CNSPContentParser::EncodeRemoteCandidatesL(
+ const RPointerArray<CNATFWCandidate>& aCandidates ) const
+ {
+ HBufC8* content = HBufC8::NewLC( KMaxCandidateLength );
+ TPtr8 ptr( content->Des() );
+
+ const TInt remotecandidatecount( aCandidates.Count() );
+ for ( TInt index = 0; index < remotecandidatecount; index++ )
+ {
+ EncodeRemoteCandidateL( ptr, *aCandidates[index] );
+ }
+
+ CSdpAttributeField* attribute = CSdpAttributeField::NewL(
+ iRemoteCandidates, *content );
+ CleanupStack::PopAndDestroy( content );
+ return attribute;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::EncodeRemoteCandidatesL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::EncodeRemoteCandidateL( TDes8& aBuffer,
+ const CNATFWCandidate& aCandidate ) const
+ {
+ // 1. Component Id( single digit )
+ AppendNumToTDes8L( aBuffer, aCandidate.ComponentId() );
+
+ // 2. IP address & Port
+ AppendTDesC8ToTDes8L( aBuffer, aCandidate.TransportDomainAddr() );
+ AppendNumToTDes8L( aBuffer, aCandidate.TransportDomainPort() );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::DecodeRemoteCandidatesL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::DecodeRemoteCandidatesL( const TDesC8& aValue,
+ RPointerArray<CNATFWCandidate>& aCandidates ) const
+ {
+ TLex8 lex( aValue );
+ TUint unsignedInteger( 0 );
+
+ CNATFWCandidate* candidate = CNATFWCandidate::NewLC();
+
+ // 1. Component Id( single digit )
+ LexTDesC8ToTUintL( lex.NextToken(), unsignedInteger );
+ candidate->SetComponentId( unsignedInteger );
+
+ // 2. IP address & Port
+ const TPtrC8 address = lex.NextToken();
+ LexTDesC8ToTUintL( lex.NextToken(), unsignedInteger );
+ candidate->SetTransportDomainAddrL( address, unsignedInteger );
+
+ User::LeaveIfError( aCandidates.Append( candidate ) );
+ CleanupStack::Pop( candidate );
+
+ if ( !lex.Eos() )
+ {
+ DecodeRemoteCandidatesL( lex.Remainder(), aCandidates );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::EncodeUfragL
+// ---------------------------------------------------------------------------
+//
+CSdpAttributeField* CNSPContentParser::EncodeUfragL(
+ const CNATFWCredentials& aCredentials ) const
+ {
+ CSdpAttributeField* attribute = NULL;
+ const TDesC8& username = aCredentials.Username();
+
+ if ( !username.Length() )
+ {
+ attribute = CSdpAttributeField::NewL( iUfrag, KAttrEmpty );
+ }
+ else
+ {
+ attribute = CSdpAttributeField::NewL( iUfrag, username );
+ }
+
+ return attribute;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::DecodeUfragL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::DecodeUfragL( const CSdpAttributeField& aAttribute,
+ CNATFWCredentials& aCredentials ) const
+ {
+ aCredentials.SetUsernameL( aAttribute.Value() );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::EncodePwdL
+// ---------------------------------------------------------------------------
+//
+CSdpAttributeField* CNSPContentParser::EncodePwdL(
+ const CNATFWCredentials& aCredentials ) const
+ {
+ CSdpAttributeField* attribute = NULL;
+ const TDesC8& password = aCredentials.Password();
+
+ if ( !password.Length() )
+ {
+ attribute = CSdpAttributeField::NewL( iPwd, KAttrEmpty );
+ }
+ else
+ {
+ attribute = CSdpAttributeField::NewL( iPwd, password );
+ }
+
+ return attribute;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::DecodePwdL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::DecodePwdL( const CSdpAttributeField& aAttribute,
+ CNATFWCredentials& aCredentials ) const
+ {
+ aCredentials.SetPasswordL( aAttribute.Value() );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::LexTDesC8ToTUintL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::LexTDesC8ToTUintL( const TDesC8& aDesC8,
+ TUint& aUint ) const
+ {
+ TLex8 lex8( aDesC8 );
+ User::LeaveIfError( lex8.Val( aUint, EDecimal ) );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::SolveTransportProtocolL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::SolveTransportProtocolL( const TDesC8& aDesC8,
+ TUint& aProto ) const
+ {
+ if ( !aDesC8.CompareF( iUdp.DesC() ) )
+ {
+ aProto = KProtocolInetUdp;
+ }
+ else if ( !aDesC8.CompareF( iTcp.DesC() ) )
+ {
+ aProto = KProtocolInetTcp;
+ }
+ else
+ {
+ User::Leave( KErrArgument );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::InputTDesC8ToTInetAddrL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::InputTDesC8ToTInetAddrL( const TDesC8& aDesC8,
+ TInetAddr& aAddress ) const
+ {
+ HBufC* buffer = HBufC::NewLC( aDesC8.Length() );
+ TPtr ptr( buffer->Des() );
+ ptr.Copy( aDesC8 );
+ User::LeaveIfError( aAddress.Input( buffer->Des() ) );
+ CleanupStack::PopAndDestroy( buffer );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::SolveCandidateTypeL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::SolveCandidateTypeL( const TDesC8& aDesC8Typ,
+ const TDesC8& aDesC8Value, CNATFWCandidate::TCandidateType& aType ) const
+ {
+ TPtrC8 type( CandidateTypeArray[ KTypeAttrIndexType ] );
+ User::LeaveIfError( !aDesC8Typ.CompareF( type ) );
+
+ const TInt candidatetypeindex = FindCandidateType( aDesC8Value );
+
+ if ( KErrNotFound == candidatetypeindex )
+ {
+ NSPLOG_STR(
+ "CNSPContentParser::SolveCandidateTypeL(),KErrNotFound" )
+ User::Leave( KErrArgument );
+ }
+
+ switch ( candidatetypeindex )
+ {
+ case KTypeAttrIndexHost:
+ case KTypeAttrIndexLocal:
+ {
+ aType = CNATFWCandidate::EHost;
+ break;
+ }
+
+ case KTypeAttrIndexServerReflex:
+ {
+ aType = CNATFWCandidate::EServerReflexive;
+ break;
+ }
+
+ case KTypeAttrIndexPeerReflex:
+ {
+ aType = CNATFWCandidate::EPeerReflexive;
+ break;
+ }
+
+ case KTypeAttrIndexRelay:
+ {
+ aType = CNATFWCandidate::ERelay;
+ break;
+ }
+
+ default:
+ {
+ NSPLOG_STR(
+ "CNSPContentParser::SolveCandidateTypeL(),default!" )
+ User::Leave( KErrArgument ); // should never come here
+ break;
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::FindCandidateType
+// ---------------------------------------------------------------------------
+//
+TInt CNSPContentParser::FindCandidateType( const TDesC8& aDesC8Value ) const
+ {
+ for ( TInt index = 0; index < KTypeAttrNumber; index++ )
+ {
+ if ( !aDesC8Value.CompareF( TPtrC8( CandidateTypeArray[index] ) ) )
+ {
+ return index;
+ }
+ }
+
+ return KErrNotFound;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::FindCandidateType
+// ---------------------------------------------------------------------------
+//
+TInt CNSPContentParser::FindCandidateTypeString(
+ const CNATFWCandidate::TCandidateType& aType ) const
+ {
+ switch ( aType )
+ {
+ case CNATFWCandidate::EHost:
+ {
+ return KTypeAttrIndexHost;
+ }
+
+ case CNATFWCandidate::EServerReflexive:
+ {
+ return KTypeAttrIndexServerReflex;
+ }
+
+ case CNATFWCandidate::EPeerReflexive:
+ {
+ return KTypeAttrIndexPeerReflex;
+ }
+
+ case CNATFWCandidate::ERelay:
+ {
+ return KTypeAttrIndexRelay;
+ }
+
+ default:
+ {
+ return KErrNotFound;
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::AppendTDesC8ToTDes8L
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::AppendTDesC8ToTDes8L( TDes8& aDes8,
+ const TDesC8& aDesC8, TBool aAddFieldSeparator ) const
+ {
+ LeaveIfTooLongL( aDes8, aDesC8.Length() );
+ aDes8.Append( aDesC8 );
+
+ if ( aAddFieldSeparator )
+ {
+ LeaveIfTooLongL( aDes8, 1 );
+ aDes8.Append( KFieldSeparator );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::AppendNumToTDes8L
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::AppendNumToTDes8L( TDes8& aDes8,
+ TUint aNumber, TBool aAddFieldSeparator ) const
+ {
+ TBuf< KMaxLengthNumberConversion > buffer;
+ buffer.AppendNum( aNumber, EDecimal );
+ LeaveIfTooLongL( aDes8, buffer.Length() );
+ aDes8.AppendNum( aNumber, EDecimal );
+
+ if ( aAddFieldSeparator )
+ {
+ LeaveIfTooLongL( aDes8, 1 );
+ aDes8.Append( KFieldSeparator );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::AppendProtocolToTDes8L
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::AppendProtocolToTDes8L( TDes8& aDes8,
+ const TUint& aProtocol, TBool aAddFieldSeparator ) const
+ {
+ LeaveIfTooLongL( aDes8, Max( iUdp.DesC().Length(), iTcp.DesC().Length() ) );
+
+ if ( KProtocolInetUdp == aProtocol )
+ {
+ aDes8.Append( iUdp.DesC() );
+ }
+ else if ( KProtocolInetTcp == aProtocol )
+ {
+ aDes8.Append( iTcp.DesC() );
+ }
+ else // EUndefined
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ if ( aAddFieldSeparator )
+ {
+ LeaveIfTooLongL( aDes8, 1 );
+ aDes8.Append( KFieldSeparator );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::AppendTInetAddrToTDes8L
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::AppendTInetAddrToTDes8L( TDes8& aDes8,
+ const TInetAddr& aAddress, TBool aAddFieldSeparator ) const
+ {
+ TBuf<KMaxLengthTInetAddr> buffer;
+ aAddress.Output( buffer );
+ LeaveIfTooLongL( aDes8, buffer.Length() );
+ aDes8.Append( buffer );
+
+ if ( aAddFieldSeparator )
+ {
+ LeaveIfTooLongL( aDes8, 1 );
+ aDes8.Append( KFieldSeparator );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::AppendTypeToTDes8L
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::AppendTypeToTDes8L( TDes8& aDes8,
+ const CNATFWCandidate::TCandidateType& aType,
+ TBool aAddFieldSeparator ) const
+ {
+ const TInt candidatetypeindex = FindCandidateTypeString( aType );
+
+ if ( KErrNotFound != candidatetypeindex )
+ {
+ TPtrC8 type( CandidateTypeArray[ KTypeAttrIndexType ] );
+ TPtrC8 value( CandidateTypeArray[ candidatetypeindex ] );
+
+ LeaveIfTooLongL( aDes8, type.Length() +
+ KFieldSeparator().Length() + value.Length() );
+
+ aDes8.Append( type );
+ aDes8.Append( KFieldSeparator );
+ aDes8.Append( value );
+
+ if ( aAddFieldSeparator )
+ {
+ LeaveIfTooLongL( aDes8, 1 );
+ aDes8.Append( KFieldSeparator );
+ }
+ }
+ else
+ {
+ NSPLOG_STR(
+ "CNSPContentParser::AppendTypeToTDes8L(),KErrNotFound!" )
+ User::Leave( KErrArgument );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::LeaveIfTooLongL
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::LeaveIfTooLongL( const TDes8& aDes8,
+ const TInt aLength ) const
+ {
+ const TInt free = aDes8.MaxLength() - aDes8.Length();
+
+ if ( free < aLength )
+ {
+ User::Leave( KErrTooBig );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::FindMediaField
+// ---------------------------------------------------------------------------
+//
+CSdpMediaField* CNSPContentParser::FindMediaField( const CSdpMediaField& aMediaField,
+ const RPointerArray<CSdpMediaField>& aMediaFields ) const
+ {
+ const TInt mediafieldscount( aMediaFields.Count() );
+ for ( TInt index = 0; index < mediafieldscount; index++ )
+ {
+ if ( aMediaFields[index]->Media() == aMediaField.Media() )
+ {
+ return aMediaFields[index];
+ }
+ }
+
+ return NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// CNSPContentParser::CleanupArrayItem
+// ---------------------------------------------------------------------------
+//
+void CNSPContentParser::CleanupArrayItem( TAny* anArray )
+ {
+ if ( anArray )
+ {
+ reinterpret_cast< RPointerArray<CNATFWCandidate>* >( anArray )->
+ ResetAndDestroy();
+ reinterpret_cast< RPointerArray<CNATFWCandidate>* >( anArray )->
+ Close();
+ }
+ }
+
+
+// end of file