/*
* Copyright (c) 2006-2010 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: Provides static utility functions for SVP
*
*/
// #include <WlanInternalPSKeys.h>
#include <sysutil.h>
#include <sipprofile.h>
#include <CommonEngineDomainCRKeys.h> // for accept-language -header
#include <centralrepository.h> // for language code
#include <settingsinternalcrkeys.h> // Settings UIs CR keys
#include <unsafprotocolscrkeys.h> // Keys for keep-alive value,ipappsrv_dom\nat_settings_api
#include <mceaudiocodec.h>
#include <mceamrcodec.h>
#include <mceg711codec.h>
#include <mceilbccodec.h>
#include <mcecodec.h>
#include <mcedtmfcodec.h>
#include <mceamrwbcodec.h>
#include <mcertpsource.h>
#include <mcemicsource.h>
#include <mcertpsink.h>
#include <pathinfo.h>
#include <crcseprofileentry.h>
#include <crcseprofileregistry.h>
#include <crcseaudiocodecregistry.h>
#include <crcseaudiocodecentry.h>
#include "voipeventlog.h" // CVoipEventLog
#include "voiperrorentry.h" // CVoipErrorEntry
#include "cipapputilsaddressresolver.h" // CIPAppUtilsAddressResolver
#include "svputility.h"
#include "svplogger.h"
#include "svpsipconsts.h"
#include "svplanguagetagconsts.h"
#include "svpaudioutility.h"
// LOCAL CONSTANTS
// Default audio frame size in milliseconds for calculating jitterbuffer size
const TInt32 KJitterBufferFrameSize = 20;
// Constants for iLBC 20 and 30ms modes
const TUint32 KSvpilbcMode20ms = 20;
const TUint32 KSvpilbcMode30ms = 30;
// ---------------------------------------------------------------------------
// CSVPUtility::NewL
// ---------------------------------------------------------------------------
//
CSVPUtility* CSVPUtility::NewL()
{
CSVPUtility* self = new( ELeave ) CSVPUtility();
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
return self;
}
// ---------------------------------------------------------------------------
// CSVPUtility::ConstructL
// ---------------------------------------------------------------------------
//
void CSVPUtility::ConstructL()
{
SVPDEBUG1("CSVPUtility::ConstructL()");
iPreferredCodec = 0;
iRoundIndex = 0;
// create CVoipEventLog
TRAP_IGNORE( iVoipEventLogger = CVoipEventLog::NewL() );
}
// ---------------------------------------------------------------------------
// CSVPUtility::CSVPUtility
// ---------------------------------------------------------------------------
//
CSVPUtility::CSVPUtility()
{
SVPDEBUG1("CSVPUtility::CSVPUtility()");
}
// ---------------------------------------------------------------------------
// CSVPUtility::~CSVPUtility
// ---------------------------------------------------------------------------
//
CSVPUtility::~CSVPUtility()
{
SVPDEBUG1("CSVPUtility::~CSVPUtility()");
delete iVoipEventLogger;
}
// ---------------------------------------------------------------------------
// CSVPUtility::SetAudioCodecsMOL
// ---------------------------------------------------------------------------
//
void CSVPUtility::SetAudioCodecsMOL( TUint32 aVoIPProfileId,
CMceAudioStream& aAudioInStream,
TInt aKeepAliveValue )
{
SVPDEBUG1("CSVPUtility::SetAudioCodecsMOL: IN");
RArray< TUint32 > codecIds;
CleanupClosePushL( codecIds );
// clear codec priority preferrence variable
iPreferredCodec = 0;
CRCSEProfileEntry* profile = CRCSEProfileEntry::NewLC();
CRCSEAudioCodecEntry* codecprofile = CRCSEAudioCodecEntry::NewLC();
CRCSEProfileRegistry* rCSEProfile = CRCSEProfileRegistry::NewLC();
CRCSEAudioCodecRegistry* rCSEAudioCodec =
CRCSEAudioCodecRegistry::NewLC();
// Get VoIP profile from RCSE
rCSEProfile->FindL( aVoIPProfileId, *profile );
// fetch codec id's
GetCodecIdsByVoIPProfileIdL( *profile, codecIds );
TBool capabilitiesSet = EFalse;
// Set capabilities
for( TInt j = 0; j < codecIds.Count(); j++ )
{
rCSEAudioCodec->FindL( codecIds[ j ], *codecprofile );
if ( !codecprofile->iMediaSubTypeName.CompareF( KAudioCodecCN ) )
{
iCN = ETrue;
}
else
{
SVPDEBUG2("CSVPUtility::SetAudioCodecsMOL: j: %d", j);
MoCallCapabilitiesL( aAudioInStream,
*profile,
*codecprofile );
capabilitiesSet = ETrue;
}
}
// in Mo case, redundancy is never offered
iRed = EFalse;
if ( capabilitiesSet )
{
SetDtmfL( *profile, aAudioInStream );
}
SetMediaQoSL( profile->iMediaQOS, aAudioInStream.Session() );
// set comfort noise for PCMA/PCMU & ILBC if CN provisioned
// also handles keep alive logics
if ( iCN )
{
SetComfortNoiseL( aAudioInStream );
RemoveUnnecessaryCodecsL( aAudioInStream );
SetCNKeepAliveL( aAudioInStream, aKeepAliveValue );
}
else
{
RemoveUnnecessaryCodecsL( aAudioInStream );
SetKeepAliveL( aAudioInStream, aKeepAliveValue );
}
// Check RTCP for actual and bound stream as we do not have knowledge where
// the actual RTP sink is residing
CheckRtcpSettingL( profile->iRTCP, aAudioInStream );
if ( aAudioInStream.BoundStream() )
{
CheckRtcpSettingL( profile->iRTCP, aAudioInStream.BoundStreamL() );
}
// RCSE objects can be deleted
CleanupStack::PopAndDestroy( 5, &codecIds );
// Leave if codec information was not found.
if ( !aAudioInStream.Codecs().Count() )
{
SVPDEBUG1("CSVPUtility::SetAudioCodecsMOL KErrNotFound");
User::Leave( KErrNotFound );
}
SVPDEBUG1("CSVPUtility::SetAudioCodecsMOL: OUT");
}
// ---------------------------------------------------------------------------
// CSVPUtility::SetKeepAliveL
// ---------------------------------------------------------------------------
//
void CSVPUtility::SetKeepAliveL( CMceAudioStream& aAudioStream,
TInt aKeepAliveValue )
{
SVPDEBUG1( "CSVPUtility::SetKeepAliveL In ")
TInt count = aAudioStream.Codecs().Count();
SVPDEBUG2( "CSVPUtility::SetKeepAliveL Codec count: %d ", count )
// values should be set to bound stream also
CMceAudioStream& boundStream =
static_cast< CMceAudioStream& > ( aAudioStream.BoundStreamL() );
__ASSERT_ALWAYS( &boundStream, User::Leave( KSVPErrCodecMismatch ) );
// Amount of codecs should be the same in audio- and boundstreams
__ASSERT_ALWAYS( count == boundStream.Codecs().Count(),
User::Leave( KSVPErrCodecMismatch ) );
TInt maxPl( 0 );
TInt minPl( 0 );
// first check the max payload in the codec set
while ( count-- )
{
minPl = aAudioStream.Codecs()[ count ]->PayloadType();
if ( minPl > maxPl )
{
maxPl = minPl;
}
}
count = aAudioStream.Codecs().Count();
// if max pl less than def 120, set 120 as pl
if ( KSVPDefKeepAlivePl > maxPl )
{
while( count-- )
{
SVPDEBUG1( "CSVPUtility::SetKeepAliveL A ")
aAudioStream.Codecs()[ count ]->SetKeepAlivePayloadTypeL( KSVPDefKeepAlivePl );
aAudioStream.Codecs()[ count ]->SetKeepAliveDataL( KNullDesC8 );
aAudioStream.Codecs()[ count ]->SetKeepAliveTimerL( aKeepAliveValue );
boundStream.Codecs()[ count ]->SetKeepAlivePayloadTypeL( KSVPDefKeepAlivePl );
boundStream.Codecs()[ count ]->SetKeepAliveDataL( KNullDesC8 );
boundStream.Codecs()[ count ]->SetKeepAliveTimerL( aKeepAliveValue );
}
}
else if ( KSVPDefKeepAlivePlMax > maxPl )
{
while( count-- )
{
SVPDEBUG1( "CSVPUtility::SetKeepAliveL B ")
aAudioStream.Codecs()[ count ]->SetKeepAlivePayloadTypeL( maxPl + 1 );
aAudioStream.Codecs()[ count ]->SetKeepAliveDataL( KNullDesC8 );
aAudioStream.Codecs()[ count ]->SetKeepAliveTimerL( aKeepAliveValue );
boundStream.Codecs()[ count ]->SetKeepAlivePayloadTypeL( maxPl + 1 );
boundStream.Codecs()[ count ]->SetKeepAliveDataL( KNullDesC8 );
boundStream.Codecs()[ count ]->SetKeepAliveTimerL( aKeepAliveValue );
}
}
SVPDEBUG1( "CSVPUtility::SetKeepAliveL Out ")
}
// ---------------------------------------------------------------------------
// CSVPUtility::SetCNKeepAliveL
// ---------------------------------------------------------------------------
//
void CSVPUtility::SetCNKeepAliveL( CMceAudioStream& aAudioStream,
TInt aKeepAliveValue )
{
SVPDEBUG1( "CSVPUtility::SetCNKeepAliveL In ")
TInt count = aAudioStream.Codecs().Count();
SVPDEBUG2( "CSVPUtility::SetCNKeepAliveL Codec count: %d ", count )
TInt mostPreferred = 0;
// bound stream should be present always
CMceAudioStream& boundStream =
static_cast< CMceAudioStream& > ( aAudioStream.BoundStreamL() );
__ASSERT_ALWAYS( &boundStream, User::Leave( KSVPErrCodecMismatch ) );
// Amount of codecs should be the same in audio- and boundstreams
__ASSERT_ALWAYS( count == boundStream.Codecs().Count(),
User::Leave( KSVPErrCodecMismatch ) );
// find most preferred codec and set keepalive timer
// value and payload for most preferred codec
while( count-- )
{
const TDesC8& codec = aAudioStream.Codecs()[ count ]->SdpName();
// handle only real audio codecs
if ( KErrNotFound == codec.Find( KCN ) && KErrNotFound == codec.Find( KTELEVENT ) )
{
if ( 0 == aAudioStream.Codecs()[ count ]->Preference() )
{
SVPDEBUG2( "Most preferred codec: %d ", count )
SVPDEBUG2( "Payload: %d ", aAudioStream.Codecs()[ count ]->PayloadType() )
aAudioStream.Codecs()[ count ]->SetKeepAliveTimerL( aKeepAliveValue );
aAudioStream.Codecs()[ count ]->SetKeepAlivePayloadTypeL( KSVPCNPayloadType );
aAudioStream.Codecs()[ count ]->SetKeepAliveDataL( KNullDesC8 );
boundStream.Codecs()[ count ]->SetKeepAliveTimerL( aKeepAliveValue );
boundStream.Codecs()[ count ]->SetKeepAlivePayloadTypeL( KSVPCNPayloadType );
boundStream.Codecs()[ count ]->SetKeepAliveDataL( KNullDesC8 );
mostPreferred = count;
}
}
}
count = aAudioStream.Codecs().Count();
while ( count-- )
{
if ( mostPreferred != count )
{
SVPDEBUG2( "Timer value 0 for codec: %d ", count )
aAudioStream.Codecs()[ count ]->SetKeepAliveTimerL( 0 );
aAudioStream.Codecs()[ count ]->SetKeepAlivePayloadTypeL( KSVPCNPayloadType );
aAudioStream.Codecs()[ count ]->SetKeepAliveDataL( KNullDesC8 );
boundStream.Codecs()[ count ]->SetKeepAliveTimerL( 0 );
boundStream.Codecs()[ count ]->SetKeepAlivePayloadTypeL( KSVPCNPayloadType );
boundStream.Codecs()[ count ]->SetKeepAliveDataL( KNullDesC8 );
}
}
SVPDEBUG1( "CSVPUtility::SetCNKeepAliveL Out ")
}
// ---------------------------------------------------------------------------
// CSVPUtility::IsComfortNoise
// ---------------------------------------------------------------------------
//
TBool CSVPUtility::IsComfortNoise( CMceAudioStream& aStream )
{
SVPDEBUG1( "CSVPUtility::IsComfortNoise In ")
TInt count = aStream.Codecs().Count();
while ( count-- )
{
if ( !aStream.Codecs()[ count ]->SdpName().CompareF( KCN ) )
{
return ETrue;
}
}
return EFalse;
}
// ---------------------------------------------------------------------------
// CSVPUtility::SetAudioCodecsForEmergencyL
// ---------------------------------------------------------------------------
//
void CSVPUtility::SetAudioCodecsForEmergencyL(
CMceAudioStream& aAudioInStream,
TInt aKeepAliveValue,
TInt32 aVoipProfileId )
{
SVPDEBUG1("CSVPUtility::SetAudioCodecsForEmergencyL() In")
// clear codec priority preferrence variable
iPreferredCodec = 0;
// Default profile
CRCSEProfileEntry* profile = CRCSEProfileEntry::NewLC(); // CS:1
// Set codecs
if ( KErrNotFound == aVoipProfileId )
{
// No VoIP profile, use default profile values
SVPDEBUG1("CSVPUtility::SetAudioCodecsForEmergencyL, no VoIP profile")
// Create default codecs (PCMA, PCMU, AMR, iLBC, G729) and set
// capabilities
CRCSEAudioCodecEntry* codec = CRCSEAudioCodecEntry::NewLC(); // CS:2
codec->SetDefaultCodecValueSet( KAudioCodecPCMA() );
MoCallCapabilitiesL( aAudioInStream, *profile, *codec );
CleanupStack::PopAndDestroy( codec ); // CS:1
codec = CRCSEAudioCodecEntry::NewLC(); // CS:2
codec->SetDefaultCodecValueSet( KAudioCodecPCMU() );
MoCallCapabilitiesL( aAudioInStream, *profile, *codec );
CleanupStack::PopAndDestroy( codec ); // CS:1
codec = CRCSEAudioCodecEntry::NewLC(); // CS:2
codec->SetDefaultCodecValueSet( KAudioCodecAMR() );
MoCallCapabilitiesL( aAudioInStream, *profile, *codec );
CleanupStack::PopAndDestroy( codec ); // CS:1
codec = CRCSEAudioCodecEntry::NewLC(); // CS:2
codec->SetDefaultCodecValueSet( KAudioCodeciLBC() );
MoCallCapabilitiesL( aAudioInStream, *profile, *codec );
CleanupStack::PopAndDestroy( codec ); // CS:1
codec = CRCSEAudioCodecEntry::NewLC(); // CS:2
codec->SetDefaultCodecValueSet( KAudioCodecG729() );
MoCallCapabilitiesL( aAudioInStream, *profile, *codec );
CleanupStack::PopAndDestroy( codec ); // CS:1
}
else
{
// VoIP profile exists
SVPDEBUG1("CSVPUtility::SetAudioCodecsForEmergencyL, VoIP profile")
User::LeaveIfError( aVoipProfileId );
// Get codec IDs from profile
CRCSEProfileRegistry* profileRegistry =
CRCSEProfileRegistry::NewLC(); // CS:2
profileRegistry->FindL( aVoipProfileId, *profile );
CleanupStack::PopAndDestroy( profileRegistry ); // CS:1
RArray< TUint32 > codecIds;
CleanupClosePushL( codecIds ); // CS:2
GetCodecIdsByVoIPProfileIdL( *profile, codecIds );
// Set flags
TBool isSetPCMA( EFalse );
TBool isSetPCMU( EFalse );
// Set capabilities
CRCSEAudioCodecRegistry* codecRegistry =
CRCSEAudioCodecRegistry::NewLC(); // CS:3
CRCSEAudioCodecEntry* codec = NULL;
for( TInt j = 0; j < codecIds.Count(); j++ )
{
codec = CRCSEAudioCodecEntry::NewLC(); // CS:4
codecRegistry->FindL( codecIds[j], *codec );
MoCallCapabilitiesL( aAudioInStream, *profile, *codec );
// Check G711
if ( !codec->iMediaSubTypeName.CompareF( KAudioCodecPCMA ) )
{
isSetPCMA = ETrue;
}
if ( !codec->iMediaSubTypeName.CompareF( KAudioCodecPCMU ) )
{
isSetPCMU = ETrue;
}
CleanupStack::PopAndDestroy( codec ); // CS:3
}
CleanupStack::PopAndDestroy( codecRegistry ); // CS:2
CleanupStack::PopAndDestroy( &codecIds ); // CS:1
// Set G711 default capabilities if not set from profile
if ( !isSetPCMA )
{
codec = CRCSEAudioCodecEntry::NewLC(); // CS:2
codec->SetDefaultCodecValueSet( KAudioCodecPCMA() );
MoCallCapabilitiesL( aAudioInStream, *profile, *codec );
CleanupStack::PopAndDestroy( codec ); // CS:1
}
if ( !isSetPCMU )
{
codec = CRCSEAudioCodecEntry::NewLC(); // CS:2
codec->SetDefaultCodecValueSet( KAudioCodecPCMU() );
MoCallCapabilitiesL( aAudioInStream, *profile, *codec );
CleanupStack::PopAndDestroy( codec ); // CS:1
}
}
SetDtmfL( *profile, aAudioInStream );
SetMediaQoSL( profile->iMediaQOS, aAudioInStream.Session() );
// in Mo case, redundancy is never offered
iRed = EFalse;
// Set comfort noise for PCMA/PCMU & ILBC if CN provisioned and keep-alive
if ( iCN )
{
SetComfortNoiseL( aAudioInStream );
RemoveUnnecessaryCodecsL( aAudioInStream );
SetCNKeepAliveL( aAudioInStream, aKeepAliveValue );
}
else
{
RemoveUnnecessaryCodecsL( aAudioInStream );
SetKeepAliveL( aAudioInStream, aKeepAliveValue );
}
// Check RTCP for actual and bound stream as we do not have knowledge where
// the actual RTP sink is residing
CheckRtcpSettingL( profile->iRTCP, aAudioInStream );
if ( aAudioInStream.BoundStream() )
{
CheckRtcpSettingL( profile->iRTCP, aAudioInStream.BoundStreamL() );
}
CleanupStack::PopAndDestroy( profile ); // CS:0
// Leave if codec information was not found.
if ( !aAudioInStream.Codecs().Count() )
{
SVPDEBUG1("CSVPUtility::SetAudioCodecsForEmergencyL KErrNotFound")
User::Leave( KErrNotFound );
}
SVPDEBUG1("CSVPUtility::SetAudioCodecsForEmergencyL() Out")
}
// ---------------------------------------------------------------------------
// CSVPUtility::SetComfortNoiseL
// ---------------------------------------------------------------------------
//
void CSVPUtility::SetComfortNoiseL( CMceAudioStream& aAudioStream )
{
SVPDEBUG1("CSVPUtility::SetComfortNoiseL In");
// fetch available codecs
const RPointerArray<CMceAudioCodec>& codecs = aAudioStream.Codecs();
// Comfort Noise must be enabled for bound stream codecs also
CMceAudioStream& boundStream =
static_cast< CMceAudioStream& > ( aAudioStream.BoundStreamL() );
// fetch bound stream codecs
const RPointerArray< CMceAudioCodec >&
boundCodecs = boundStream.Codecs();
iCN = EFalse;
for ( TInt z = 0; z < codecs.Count(); z++ )
{
if ( !codecs[ z ]->SdpName().CompareF( KCN ) && !iCN )
{
SVPDEBUG1("CSVPUtility::SetComfortNoiseL CN found");
// enable CN from main and bound stream
aAudioStream.Codecs()[ z ]->SetStateL( CMceCodec::EEnabled );
boundStream.Codecs()[ z ]->SetStateL( CMceCodec::EEnabled );
// set flag to true, so CN is not removed from media attributes
iCN = ETrue;
// set also correct priority order for CN => lowest priority
aAudioStream.Codecs()[ z ]->SetPreferenceL( codecs.Count() );
}
}
if ( iCN )
{
for ( TInt i = 0; i < codecs.Count(); i++ )
{
if( !codecs[ i ]->SdpName().CompareF( KPCMA ) ||
!codecs[ i ]->SdpName().CompareF( KPCMU ) ||
!codecs[ i ]->SdpName().CompareF( KILBC ) )
{
SVPDEBUG1("CSVPUtility::SetComfortNoiseL Setting VAD");
codecs[ i ]->EnableVAD( ETrue );
boundCodecs[ i ]->EnableVAD( ETrue );
}
}
}
SVPDEBUG1("CSVPUtility::SetComfortNoiseL Out");
}
// ---------------------------------------------------------------------------
// CSVPUtility::SetDtmfL
// ---------------------------------------------------------------------------
//
void CSVPUtility::SetDtmfL( const CRCSEProfileEntry& aVoIPProfile,
CMceAudioStream& aAudioStream )
{
SVPDEBUG3( "CSVPUtility::SetDtmfL IB STATUS: %d OB STATUS: %d",
aVoIPProfile.iInbandDTMF, aVoIPProfile.iOutbandDTMF )
// If both on, not set or both off, prefer outband.
if ( ( CRCSEAudioCodecEntry::EOn == aVoIPProfile.iInbandDTMF &&
CRCSEAudioCodecEntry::EOn == aVoIPProfile.iOutbandDTMF ) ||
( CRCSEAudioCodecEntry::EOONotSet == aVoIPProfile.iInbandDTMF &&
CRCSEAudioCodecEntry::EOONotSet == aVoIPProfile.iOutbandDTMF ) ||
( CRCSEAudioCodecEntry::EOff == aVoIPProfile.iInbandDTMF &&
CRCSEAudioCodecEntry::EOff == aVoIPProfile.iOutbandDTMF ) )
{
SVPDEBUG1( "CSVPUtility::SetDtmfL IB/OB both enabled, not set or off" )
iTelEv = ETrue;
SetDtmfCodecOrderL( aAudioStream );
}
// Check inband enabled situation
else if ( CRCSEAudioCodecEntry::EOn == aVoIPProfile.iInbandDTMF &&
CRCSEAudioCodecEntry::EOff == aVoIPProfile.iOutbandDTMF )
{
SVPDEBUG1( "CSVPUtility::SetDtmfL OB DTMF OFF, IB DTMF ON" )
iTelEv = EFalse;
}
// Check outband enabled situation
else if ( CRCSEAudioCodecEntry::EOff == aVoIPProfile.iInbandDTMF &&
CRCSEAudioCodecEntry::EOn == aVoIPProfile.iOutbandDTMF )
{
SVPDEBUG1( "CSVPUtility::SetDtmfL OB DTMF ON, IB DTMF OFF" )
iTelEv = ETrue;
SetDtmfCodecOrderL( aAudioStream );
}
// else all cases handled above.
}
//----------------------------------------------------------------------------
// CSVPUtility::GetDTMFMode
//----------------------------------------------------------------------------
//
TBool CSVPUtility::GetDTMFMode()
{
SVPDEBUG2( "SVPUtility::GetDTMFMode iTelEv: %d", iTelEv )
return iTelEv; // EFalse: DTMF Inband, ETrue: DTMF Outband
}
//----------------------------------------------------------------------------
// CSVPUtility::SetDtmfMode
//----------------------------------------------------------------------------
//
void CSVPUtility::SetDtmfMode( TBool aOutbandEnabled )
{
SVPDEBUG2( "SVPUtility::SetDtmfMode aOutbandEnabled: %d",
aOutbandEnabled )
iTelEv = aOutbandEnabled;
}
// ---------------------------------------------------------------------------
// CSVPUtility::SetAudioCodecsMTL
// ---------------------------------------------------------------------------
//
void CSVPUtility::SetAudioCodecsMTL( CRCSEProfileEntry& aVoIPProfile,
CMceMediaStream& aAudioStream,
TInt aKeepAliveValue,
TBool aSessionUpdateOngoing )
{
SVPDEBUG1("CSVPUtility::SetAudioCodecsMTL In")
RArray< TUint32 > codecIds;
CleanupClosePushL( codecIds );
GetCodecIdsByVoIPProfileIdL( aVoIPProfile, codecIds );
// create codec profile
CRCSEAudioCodecEntry* codecprofile =
CRCSEAudioCodecEntry::NewLC();
CRCSEAudioCodecRegistry* rCSEAudioCodec =
CRCSEAudioCodecRegistry::NewLC();
// clearing the flag for next session
iCodecMatched = EFalse;
// Initialize round index variable (for the current session)
iRoundIndex = 0;
CMceAudioStream& audioStream =
static_cast<CMceAudioStream&>( aAudioStream );
const RPointerArray< CMceAudioCodec >& supportedCodecs =
audioStream.Codecs();
const TInt suppCodecCount = supportedCodecs.Count();
// loop as many times as needed
while ( iRoundIndex < suppCodecCount )
{
for ( TInt codecCnt = 0; codecCnt < codecIds.Count(); codecCnt++ )
{
if ( !iCodecMatched )
{
rCSEAudioCodec->FindL( codecIds[ codecCnt ], *codecprofile );
MtCallCapabilitiesL( audioStream, aVoIPProfile, *codecprofile );
}
}
if ( iCodecMatched )
{
SVPDEBUG1( "CSVPUtility::SetAudioCodecsMTL RED set" )
SetRedundancyL( audioStream );
SVPDEBUG1( "CSVPUtility::SetAudioCodecsMTL RED set done" )
break;
}
else
{
iRoundIndex++;
}
}
if ( !iCodecMatched )
{
User::Leave( KSVPErrCodecMismatch );
}
SetMediaQoSL( aVoIPProfile.iMediaQOS, aAudioStream.Session() );
// if outband DTMF offered, it's used even if inband is provisioned
if ( DtmfOBInOffer( audioStream ) )
{
SetDtmfCodecOrderL( audioStream );
iTelEv = ETrue;
}
else
{
SetDtmfL( aVoIPProfile, audioStream );
}
// set comfort noise if provisioned and offered by caller
for ( TInt codecCnt = 0; codecCnt < codecIds.Count(); codecCnt++ )
{
// fetch codec profile
rCSEAudioCodec->FindL( codecIds[ codecCnt ], *codecprofile );
// set comfort noise
HBufC8* tempSdpName =
HBufC8::NewLC( codecprofile->iMediaSubTypeName.Length() );
TPtr8 ptr = tempSdpName->Des();
ptr.Copy( codecprofile->iMediaSubTypeName );
if ( !tempSdpName->CompareF( KCN ) )
{
SVPDEBUG1( "CSVPUtility::SetAudioCodecsMTL - CN Provisioned" )
SetComfortNoiseL( audioStream );
}
CleanupStack::PopAndDestroy( tempSdpName );
}
RemoveUnnecessaryCodecsL( audioStream );
// CN provisioned and in offer
if ( iCN )
{
SVPDEBUG1( "CSVPUtility::SetAudioCodecsMTL - CN" )
SetCNKeepAliveL( audioStream, aKeepAliveValue );
}
// CN not provisioned or offered
else
{
SVPDEBUG1( "CSVPUtility::SetAudioCodecsMTL - No CN" )
SetKeepAliveL( audioStream, aKeepAliveValue );
}
// Check RTCP for actual and bound stream as we do not have knowledge where
// the actual RTP sink is residing
CheckRtcpSettingL( aVoIPProfile.iRTCP, aAudioStream, aSessionUpdateOngoing );
if ( aAudioStream.BoundStream() )
{
CheckRtcpSettingL( aVoIPProfile.iRTCP, aAudioStream.BoundStreamL(), aSessionUpdateOngoing );
}
// RCSE objects can be deleted
CleanupStack::PopAndDestroy( 3, &codecIds );
SVPDEBUG1( "CSVPUtility::SetAudioCodecsMTL Out" )
}
// ---------------------------------------------------------------------------
// CSVPUtility::DtmfOBInOffer
// ---------------------------------------------------------------------------
//
TBool CSVPUtility::DtmfOBInOffer( CMceAudioStream& aAudioStream )
{
SVPDEBUG1( "CSVPUtility::DtmfOBInOffer In" )
const RPointerArray< CMceAudioCodec >& supportedCodecs =
aAudioStream.Codecs();
TInt count = supportedCodecs.Count();
while ( count-- )
{
if ( !supportedCodecs[ count ]->SdpName().CompareF( KTELEVENT ) )
{
SVPDEBUG1( "CSVPUtility::DtmfOBInOffer Outband DTMF in offer" )
return ETrue;
}
}
return EFalse;
}
// ---------------------------------------------------------------------------
// CSVPUtility::RemoveUnnecessaryCodecsL
// ---------------------------------------------------------------------------
//
void CSVPUtility::RemoveUnnecessaryCodecsL( CMceAudioStream& aAudioInStream )
{
SVPDEBUG1("CSVPUtility::RemoveUnnecessaryCodecs In");
// if codec was not found, remove code from the codec array
if ( !iAMR )
{
SVPAudioUtility::RemoveCodecL( aAudioInStream, KAMR );
}
if ( !iPCMA )
{
SVPAudioUtility::RemoveCodecL( aAudioInStream, KPCMA );
}
if ( !iPCMU )
{
SVPAudioUtility::RemoveCodecL( aAudioInStream, KPCMU );
}
if ( !iILBC )
{
SVPAudioUtility::RemoveCodecL( aAudioInStream, KILBC );
}
if ( !iG729 )
{
SVPAudioUtility::RemoveCodecL( aAudioInStream, KG729 );
}
if ( !iTelEv )
{
SVPAudioUtility::RemoveCodecL( aAudioInStream, KTELEVENT );
}
if ( !iCN )
{
SVPAudioUtility::RemoveCodecL( aAudioInStream, KCN );
iCN = EFalse;
}
if ( !iRed )
{
SVPAudioUtility::RemoveCodecL( aAudioInStream, KRED );
}
if ( !iAMRWB )
{
SVPAudioUtility::RemoveCodecL( aAudioInStream, KAMRWB );
}
// clear codec flags for next session
iAMR = EFalse;
iPCMA = EFalse;
iPCMU = EFalse;
iILBC = EFalse;
iG729 = EFalse;
iRed = EFalse;
iAMRWB = EFalse;
SVPDEBUG1("CSVPUtility::RemoveUnnecessaryCodecs Out");
}
// ---------------------------------------------------------------------------
// CSVPUtility::GetCodecIdsByVoIPProfileIdL
// ---------------------------------------------------------------------------
//
void CSVPUtility::GetCodecIdsByVoIPProfileIdL(
const CRCSEProfileEntry& aProfile,
RArray< TUint32 >& aCodecIds ) const
{
SVPDEBUG1("CSVPUtility::GetCodecIdsByVoIPProfileIdL IN");
aCodecIds.Reset();
const TInt codCount = aProfile.iPreferredCodecs.Count();
for ( TInt codecCnt = 0; codecCnt < codCount; codecCnt++ )
{
// append codec id's in preference order
aCodecIds.AppendL( aProfile.iPreferredCodecs[ codecCnt ] );
}
SVPDEBUG1("CSVPUtility::GetCodecIdsByVoIPProfileIdL OUT");
}
// ---------------------------------------------------------------------------
// CSVPUtility::MtCallCapabilitiesL
// ---------------------------------------------------------------------------
//
void CSVPUtility::MtCallCapabilitiesL(
CMceAudioStream& aAudioInStream,
const CRCSEProfileEntry& aVoIPProfile,
const CRCSEAudioCodecEntry& aCodecProfile )
{
SVPDEBUG1( "CSVPUtility::MtCallCapabilitiesL IN" )
// fetch the codecs mce supports
const RPointerArray< CMceAudioCodec >& supportedCodecs =
aAudioInStream.Codecs();
SVPDEBUG2( "CSVPUtility::MtCallCapabilitiesL: Supp. codec count: %d",
supportedCodecs.Count() )
HBufC8* tempSdpName =
HBufC8::NewLC( aCodecProfile.iMediaSubTypeName.Length() );
TPtr8 ptr = tempSdpName->Des();
ptr.Copy( aCodecProfile.iMediaSubTypeName );
// compare offered codec to codec supported by app.
if ( *tempSdpName != supportedCodecs[ iRoundIndex ]->SdpName() ||
!supportedCodecs[ iRoundIndex ]->SdpName().CompareF( KCN ) ||
!supportedCodecs[ iRoundIndex ]->SdpName().CompareF( KTELEVENT ) ||
!supportedCodecs[ iRoundIndex ]->SdpName().CompareF( KRED ) )
{
SVPDEBUG1( "CSVPUtility::MtCallCapabilitiesL do nothing" )
}
else
{
SVPDEBUG2( "CSVPUtility::MtCallCapabilitiesL Mediasubtypename: %S",
&aCodecProfile.iMediaSubTypeName )
SVPDEBUG2( "CSVPUtility::MtCallCapabilitiesL - ptime: %d",
aCodecProfile.iPtime )
SVPDEBUG2( "CSVPUtility::MtCallCapabilitiesL - maxptime: %d",
aCodecProfile.iMaxptime )
if ( aVoIPProfile.iStartMediaPort )
{
aAudioInStream.SetLocalMediaPortL( aVoIPProfile.iStartMediaPort );
SVPDEBUG1( "CSVPUtility::MtCallCapabilitiesL start media port set" )
}
SVPDEBUG2( "CSVPUtility::MtCallCapabilitiesL codec ptime: %u",
supportedCodecs[ iRoundIndex ]->PTime() )
SVPDEBUG2( "CSVPUtility::MtCallCapabilitiesL codec maxptime: %u",
supportedCodecs[ iRoundIndex ]->MaxPTime() )
if ( aCodecProfile.iPtime >= 0 &&
aCodecProfile.iMaxptime <
supportedCodecs[ iRoundIndex ]->PTime() )
{
supportedCodecs[ iRoundIndex ]->SetPTime( aCodecProfile.iPtime );
}
if ( !aCodecProfile.iMediaSubTypeName.CompareF( KAudioCodecAMR ) )
{
// No actions taken in MT calls for AMR parameters. We accept
// them as-is for improved IOP.
iAMR = ETrue;
}
if ( !aCodecProfile.iMediaSubTypeName.CompareF( KAudioCodecPCMA ) )
{
iPCMA = ETrue;
}
if ( !aCodecProfile.iMediaSubTypeName.CompareF( KAudioCodecPCMU ) )
{
iPCMU = ETrue;
}
if ( !aCodecProfile.iMediaSubTypeName.CompareF( KAudioCodeciLBC ) )
{
iILBC = ETrue;
}
if ( !aCodecProfile.iMediaSubTypeName.CompareF( KAudioCodecAMRWB ) )
{
iAMRWB = ETrue;
}
if ( !aCodecProfile.iMediaSubTypeName.CompareF( KAudioCodecG729 ) )
{
// AnnexB is not set if it is not in the offer. MO side may not
// support AnnexB so we do not want to enforce it.
iG729 = ETrue;
}
else
{
// set VAD if other than G729 codec case
if ( CRCSEAudioCodecEntry::EOONotSet != aCodecProfile.iVAD )
{
SVPDEBUG1( "CSVPUtility::MtCallCapabilitiesL, codec and boundcodec VAD" );
// Setting VAD for codec
SetVADL( aAudioInStream, aCodecProfile.iVAD, *tempSdpName );
// Setting VAD also for bound codec
CMceAudioStream& boundStream =
static_cast< CMceAudioStream& > ( aAudioInStream.BoundStreamL() );
SetVADL( boundStream, aCodecProfile.iVAD, *tempSdpName );
}
}
// Take the largest jitterbuffer size from settings. NB. this does
// not actually take into account that we have codec spesific
// jitterbuffer sizes and MCE has session level jitterbuffer size.
// So we may end up using wrong jitterbuffer size if codec spesific
// jitterbuffer settings are different amongst each other.
if ( aCodecProfile.iJitterBufferSize > iJitterBufferSize )
{
iJitterBufferSize = aCodecProfile.iJitterBufferSize;
}
SVPDEBUG2( "CSVPUtility::MtCallCapabilitiesL iJitterBufferSize: %d",
iJitterBufferSize )
// set codec matched flag to ETrue, codec matched and set up
iCodecMatched = ETrue;
}
CleanupStack::PopAndDestroy( tempSdpName );
SVPDEBUG1( "CSVPUtility::MtCallCapabilitiesL OUT" )
}
// ---------------------------------------------------------------------------
// CSVPUtility::SetRedundancyL
// ---------------------------------------------------------------------------
//
void CSVPUtility::SetRedundancyL( CMceAudioStream& aAudioStream )
{
SVPDEBUG1( "CSVPUtility::SetRedundancyL In");
const RPointerArray< CMceAudioCodec >& codecs = aAudioStream.Codecs();
for ( TInt z = 0; z < codecs.Count(); z++ )
{
if ( !codecs[ z ]->SdpName().CompareF( KRED ) )
{
SVPDEBUG1( "CSVPUtility::SetRedundancyL Setting Red pref.");
// set preference
aAudioStream.Codecs()[ z ]->
SetPreferenceL( codecs.Count() );
// set red flag so red media attribute is not removed
iRed = ETrue;
}
}
SVPDEBUG1( "CSVPUtility::SetRedundancyL Out");
}
// ---------------------------------------------------------------------------
// CSVPUtility::MoCallCapabilitiesL
// ---------------------------------------------------------------------------
//
void CSVPUtility::MoCallCapabilitiesL(
CMceAudioStream& aAudioInStream,
const CRCSEProfileEntry& aVoIPProfile,
const CRCSEAudioCodecEntry& aCodecProfile )
{
SVPDEBUG1("CSVPUtility::MoCallCapabilitiesL In")
// fetch the codecs mce supports
const RPointerArray< CMceAudioCodec >& supportedCodecs =
aAudioInStream.Codecs();
SVPDEBUG2("CSVPUtility::MoCallCapabilitiesL, Supported codec count: %d",
supportedCodecs.Count() );
HBufC8* tempSdpName =
HBufC8::NewLC( aCodecProfile.iMediaSubTypeName.Length() );
SVPDEBUG2("CSVPUtility::MoCallCapabilitiesL Mediasubtypename: %S",
&aCodecProfile.iMediaSubTypeName );
// go through the array and find Sdp name match
for ( TInt z = 0; z < supportedCodecs.Count(); z++ )
{
TPtr8 ptr = tempSdpName->Des();
ptr.Copy( aCodecProfile.iMediaSubTypeName );
if ( *tempSdpName == supportedCodecs[ z ]->SdpName() )
{
// first setting audio capabilities common for all codecs
// set codec priority order
SVPDEBUG2("CSVPUtility::MoCallCapabilitiesL Codec order: %d",
iPreferredCodec );
supportedCodecs[ z ]->SetPreferenceL( iPreferredCodec++ );
// set media port
if ( aVoIPProfile.iStartMediaPort )
{
aAudioInStream.SetLocalMediaPortL( aVoIPProfile.iStartMediaPort );
SVPDEBUG1("CSVPUtility::MoCallCapabilitiesL start media port set");
}
// set VAD
if ( CRCSEAudioCodecEntry::EOONotSet != aCodecProfile.iVAD )
{
SVPDEBUG1( "CSVPUtility::MoCallCapabilitiesL Setting codec VAD" );
// Setting VAD for codec
SetVADL( aAudioInStream, aCodecProfile.iVAD, *tempSdpName );
SVPDEBUG1( "CSVPUtility::MoCallCapabilitiesL Setting bound VAD" );
// Setting VAD also for bound codec
CMceAudioStream& boundStream =
static_cast< CMceAudioStream& > ( aAudioInStream.BoundStreamL() );
SetVADL( boundStream, aCodecProfile.iVAD, *tempSdpName );
}
// set maxptime
if ( aCodecProfile.iMaxptime >= 0 )
{
supportedCodecs[ z ]->SetMaxPTime( aCodecProfile.iMaxptime );
SVPDEBUG2("CSVPUtility::MoCallCapabilitiesL iMaxptime: %d",
aCodecProfile.iMaxptime );
}
// set ptime
if ( aCodecProfile.iPtime >= 0 )
{
SVPDEBUG2("CSVPUtility::MoCallCapabilitiesL, PTime: %d",
aCodecProfile.iPtime );
supportedCodecs[ z ]->SetPTime( aCodecProfile.iPtime );
}
if ( !aCodecProfile.iMediaSubTypeName.CompareF( KAudioCodecAMR ) )
{
iAMR = ETrue;
// AMR specific settings: mode-set, mode-change-period,
// mode-change-neighbor and octet alignment vs. bw-efficient
// mode
SetAMRParameters( aAudioInStream, aCodecProfile, z );
if ( CRCSEAudioCodecEntry::EOn == aCodecProfile.iOctetAlign )
{
// use octet-alignment for MO call
supportedCodecs[ z ]->SetCodecMode(
EMceOctetAligned );
}
}
if ( !aCodecProfile.iMediaSubTypeName.
CompareF( KAudioCodecPCMA ) )
{
iPCMA = ETrue;
}
if ( !aCodecProfile.iMediaSubTypeName.
CompareF( KAudioCodecPCMU ) )
{
iPCMU = ETrue;
}
if ( !aCodecProfile.iMediaSubTypeName.
CompareF( KAudioCodeciLBC ) )
{
iILBC = ETrue;
// Set mode according to mode-set.
if ( aCodecProfile.iModeSet.Count() )
{
if ( KSvpilbcMode20ms == aCodecProfile.iModeSet[0] )
{
supportedCodecs[ z ]->SetBitrate(
KMceiLBCLevel20Bitrate );
}
else if( KSvpilbcMode30ms == aCodecProfile.iModeSet[0] )
{
supportedCodecs[ z ]->SetBitrate(
KMceiLBCLevel30Bitrate );
}
}
}
if ( !aCodecProfile.iMediaSubTypeName.
CompareF( KAudioCodecG729 ) )
{
iG729 = ETrue;
// set annexb
if ( CRCSEAudioCodecEntry::EOn == aCodecProfile.iAnnexb )
{
supportedCodecs[ z ]->EnableVAD( ETrue );
}
}
if ( !aCodecProfile.iMediaSubTypeName.CompareF( KAudioCodecAMRWB ) )
{
iAMRWB = ETrue;
// AMR-WB specific settings: mode-set, mode-change-period,
// mode-change-neighbor and octet alignment vs. bw-efficient
// mode
SetAmrWbParameters( aAudioInStream, aCodecProfile, z );
if ( CRCSEAudioCodecEntry::EOn == aCodecProfile.iOctetAlign )
{
// use octet-alignment for MO call
supportedCodecs[ z ]->SetCodecMode(
EMceOctetAligned );
}
}
// Take the largest jitterbuffer size from settings. NB. this does
// not actually take into account that we have codec spesific
// jitterbuffer sizes and MCE has session level jitterbuffer size.
// So we may end up using wrong jitterbuffer size if codec spesific
// jitterbuffer settings are different amongst each other.
if ( aCodecProfile.iJitterBufferSize > iJitterBufferSize )
{
iJitterBufferSize = aCodecProfile.iJitterBufferSize;
}
SVPDEBUG2( "CSVPUtility::MoCallCapabilitiesL iJitterBufferSize: %d",
iJitterBufferSize );
}
}
CleanupStack::PopAndDestroy( tempSdpName );
SVPDEBUG1( "CSVPUtility::MoCallCapabilitiesL OUT" );
}
// ---------------------------------------------------------------------------
// CSVPUtility::SetAMRParameters
// ---------------------------------------------------------------------------
//
void CSVPUtility::SetAMRParameters( CMceAudioStream& aAudioInStream,
const CRCSEAudioCodecEntry& aCodecProfile,
TInt aCodecNumber )
{
SVPDEBUG1( "CSVPUtility::SetAMRParameters Entry" )
TUint allowedBitrates( 0 );
// Set correct mode-set (default 0,1,2,3,4,5,6,7):
const RArray< TUint32 >& modeSetArray = aCodecProfile.iModeSet;
for ( TInt i = 0; i < modeSetArray.Count(); i++ )
{
TUint value = modeSetArray[ i ];
switch ( value )
{
case 0: { allowedBitrates |= KMceAllowedAmrNbBitrate475; break; }
case 1: { allowedBitrates |= KMceAllowedAmrNbBitrate515; break; }
case 2: { allowedBitrates |= KMceAllowedAmrNbBitrate590; break; }
case 3: { allowedBitrates |= KMceAllowedAmrNbBitrate670; break; }
case 4: { allowedBitrates |= KMceAllowedAmrNbBitrate740; break; }
case 5: { allowedBitrates |= KMceAllowedAmrNbBitrate795; break; }
case 6: { allowedBitrates |= KMceAllowedAmrNbBitrate102; break; }
case 7: { allowedBitrates |= KMceAllowedAmrNbBitrate122; break; }
}
SVPDEBUG3( "CSVPUtility::SetAMRParameters round %d, value: %u",
i, value )
SVPDEBUG2( "CSVPUtility::SetAMRParameters allowedBitrates 0x%x",
allowedBitrates )
}
if ( !allowedBitrates )
{
allowedBitrates = KMceAllowedAmrNbBitrateAll;
}
SVPDEBUG2( "CSVPUtility::SetAMRParameters mode-set 0x%x", allowedBitrates )
if ( 2 == aCodecProfile.iModeChangePeriod )
{
// Set correct mode-change-period (default == 1):
allowedBitrates |= KMceAllowedAmrNbChangePeriod2;
}
// Set correct mode-change-neighbor (default == 0)
if ( CRCSEAudioCodecEntry::EOn == aCodecProfile.iModeChangeNeighbor )
{
allowedBitrates |= KMceAllowedAmrNbChangeNeighbor1;
}
aAudioInStream.Codecs()[ aCodecNumber ]->SetAllowedBitrates(
allowedBitrates );
SVPDEBUG2( "CSVPUtility::SetAMRParameters, Exit 0x%x", allowedBitrates )
}
// ---------------------------------------------------------------------------
// CSVPUtility::GetCCPError
// ---------------------------------------------------------------------------
//
TCCPError CSVPUtility::GetCCPError( TInt& aErrorCode, TCCPTone& aTone ) const
{
SVPDEBUG2( "CSVPUtility::GetCCPError aErrorCode: %d", aErrorCode )
// See ccpdefs.h - this may require additional checking so that the
// tones are really correct.
TCCPError error = ECCPErrorNone;
TCCPTone tone = ECCPNoSoundSequence;
switch ( aErrorCode )
{
case KSVPDeclineVal:
case KSVPBusyHereVal:
case KSVPBusyEverywhereVal:
{
error = ECCPErrorBusy;
tone = ECCPToneUserBusy;
break;
}
case KSVPLoopDetectedVal:
case KSVPTooManyHopsVal:
case KSVPServerInternalErrorVal:
case KSVPNotImplementedVal:
case KSVPBadGatewayVal:
case KSVPServiceUnavailableVal:
case KSVPServerTimeoutVal:
case KSVPVersionNotSupportedVal:
case KSVPMessageTooLargeVal:
case KSVPPreconditionFailureVal:
{
error = ECCPErrorNetworkOutOfOrder;
tone = ECCPToneCongestion;
break;
}
case KSVPUseProxyVal:
case KSVPAlternativeServiceVal:
{
error = ECCPErrorNotReached;
tone = ECCPToneSpecialInformation;
break;
}
case KSVPRequestUriTooLongVal:
case KSVPUnsupportedUriSchemeVal:
case KSVPAddressIncompleteVal:
case KSVPAmbiguousVal:
{
error = ECCPErrorInvalidURI;
tone = ECCPToneSpecialInformation;
break;
}
case KSVPBadRequestVal:
case KSVPMethodNotAllowedVal:
case KSVPUnsupportedMediaTypeVal:
case KSVP406NotAcceptableVal:
case KSVPRequestEntityTooLargeVal:
case KSVPBadExtensionVal:
case KSVPExtensionRequiredVal:
case KSVPCallDoesNotExistVal:
case KSVPNotAcceptableHereVal:
case KSVPNotAcceptableVal:
{
error = ECCPErrorNotAcceptable;
tone = ECCPToneRadioPathNotAvailable;
break;
}
case KSVPRequestTerminatedVal:
case KSVPNotFoundVal:
case KSVPTemporarilyUnavailableVal:
{
error = ECCPErrorNotResponding;
tone = ECCPToneUserBusy;
break;
}
case KSVPMovedPermanentlyVal:
case KSVPGoneVal:
case KSVPDoesNotExistAnywhereVal:
{
error = ECCPErrorMovedPermanently;
tone = ECCPToneRadioPathNotAvailable;
break;
}
case KSVPRequestTimeoutVal:
{
error = ECCPErrorConnectionErrorRedial;
tone = ECCPToneSpecialInformation;
break;
}
case KSVPUnauthorizedVal:
case KSVPPaymentRequiredVal:
case KSVPForbiddenVal:
case KSVPProxyAuthenticationRequiredVal:
case KSVPIntervalTooBriefVal:
case KSVPBadEventVal:
case KSVPSecurityAgreementRequiredVal:
{
error = ECCPErrorNoService;
tone = ECCPToneCongestion;
break;
}
default:
{
if ( 299 < aErrorCode && 400 > aErrorCode )
{
// Received a 3XX response not handled above
error = ECCPErrorNotReached;
break;
}
else if ( 399 < aErrorCode && 500 > aErrorCode )
{
// Received a 4XX response not handled above
error = ECCPErrorNotAcceptable;
tone = ECCPToneRadioPathNotAvailable;
break;
}
else if ( 499 < aErrorCode && 600 > aErrorCode )
{
// Received a 5XX response not handled above
error = ECCPErrorNetworkOutOfOrder;
tone = ECCPToneCongestion;
break;
}
else if ( 599 < aErrorCode && 700 > aErrorCode )
{
// Received a 6XX response not handled above
error = ECCPGlobalFailure;
tone = ECCPToneUserBusy;
break;
}
else
{
SVPDEBUG1("CSVPUtility::GetCCPError Not an error code")
aErrorCode = KErrNone;
tone = ECCPNoSoundSequence;
break;
}
}
}
SVPDEBUG3( "CSVPUtility::GetCCPError error: %d, tone: %d",
error, tone )
aTone = tone;
return error;
}
// ---------------------------------------------------------------------------
// CSVPUtility::LogVoipEventL
// ---------------------------------------------------------------------------
//
void CSVPUtility::LogVoipEventL( TInt aErrorCode, TUint32 aSipProfileId,
const TDesC& aRemoteURI, const TDesC& aMethod ) const
{
SVPDEBUG1( "CSVPUtility::LogVoipEventL In" );
HBufC* remote = NULL;
if ( iVoipEventLogger )
{
// set the profile id and remote URI to the error text parameter
// tab is used as value delimiter
TBuf<KSVPTempStringlength> entryArguments;
entryArguments.AppendNum( aSipProfileId );
entryArguments.Append( KSVPLogFieldDelimiter );
// parse "sip:" away from the remote address
if ( aRemoteURI.Length() > 0 )
{
remote = aRemoteURI.AllocLC();
if ( 0 == remote->Find( KSVPSipPrefix2 ) )
{
remote->Des().Delete( 0, KSVPSipPrefixLength );
}
entryArguments.Append( *remote );
CleanupStack::PopAndDestroy( remote );
}
else
{
entryArguments.Append( aRemoteURI );
}
entryArguments.Append( KSVPLogFieldDelimiter );
entryArguments.Append( aMethod );
CVoipErrorEntry* entry = CVoipErrorEntry::NewLC( aErrorCode,
entryArguments );
iVoipEventLogger->WriteError( *entry );
CleanupStack::PopAndDestroy( entry );
SVPDEBUG3( "CSVPUtility::LogVoipEventL: \
err: %d, aMethod: %S", aErrorCode, &aMethod );
}
SVPDEBUG1( "CSVPUtility::LogVoipEventL Out" );
}
// ---------------------------------------------------------------------------
// CSVPUtility::GetDtmfEvent
// ---------------------------------------------------------------------------
//
MCCPDTMFObserver::TCCPDtmfEvent CSVPUtility::GetDtmfEvent(
MMceDtmfObserver::TMceDtmfEvent aEvent,
TBool aDtmfStringSending )
{
SVPDEBUG1( "CSVPUtility::GetDtmfEvent In" )
MCCPDTMFObserver::TCCPDtmfEvent event = MCCPDTMFObserver::ECCPDtmfUnknown;
switch ( aEvent )
{
case MMceDtmfObserver::EDtmfSendStarted:
{
if ( aDtmfStringSending )
{
SVPDEBUG1( "CSVPUtility::GetDtmfEvent ECCPDtmfSequenceStart" )
event = MCCPDTMFObserver::ECCPDtmfSequenceStart;
}
else
{
SVPDEBUG1( "CSVPUtility::GetDtmfEvent ECCPDtmfManualStart" )
event = MCCPDTMFObserver::ECCPDtmfManualStart;
}
break;
}
case MMceDtmfObserver::EDtmfSendCompleted:
{
if ( aDtmfStringSending )
{
SVPDEBUG1( "CSVPUtility::GetDtmfEvent ECCPDtmfStringSendingCompleted" )
event = MCCPDTMFObserver::ECCPDtmfStringSendingCompleted;
}
// else NOP
break;
}
default:
{
// This block should never be reached.
SVPDEBUG1( "CSVPUtility::GetDtmfEvent default case!" )
event = MCCPDTMFObserver::ECCPDtmfUnknown;
break;
}
}
return event;
}
// ---------------------------------------------------------------------------
// CSVPUtility::SetProvisioningDataL
// ---------------------------------------------------------------------------
//
void CSVPUtility::SetProvisioningDataL( CRCSEProfileEntry& aVoipProfile,
CDesC8Array& aUserAgentHeaders,
TUint32& aSecurityStatus,
TBuf<KSVPMaxTerminalTypeLength>& aTerminalType,
TBuf<KSVPWlanMacAddressLength>& aWlanMACAddress ) const
{
SVPDEBUG1("CSVPUtility::SetProvisioningDataL In" );
// fetch security status
aSecurityStatus = aVoipProfile.iSecureCallPreference;
SVPDEBUG2("CSVPUtility::SetProvisioningDataL: aSecurityStatus = %d",
aSecurityStatus );
TBool terminalTypeEnabled = aVoipProfile.iSIPVoIPUAHTerminalType;
SVPDEBUG2("CSVPUtility::SetProvisioningDataL: terminalTypeEnabled = %d",
terminalTypeEnabled );
TBool wlanMacEnabled = aVoipProfile.iSIPVoIPUAHeaderWLANMAC;
SVPDEBUG2("CSVPUtility::SetProvisioningDataL: wlanMacEnabled = %d",
wlanMacEnabled );
// temp descriptor for user-agent header
TBuf< KSVPMaxUAFreeTextLength > uaHeaderFreeString;
// SIP VoIP User Agent header string
uaHeaderFreeString = aVoipProfile.iSIPVoIPUAHeaderString;
// UA header found, append header name
TBuf8<KSVPTempStringlength> userAgentString;
userAgentString.Append( KSVPUserAgent );
// add terminat type
if( terminalTypeEnabled )
{
userAgentString.Append( KSVPSpaceMark );
userAgentString.Append( aTerminalType );
SVPDEBUG2("CSVPUtility::SetProvisioningDataL: aTerminalType = %S",
&aTerminalType );
userAgentString.Append( KSVPSpaceMark );
}
// add wlan mac address
if( wlanMacEnabled )
{
userAgentString.Append( aWlanMACAddress );
SVPDEBUG2("CSVPUtility::SetProvisioningDataL: aWlanMACAddress = %S",
&aWlanMACAddress );
userAgentString.Append( KSVPSpaceMark );
}
// add free string
if( 0 != uaHeaderFreeString.Length() )
{
// append user agent header string part
userAgentString.Append( uaHeaderFreeString );
SVPDEBUG2("CSVPUtility::SetProvisioningDataL:\
uaHeaderFreeString = %S", &uaHeaderFreeString );
userAgentString.Append( KSVPSpaceMark );
}
// match language code and add to user-agent header
TInt langCode = User::Language();
TBuf< KSVPMaxLangCodeLength > languageTag;
if ( langCode > 0 )
{
SVPDEBUG2("CSVPUtility::SetProvisioningDataL\
Language code: %d", langCode );
MatchLanguageTags( langCode, languageTag );
if ( languageTag.Length() != 0 )
{
SVPDEBUG2("CSVPUtility::SetProvisioninDataL ISO\
stanard language code: %S", &languageTag );
// add language tag to user agent string
userAgentString.Append( KSVPOpeningBracket );
userAgentString.Append( languageTag );
userAgentString.Append( KSVPClosingBracket );
}
}
// add collected User-Agent string to header
aUserAgentHeaders.AppendL( userAgentString );
// add accept language header
TBuf8<KSVPAcceptLangStringLength> acceptLanguageString;
acceptLanguageString.Append( KSVPAcceptLanguage );
acceptLanguageString.Append( languageTag );
// add expires header
// add accept language header
TBuf8<KSVPExpiresHeaderLength> expiresHeaderString;
expiresHeaderString.Append( KSVPExpiresHeader );
expiresHeaderString.Append( KSVPExpires );
aUserAgentHeaders.AppendL( acceptLanguageString );
aUserAgentHeaders.AppendL( expiresHeaderString );
// Add Privacy header
TBuf8<KSVPPrivacyLength> privacyString;
privacyString.Append( KSVPPrivacy );
if ( IsCLIROnL() )
{
privacyString.Append( KSVPId );
}
else
{
privacyString.Append( KSVPNone );
}
aUserAgentHeaders.AppendL( privacyString );
}
// ---------------------------------------------------------------------------
// CSVPUtility::IsCLIROnL
// ---------------------------------------------------------------------------
//
TBool CSVPUtility::IsCLIROnL() const
{
TInt valueCLIR( KSVPClirOff );
TBool clirOn = EFalse;
CRepository* repository = NULL;
repository = CRepository::NewL( KCRUidRichCallSettings );
repository->Get( KRCSEClir, valueCLIR );
delete repository;
repository = NULL;
SVPDEBUG2("CSVPUtility::IsCLIROnL valueCLIR : %d", valueCLIR );
if ( KSVPClirOn == valueCLIR )
{
// 0 = KRCSEClirOff
clirOn = ETrue;
}
else
{
// 1 = KRCSEClirOn or 2 = KRCSEClirDefault
clirOn = EFalse;
}
SVPDEBUG2("CSVPUtility::IsCLIROnL returns %d", clirOn);
return clirOn;
}
// ---------------------------------------------------------------------------
// CSVPUtility::SetMoFromHeaderLC
// ---------------------------------------------------------------------------
//
HBufC8* CSVPUtility::SetMoFromHeaderLC( TUint aSecurityStatus )
{
HBufC8* fromheader = NULL;
if ( IsCLIROnL() )
{
SVPDEBUG1("CSVPMoSession::SetMoFromHeaderLC CLIR is ON");
if ( KSVPStatusNonSecure == aSecurityStatus )
{
fromheader = HBufC8::NewLC(KSVPMyAnonymousAddress.iTypeLength);
fromheader->Des().Append( KSVPMyAnonymousAddress );
}
else
{
fromheader = HBufC8::NewLC(KSVPMyAnonymousSecAddress.iTypeLength);
fromheader->Des().Append( KSVPMyAnonymousSecAddress );
}
}
else
{
SVPDEBUG1("CSVPMoSession::SetMoFromHeaderLC CLIR is OFF");
fromheader = HBufC8::NewLC(KSVPEmpty.iTypeLength);
fromheader->Des().Append( KSVPEmpty );
}
return fromheader;
}
// ---------------------------------------------------------------------------
// CSVPUtility::AddPPreferredIdentityToUserHeaders
// ---------------------------------------------------------------------------
//
void CSVPUtility::AddPPreferredIdentityToUserHeadersL(
CDesC8Array& aUserAgentHeaders, const TDesC8& aUri )
{
SVPDEBUG1( "CSVPUtility::AddPPreferredIdentityToUserHeadersL In" )
TBuf8<KSVPTempStringlength> pPreferredHeaderString;
pPreferredHeaderString.Append( KSVPPIdentity );
pPreferredHeaderString.Append( KSVPLeftBracketMark );
pPreferredHeaderString.Append( aUri );
pPreferredHeaderString.Append( KSVPRightBracketMark );
aUserAgentHeaders.AppendL( pPreferredHeaderString );
SVPDEBUG1( "CSVPUtility::AddPPreferredIdentityToUserHeadersL Out " )
}
// ---------------------------------------------------------------------------
// CSVPUtility::GetTerminalTypeL
// ---------------------------------------------------------------------------
//
void CSVPUtility::GetTerminalTypeL(
TBuf< KSVPMaxTerminalTypeLength >& aTerminalType )
{
// Using ipapputils functionality
TBuf<KSVPMaxTerminalTypeLength> terminalType (KNullDesC);
CIpAppPhoneUtils* libIpAppPhoneUtils = CIpAppPhoneUtils::NewLC();
libIpAppPhoneUtils->GetTerminalTypeL( terminalType );
CleanupStack::PopAndDestroy( libIpAppPhoneUtils );
aTerminalType.Copy( terminalType );
}
// ---------------------------------------------------------------------------
// CSVPUtility::GetWlanMACAddressL
// ---------------------------------------------------------------------------
//
void CSVPUtility::GetWlanMACAddressL(
TBuf< KSVPWlanMacAddressLength >& aWlanMACAddress )
{
// Using ipapputils functionality
TBuf8<KSVPWlanMacAddressLength> wlanMacAddress (KNullDesC8);
CIPAppUtilsAddressResolver* addressResolver =
CIPAppUtilsAddressResolver::NewLC();
TInt ret = addressResolver->GetWlanMACAddress( wlanMacAddress,
KSVPWlanMacAddressFrmt );
SVPDEBUG2("CSVPUtility::GetWlanMACAddressL ret: %d", ret );
CleanupStack::PopAndDestroy( addressResolver );
aWlanMACAddress.Copy( wlanMacAddress );
}
// ---------------------------------------------------------------------------
// CSVPUtility::ResolveSecurityMechanismL
// ---------------------------------------------------------------------------
//
void CSVPUtility::ResolveSecurityMechanismL( const CSIPProfile& aProfile,
TUint32& aSecureCallPreference )
{
const TDesC8* securityMechanism = NULL;
const TDesC8* sipUserAor = NULL;
const TDesC8* sipOutboundProxy = NULL;
const TDesC8* registeredContact = NULL;
aProfile.GetParameter( KSIPNegotiatedSecurityMechanism,
securityMechanism );
aProfile.GetParameter( KSIPUserAor,
sipUserAor );
aProfile.GetParameter( KSIPOutboundProxy,
KSIPServerAddress,
sipOutboundProxy );
aProfile.GetParameter( KSIPRegisteredContact,
KSIPServerAddress,
registeredContact );
if ( KErrNotFound == securityMechanism->Find( KSVPTLS ) &&
KErrNotFound == sipUserAor->Find( KSVPSipsPrefix ) &&
KErrNotFound == sipOutboundProxy->Find( KSVPSipsPrefix ) &&
KErrNotFound == registeredContact->Find( KSVPSipsPrefix ) )
{
SVPDEBUG1("CSVPUtility::ResolveSecurityMechanism:\
TLS not enabled (tls and sips: wasn't found)");
aSecureCallPreference = 0;
}
}
// ---------------------------------------------------------------------------
// CSVPUtility::MatchLanguageTags
// ---------------------------------------------------------------------------
//
void CSVPUtility::MatchLanguageTags( TInt aLanguageCode,
TDes& aLangMatch )
{
SVPDEBUG2("CSVPUtility::MatchLanguageTags Langcode: %d", aLanguageCode );
switch( aLanguageCode)
{
case ESVPLangEnglish:
{
SVPDEBUG1("CSVPUtility::MatchLanguageTags -> English");
aLangMatch.Copy( KSVPLanguageTagEn );
break;
}
case ESVPLangFrench:
{
aLangMatch.Copy( KSVPLanguageTagFr );
break;
}
case ESVPLangGerman:
{
aLangMatch.Copy( KSVPLanguageTagDe );
break;
}
case ESVPLangSpanish:
{
aLangMatch.Copy( KSVPLanguageTagEs );
break;
}
case ESVPLangItalian:
{
aLangMatch.Copy( KSVPLanguageTagIt );
break;
}
case ESVPLangSwedish:
{
aLangMatch.Copy( KSVPLanguageTagSv );
break;
}
case ESVPLangDanish:
{
aLangMatch.Copy( KSVPLanguageTagDa );
break;
}
case ESVPLangNorwegian:
{
aLangMatch.Copy( KSVPLanguageTagNo );
break;
}
case ESVPLangFinnish:
{
aLangMatch.Copy( KSVPLanguageTagFi );
break;
}
case ESVPLangAmerican:
{
aLangMatch.Copy( KSVPLanguageTagEn );
break;
}
case ESVPLangSwissFrench:
{
aLangMatch.Copy( KSVPLanguageTagFr );
break;
}
case ESVPLangSwissGerman:
{
aLangMatch.Copy( KSVPLanguageTagDe );
break;
}
case ESVPLangPortuguese:
{
aLangMatch.Copy( KSVPLanguageTagPt );
break;
}
case ESVPLangTurkish:
{
aLangMatch.Copy( KSVPLanguageTagTr );
break;
}
case ESVPLangIcelandic:
{
aLangMatch.Copy( KSVPLanguageTagIs );
break;
}
case ESVPLangRussian:
{
aLangMatch.Copy( KSVPLanguageTagRu );
break;
}
case ESVPLangHungarian:
{
aLangMatch.Copy( KSVPLanguageTagHu );
break;
}
case ESVPLangDutch:
{
aLangMatch.Copy( KSVPLanguageTagNl );
break;
}
case ESVPLangBelgianFlemish:
{
aLangMatch.Copy( KSVPLanguageTagNl );
break;
}
case ESVPLangAustralian:
{
aLangMatch.Copy( KSVPLanguageTagEn );
break;
}
case ESVPLangBelgianFrench:
{
aLangMatch.Copy( KSVPLanguageTagFr );
break;
}
case ESVPLangAustrian:
{
aLangMatch.Copy( KSVPLanguageTagDe );
break;
}
case ESVPLangNewZealand:
{
aLangMatch.Copy( KSVPLanguageTagEn );
break;
}
case ESVPLangInternationalFrench:
{
aLangMatch.Copy( KSVPLanguageTagFr );
break;
}
case ESVPLangCzech:
{
aLangMatch.Copy( KSVPLanguageTagCs );
break;
}
case ESVPLangSlovak:
{
aLangMatch.Copy( KSVPLanguageTagSk );
break;
}
case ESVPLangPolish:
{
aLangMatch.Copy( KSVPLanguageTagPl );
break;
}
case ESVPLangSlovenian:
{
aLangMatch.Copy( KSVPLanguageTagSl );
break;
}
case ESVPLangTaiwanChinese:
{
aLangMatch.Copy( KSVPLanguageTagTaiwaneseChinese );
break;
}
case ESVPLangHongKongChinese:
{
aLangMatch.Copy( KSVPLanguageTagHongKongChinese );
break;
}
case ESVPLangPrcChinese:
{
aLangMatch.Copy( KSVPLanguageTagChinese );
break;
}
case ESVPLangJapanese:
{
aLangMatch.Copy( KSVPLanguageTagJa );
break;
}
case ESVPLangThai:
{
aLangMatch.Copy( KSVPLanguageTagTh );
break;
}
case ESVPLangAfrikaans:
{
aLangMatch.Copy( KSVPLanguageTagAf );
break;
}
case ESVPLangAlbanian:
{
aLangMatch.Copy( KSVPLanguageTagSq );
break;
}
case ESVPLangAmharic:
{
aLangMatch.Copy( KSVPLanguageTagAm );
break;
}
case ESVPLangArabic:
{
aLangMatch.Copy( KSVPLanguageTagAr );
break;
}
case ESVPLangArmenian:
{
aLangMatch.Copy( KSVPLanguageTagHy );
break;
}
case ESVPLangTagalog:
{
aLangMatch.Copy( KSVPLanguageTagTl );
break;
}
case ESVPLangBelarussian:
{
aLangMatch.Copy( KSVPLanguageTagBe );
break;
}
case ESVPLangBengali:
{
aLangMatch.Copy( KSVPLanguageTagBn );
break;
}
case ESVPLangBulgarian:
{
aLangMatch.Copy( KSVPLanguageTagBg );
break;
}
case ESVPLangBurmese:
{
aLangMatch.Copy( KSVPLanguageTagMy );
break;
}
case ESVPLangCatalan:
{
aLangMatch.Copy( KSVPLanguageTagCa );
break;
}
case ESVPLangCroatian:
{
aLangMatch.Copy( KSVPLanguageTagHr );
break;
}
case ESVPLangCanadianEnglish:
case ESVPLangInternationalEnglish:
case ESVPLangSouthAfricanEnglish:
{
aLangMatch.Copy( KSVPLanguageTagEn );
break;
}
case ESVPLangEstonian:
{
aLangMatch.Copy( KSVPLanguageTagEt );
break;
}
case ESVPLangFarsi:
{
aLangMatch.Copy( KSVPLanguageTagFa );
break;
}
case ESVPLangCanadianFrench:
{
aLangMatch.Copy( KSVPLanguageTagCanadianFrench );
break;
}
case ESVPLangScotsGaelic:
{
aLangMatch.Copy( KSVPLanguageTagGd );
break;
}
case ESVPLangGeorgian:
{
aLangMatch.Copy( KSVPLanguageTagKa );
break;
}
case ESVPLangGreek:
{
aLangMatch.Copy( KSVPLanguageTagEl );
break;
}
case ESVPLangCyprusGreek:
{
aLangMatch.Copy( KSVPLanguageTagCyprusGreek );
break;
}
case ESVPLangGujarati:
{
aLangMatch.Copy( KSVPLanguageTagGu );
break;
}
case ESVPLangHebrew:
{
aLangMatch.Copy( KSVPLanguageTagHe );
break;
}
case ESVPLangHindi:
{
aLangMatch.Copy( KSVPLanguageTagHi );
break;
}
case ESVPLangIndonesian:
{
aLangMatch.Copy( KSVPLanguageTagId );
break;
}
case ESVPLangIrish:
{
aLangMatch.Copy( KSVPLanguageTagGa );
break;
}
case ESVPLangSwissItalian:
{
aLangMatch.Copy( KSVPLanguageTagSwissItalian );
break;
}
case ESVPLangKannada:
{
aLangMatch.Copy( KSVPLanguageTagKn );
break;
}
case ESVPLangKazakh:
{
aLangMatch.Copy( KSVPLanguageTagKk );
break;
}
case ESVPLangKhmer:
{
aLangMatch.Copy( KSVPLanguageTagKm );
break;
}
case ESVPLangKorean:
{
aLangMatch.Copy( KSVPLanguageTagKo );
break;
}
case ESVPLangLao:
{
aLangMatch.Copy( KSVPLanguageTagLo );
break;
}
case ESVPLangLatvian:
{
aLangMatch.Copy( KSVPLanguageTagLv );
break;
}
case ESVPLangLithuanian:
{
aLangMatch.Copy( KSVPLanguageTagLt );
break;
}
case ESVPLangMacedonian:
{
aLangMatch.Copy( KSVPLanguageTagMk );
break;
}
case ESVPLangMalay:
{
aLangMatch.Copy( KSVPLanguageTagMs );
break;
}
case ESVPLangMalayalam:
{
aLangMatch.Copy( KSVPLanguageTagMl );
break;
}
case ESVPLangMarathi:
{
aLangMatch.Copy( KSVPLanguageTagMr );
break;
}
case ESVPLangMoldavian:
{
aLangMatch.Copy( KSVPLanguageTagMo );
break;
}
case ESVPLangMongolian:
{
aLangMatch.Copy( KSVPLanguageTagMn );
break;
}
case ESVPLangNorwegianNynorsk:
{
aLangMatch.Copy( KSVPLanguageTagNorwegianNynorsk );
break;
}
case ESVPLangBrazilianPortuguese:
{
aLangMatch.Copy( KSVPLanguageTagBrazilianPortugese );
break;
}
case ESVPLangPunjabi:
{
aLangMatch.Copy( KSVPLanguageTagPa );
break;
}
case ESVPLangRomanian:
{
aLangMatch.Copy( KSVPLanguageTagRo );
break;
}
case ESVPLangSerbian:
{
aLangMatch.Copy( KSVPLanguageTagSr );
break;
}
case ESVPLangSinhalese:
{
aLangMatch.Copy( KSVPLanguageTagSi );
break;
}
case ESVPLangSomali:
{
aLangMatch.Copy( KSVPLanguageTagSo );
break;
}
case ESVPLangInternationalSpanish:
{
aLangMatch.Copy( KSVPLanguageTagEs );
break;
}
case ESVPLangLatinAmericanSpanish:
{
aLangMatch.Copy( KSVPLanguageTagAmericanSpanish );
break;
}
case ESVPLangSwahili:
{
aLangMatch.Copy( KSVPLanguageTagSw );
break;
}
case ESVPLangFinlandSwedish:
{
aLangMatch.Copy( KSVPLanguageTagFinlandSwedish );
break;
}
case ESVPLangReserved1:
{
aLangMatch.Copy( KSVPLanguageTagReserved );
break;
}
case ESVPLangTamil:
{
aLangMatch.Copy( KSVPLanguageTagTa );
break;
}
case ESVPLangTelugu:
{
aLangMatch.Copy( KSVPLanguageTagTe );
break;
}
case ESVPLangTibetan:
{
aLangMatch.Copy( KSVPLanguageTagBo );
break;
}
case ESVPLangTigrinya:
{
aLangMatch.Copy( KSVPLanguageTagTi );
break;
}
case ESVPLangCyprusTurkish:
{
aLangMatch.Copy( KSVPLanguageTagCyprusTurkish );
break;
}
case ESVPLangTurkmen:
{
aLangMatch.Copy( KSVPLanguageTagTurkaem );
break;
}
case ESVPLangUkrainian:
{
aLangMatch.Copy( KSVPLanguageTagUk );
break;
}
case ESVPLangUrdu:
{
aLangMatch.Copy( KSVPLanguageTagUr );
break;
}
case ESVPLangReserved2:
{
aLangMatch.Copy( KSVPLanguageTagReserved );
break;
}
case ESVPLangVietnamese:
{
aLangMatch.Copy( KSVPLanguageTagVi );
break;
}
case ESVPLangWelsh:
{
aLangMatch.Copy( KSVPLanguageTagCy );
break;
}
case ESVPLangZulu:
{
aLangMatch.Copy( KSVPLanguageTagZu );
break;
}
case ESVPLangOther:
{
break;
}
case ESVPLangSouthSotho:
{
aLangMatch.Copy( KSVPLanguageTagSoth );
break;
}
case ESVPLangManufacturerEnglish:
case ESVPLangEnglish_Apac:
case ESVPLangEnglish_Taiwan:
case ESVPLangEnglish_HongKong:
case ESVPLangEnglish_Prc:
case ESVPLangEnglish_Japan:
case ESVPLangEnglish_Thailand:
{
aLangMatch.Copy( KSVPLanguageTagEn );
break;
}
case ESVPLangMalay_Apac:
{
aLangMatch.Copy( KSVPLanguageTagMalay );
break;
}
case ESVPLangNone:
case ESVPLangMaximum:
{
SVPDEBUG1("CSVPUtility::MatchLanguageTags Lang none/maximum");
break;
}
default:
{
SVPDEBUG1("CSVPUtility::MatchLanguageTags Default");
aLangMatch.Copy( KSVPLanguageTagEn );
}
}
}
// ---------------------------------------------------------------------------
// CSVPUtility::UpdateJitterBufferSizeL
// ---------------------------------------------------------------------------
//
void CSVPUtility::UpdateJitterBufferSizeL( CMceRtpSource& aRtpSource )
{
// Convert the jitterbuffer size from milliseconds to RTP packets. This
// does not take into account the fact that RTP packet can hold n
// milliseconds of audio. Also G.711 may use 10ms frames, so and we are
// assuming 20ms frames here. But, MCC actually has the logic to handle
// this issue, as it also assumes initially that G.711 has 20ms frames and
// then adjusts accordingly.
TInt32 jBufSize = KSvpJitterBufferLength;
if ( iJitterBufferSize )
{
jBufSize = iJitterBufferSize / KJitterBufferFrameSize;
}
SVPDEBUG2( "CSVPUtility::UpdateJitterBufferSizeL size: %d", jBufSize );
SVPDEBUG2( "CSVPUtility::UpdateJitterBufferSizeL iJitterBufferSize: %d",
iJitterBufferSize );
// If jitterbuffer size goes to zero, then force it back to default. We
// cannot tolerate zero size jitterbuffer.
if ( !jBufSize )
{
SVPDEBUG1( "CSVPUtility::UpdateJitterBufferSizeL need to default" )
jBufSize = KSvpJitterBufferLength;
}
aRtpSource.UpdateL( jBufSize,
KSvpJitterBufferThreshold,
KSvpStandbyTimerInMillisecs );
iJitterBufferSize = 0;
}
// ---------------------------------------------------------------------------
// CSVPUtility::SetDtmfCodecOrderL
// ---------------------------------------------------------------------------
//
void CSVPUtility::SetDtmfCodecOrderL( CMceAudioStream& aAudioStream ) const
{
SVPDEBUG1( "CSVPUtility::SetDtmfCodecOrderL In" );
const RPointerArray<CMceAudioCodec>& codecs = aAudioStream.Codecs();
const TInt codCount( codecs.Count() );
// loop through codecs in in stream
for ( TInt i = 0; i < codCount; i++ )
{
// Check if codec is DTMF, note the return values of CompareF
if( !codecs[ i ]->SdpName().CompareF( KTELEVENT ) )
{
codecs[ i ]->SetPreferenceL( iPreferredCodec );
}
}
SVPDEBUG1( "CSVPUtility::SetDtmfCodecOrderL Out" );
}
// ---------------------------------------------------------------------------
// CSVPUtility::SetMediaQoSL
// ---------------------------------------------------------------------------
//
void CSVPUtility::SetMediaQoSL( TUint32 aQosValue,
CMceSession* aSession ) const
{
SVPDEBUG2( "CSVPUtility::SetMediaQoSL aQosValue: %u", aQosValue );
__ASSERT_ALWAYS( aSession, User::Leave( KErrArgument ) );
// We need to do bitshifting on the IP TOS, because it's the upper 6 bits
// that are set and settings provide us the IP TOS as the lower 6 bits.
// The lower 2 bits are reserver for explicit congestion notification.
// See also more from:
// Symbian Developer Library / in_sock.h Global variables / KSoIpTOS
const TInt ipTosShift( 2 );
const TUint32 tosBits( aQosValue << ipTosShift );
SVPDEBUG2( "CSVPUtility::SetMediaQoSL tosBits: %u", tosBits );
aSession->SetServiceTypeL( tosBits );
SVPDEBUG1( "CSVPUtility::SetMediaQoSL out" );
}
// ---------------------------------------------------------------------------
// CSVPUtility::GetKeepAliveByIapIdL
// ---------------------------------------------------------------------------
//
TBool CSVPUtility::GetKeepAliveByIapIdL( TUint32 aIapId,
TInt& aKeepAliveValue ) const
{
SVPDEBUG2( "CSVPUtility::SetKeepAliveIapIdL IN, aIapId = %d", aIapId );
TBool found = EFalse;
TInt keepAliveValue = 0;
aKeepAliveValue = KSVPDefaultUDPRefreshInterval;
RArray< TUint32 > keys;
CleanupClosePushL( keys );
CRepository* rep = CRepository::NewLC( KCRUidUNSAFProtocols );
TInt err = rep->FindEqL( KUNSAFProtocolsIAPIdMask,
KUNSAFProtocolsFieldTypeMask,
static_cast<TInt>(aIapId),
keys );
if ( KErrNone == err && keys.Count() == 1 )
{
TUint32 key = ( KUNSAFProtocolsIAPIdMask^( keys[ 0 ] ) );
key |= KUNSAFProtocolsIAPTableMask;
// UDP refresh interval
SVPDEBUG2( "CSVPUtility::SetKeepAliveIapIdL UDP refresh interval key = %d", key );
if ( KErrNone == rep->Get( KUNSAFProtocolsIntervalUDPMask|key, keepAliveValue ) )
{
aKeepAliveValue = keepAliveValue;
found = ETrue;
}
}
CleanupStack::PopAndDestroy( 2, &keys ); // keys & rep
SVPDEBUG3( "CSVPUtility::SetKeepAliveIapIdL OUT keepAliveValue = %d found = %d",
keepAliveValue, found );
return found;
}
// ---------------------------------------------------------------------------
// CSVPUtility::GetKeepAliveByAORL
// ---------------------------------------------------------------------------
//
TBool CSVPUtility::GetKeepAliveByAORL( const TDesC8& aAor,
TInt& aKeepAliveValue ) const
{
SVPDEBUG1( "CSVPUtility::GetKeepAliveByAORL In" );
HBufC8* newAor = aAor.AllocLC();
// Domain name is what is after @ character
newAor->Des().Delete( 0, newAor->Find( KSVPAt ) + 1 );
TBool found = EFalse;
TInt keepAliveValue = 0;
aKeepAliveValue = KSVPDefaultUDPRefreshInterval;
RArray<TUint32> keys;
CleanupClosePushL( keys );
CRepository* rep = CRepository::NewLC( KCRUidUNSAFProtocols );
TInt err = rep->FindEqL( KUNSAFProtocolsDomainMask,
KUNSAFProtocolsFieldTypeMask,
*newAor,
keys );
if ( KErrNone == err && keys.Count() == 1 )
{
TUint32 key = ( KUNSAFProtocolsDomainMask^( keys[0] ) );
key |= KUNSAFProtocolsDomainTableMask;
// UDP refresh interval
if ( KErrNone ==
rep->Get( KUNSAFProtocolsDomainIntervalUDPMask|key, keepAliveValue ) )
{
aKeepAliveValue = keepAliveValue;
found = ETrue;
}
}
CleanupStack::PopAndDestroy( 3, newAor );
if ( !found )
{
// Neither IapId nor Domain spesific keepalive value was not found.
SVPDEBUG1( "CSVPUtility::GetKeepAliveByAORL::GetKeepAliveByAORL use default keepalive" );
aKeepAliveValue = KSVPDefaultUDPRefreshInterval;
}
SVPDEBUG2( "CSVPUtility::GetKeepAliveByAORL Out found: %d", found );
return found;
}
// ---------------------------------------------------------------------------
// CSVPUtility::CheckRtcpSettingL
// ---------------------------------------------------------------------------
//
void CSVPUtility::CheckRtcpSettingL( TUint32 aRtcp,
CMceMediaStream& aStream, TBool aSessionUpdateOngoing ) const
{
SVPDEBUG2( "CSVPUtility::CheckRtcpSettingL aRtcp: %u", aRtcp );
TBool rtcpsuppression = ETrue;
if ( CRCSEProfileEntry::EOn == aRtcp )
{
SVPDEBUG1("CSVPUtility::CheckRtcpSettingL RTCP=ON");
rtcpsuppression = EFalse;
}
// At this point we should have only audio streams. Thus the leave.
if ( KMceAudio == aStream.Type() )
{
if ( !aStream.Source()->IsEnabled() && aSessionUpdateOngoing )
{
aStream.Source()->EnableL();
}
const RPointerArray<CMceMediaSink>& sinks = aStream.Sinks();
const TInt snkCount = sinks.Count();
for ( TInt k = 0; k < snkCount; k++ )
{
if ( !sinks[k]->IsEnabled()&& aSessionUpdateOngoing )
{
sinks[k]->EnableL();
}
if ( KMceRTPSink == sinks[k]->Type() )
{
SVPDEBUG2( "CSVPUtility::CheckRtcpSettingL updating: %d", k );
static_cast<CMceRtpSink*>(
sinks[k] )->UpdateL( rtcpsuppression );
SVPDEBUG1( "CSspUtility::CheckRtcpSettingL update done" );
}
}
}
else
{
SVPDEBUG1( "CSspUtility::CheckRtcpSettingL KErrArgument" );
User::Leave( KErrArgument );
}
SVPDEBUG1( "CSspUtility::CheckRtcpSettingL Exit" );
}
// ---------------------------------------------------------------------------
// CSVPUtility::SetVADL
// ---------------------------------------------------------------------------
//
void CSVPUtility::SetVADL( CMceAudioStream& aInAudioStream,
TBool aVADSetting,
const TDesC8& aCodecName )
{
SVPDEBUG1( "CSVPUtility::SetVADL In" )
__ASSERT_ALWAYS( &aCodecName, User::Leave( KErrArgument ) );
if ( &aInAudioStream )
{
CMceAudioCodec* codec = SVPAudioUtility::FindCodec( aInAudioStream, aCodecName );
if ( codec )
{
SVPDEBUG2( "CSVPUtility aInAudioStream and codec valid, setting VAD with %d", aVADSetting )
codec->EnableVAD( aVADSetting );
}
}
SVPDEBUG1( "CSVPUtility::SetVADL Out" )
}
// ---------------------------------------------------------------------------
// CSVPUtility::SetAmrWbParameters
// ---------------------------------------------------------------------------
//
void CSVPUtility::SetAmrWbParameters( CMceAudioStream& aAudioInStream,
const CRCSEAudioCodecEntry& aCodecProfile,
TInt aCodecNumber )
{
SVPDEBUG1( "CSVPUtility::SetAmrWbParameters In" )
TUint allowedBitrates( 0 );
// Set correct mode-set
const RArray< TUint32 >& modeSetArray = aCodecProfile.iModeSet;
for ( TInt i = 0; i < modeSetArray.Count(); i++ )
{
TUint value = modeSetArray[ i ];
switch ( value )
{
case 0: { allowedBitrates |= KMceAllowedAmrWbBitrate660; break; }
case 1: { allowedBitrates |= KMceAllowedAmrWbBitrate885; break; }
case 2: { allowedBitrates |= KMceAllowedAmrWbBitrate1265; break; }
case 3: { allowedBitrates |= KMceAllowedAmrWbBitrate1425; break; }
case 4: { allowedBitrates |= KMceAllowedAmrWbBitrate1585; break; }
case 5: { allowedBitrates |= KMceAllowedAmrWbBitrate1825; break; }
case 6: { allowedBitrates |= KMceAllowedAmrWbBitrate1985; break; }
case 7: { allowedBitrates |= KMceAllowedAmrWbBitrate2305; break; }
case 8: { allowedBitrates |= KMceAllowedAmrWbBitrate2305; break; }
case 9: { allowedBitrates |= KMceAllowedAmrWbBitrate2385; break; }
default: { allowedBitrates |= KMceAllowedAmrWbBitrateAll; break; }
}
SVPDEBUG3( "SetAmrWbParameters round %d, value: %u",
i, value )
SVPDEBUG2( "SetAmrWbParameters allowedBitrates 0x%x",
allowedBitrates )
}
SVPDEBUG2( "SetAmrWbParameters mode-set 0x%x", allowedBitrates )
// Set correct mode-change-period (mode-change-period=1):
if ( 2 == aCodecProfile.iModeChangePeriod )
{
allowedBitrates |= KMceAllowedAmrWbModeChangePeriod2;
}
// Set correct mode-change-neighbor (mode-change-neighbor=0)
if ( CRCSEAudioCodecEntry::EOn == aCodecProfile.iModeChangeNeighbor )
{
allowedBitrates |= KMceAllowedAmrWbModeChangeNeighbor1;
}
aAudioInStream.Codecs()[ aCodecNumber ]->SetAllowedBitrates(
allowedBitrates );
SVPDEBUG2( "CSVPUtility::SetAmrWbParameters Out, 0x%x", allowedBitrates )
}
// EOF