/*
* 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: Connection multiplexer session abstraction.
*
*/
#include <commdbconnpref.h>
#include <e32math.h>
#include <es_sock_partner.h>
#include "cncmsession.h"
#include "cncmstream.h"
#include "cncmconnection.h"
#include "cncmconnectionobserverhandler.h"
#include "cncmlocaladdressresolver.h"
//#include "cncmicmpreceiver.h"
#include "ncmconnectionmultiplexerlogs.h"
//#include "cncmportstore.h"
#include "mncmsessionobserver.h"
#include "mncmconnectionmultiplexerobserver.h"
const TUint KESockMessageSlots = 16;
const TUint32 KLocalAddress = INET_ADDR( 10, 168, 0, 100 );
const TUint KLocalPort = 5000;
// ---------------------------------------------------------------------------
// CNcmSessionSession::CNcmSession
// ---------------------------------------------------------------------------
//
CNcmSession::CNcmSession( TUint aSessionId,
TUint32 aIapId,
MNcmConnectionMultiplexerObserver& aObserver,
MNcmSessionObserver& aSessionObserver ) :
CActive( EPriorityStandard ),
iSessionId( aSessionId ), iIapId( aIapId ), iObserver( aObserver ),
iSessionObserver( aSessionObserver )
{
CActiveScheduler::Add( this );
}
// ---------------------------------------------------------------------------
// CNcmSession::ConstructL
// ---------------------------------------------------------------------------
//
void CNcmSession::ConstructL( TUint /*aPortRangeStart*/,
TUint /*aPortRangeStop*/ )
{
iIpv4Addr.SetAddress( KLocalAddress );
iIpv4Addr.SetPort( KLocalPort );
/*
iPortStore = CNcmPortStore::NewL( aPortRangeStart, aPortRangeStop );
*/
User::LeaveIfError( iSocketServ.Connect( KESockMessageSlots ) );
TCommDbConnPref pref;
pref.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
pref.SetIapId( iIapId );
User::LeaveIfError( iConnection.Open( iSocketServ ) );
TSecurityPolicy policy( ECapabilityNetworkServices );
TSecurityPolicyBuf securityBuf(policy);
User::LeaveIfError( iConnection.Control(
KCOLConnection, KCoEnableCloneOpen, securityBuf ) );
iConnection.Start( pref/*, iStatus*/ );
// SetActive();
}
// ---------------------------------------------------------------------------
// CNcmSession::NewL
// ---------------------------------------------------------------------------
//
CNcmSession* CNcmSession::NewL( TUint aSessionId,
TUint32 aIapId, TUint aPortRangeStart, TUint aPortRangeStop,
MNcmConnectionMultiplexerObserver& aObserver,
MNcmSessionObserver& aSessionObserver )
{
CNcmSession* self =
CNcmSession::NewLC( aSessionId, aIapId, aPortRangeStart,
aPortRangeStop, aObserver, aSessionObserver );
CleanupStack::Pop( self );
return self;
}
// ---------------------------------------------------------------------------
// CNcmSession::NewLC
// ---------------------------------------------------------------------------
//
CNcmSession* CNcmSession::NewLC( TUint aSessionId,
TUint32 aIapId, TUint aPortRangeStart, TUint aPortRangeStop,
MNcmConnectionMultiplexerObserver& aObserver,
MNcmSessionObserver& aSessionObserver )
{
CNcmSession* self =
new( ELeave ) CNcmSession( aSessionId, aIapId,
aObserver, aSessionObserver );
CleanupStack::PushL( self );
self->ConstructL( aPortRangeStart, aPortRangeStop );
return self;
}
// ---------------------------------------------------------------------------
// CNcmSession::~CNcmSession
// ---------------------------------------------------------------------------
//
CNcmSession::~CNcmSession()
{
//delete iPortStore;
iStreams.ResetAndDestroy();
// delete iIcmpReceiver;
iConnection.Close();
// Cancel();
iSocketServ.Close();
}
// ---------------------------------------------------------------------------
// CNcmSession::CreateStreamL
// ---------------------------------------------------------------------------
//
TUint CNcmSession::CreateStreamL( TInt aQos,
TUint aProtocol )
{
TUint streamId( GenerateStreamId() );
CNcmStream* item = CNcmStream::NewL(
iSessionId, streamId, aQos, aProtocol );
CleanupStack::PushL( item );
iStreams.AppendL( item );
CleanupStack::Pop( item );
return item->StreamId();
}
// ---------------------------------------------------------------------------
// CNcmSession::RemoveStreamL
// ---------------------------------------------------------------------------
//
void CNcmSession::RemoveStreamL( TUint aStreamId )
{
TUint streamIndex( StreamIndexL( aStreamId ) );
delete iStreams[streamIndex];
iStreams.Remove( streamIndex );
}
/*
// ---------------------------------------------------------------------------
// CNcmSession::ConnectionId
// ---------------------------------------------------------------------------
//
TUint32 CNcmSession::IapId() const
{
return iIapId;
}
*/
// ---------------------------------------------------------------------------
// CNcmSession::ConnectionId
// ---------------------------------------------------------------------------
//
TUint CNcmSession::SessionId() const
{
return iSessionId;
}
// ---------------------------------------------------------------------------
// From class CActive
//
// CNcmSocketDestination::RunL
// ---------------------------------------------------------------------------
//
void CNcmSession::RunL()
{
__CONNECTIONMULTIPLEXER_INT1(
"CNcmSession::RunL - iStatus: ", iStatus.Int() )
/*
if ( iStatus != KErrNone )
{
iObserver.Notify( iSessionId, 0,
MNcmConnectionMultiplexerObserver::ESessionCreated,
iStatus.Int() );
iSessionObserver.SessionCreationFailed( iSessionId );
}
else
{
iInitialized = ETrue;
#ifndef _DEBUG_EUNIT
iIcmpReceiver = CNcmIcmpReceiver::NewL( iSessionId,
iSessionObserver,
iSocketServ,
iConnection );
#endif
CNcmLocalAddressResolver* localAddressResolver(
CNcmLocalAddressResolver::NewLC( iSocketServ ) );
localAddressResolver->GetLocalAddrL( iLocalAddr, iIapId );
CleanupStack::PopAndDestroy( localAddressResolver );
iObserver.Notify( iSessionId, 0,
MNcmConnectionMultiplexerObserver::ESessionCreated,
iStatus.Int() );
}
*/
}
// ---------------------------------------------------------------------------
// From class CActive
//
// DoCancel
// ---------------------------------------------------------------------------
//
void CNcmSession::DoCancel()
{
// RConnection doesn't cancel an outstanding request at Close()
// so we'll have to it "manually" here
if( iStatus.Int() == KRequestPending )
{
TRequestStatus* status = &iStatus;
User::RequestComplete( status, KErrCancel );
}
}
// -----------------------------------------------------------------------------
// From class CActive
//
// CNcmSession::RunError
// -----------------------------------------------------------------------------
//
TInt CNcmSession::RunError( TInt /*aError*/ )
{
/*
__CONNECTIONMULTIPLEXER_INT1(
"CNcmSession::RunError aError: ", aError )
iObserver.Notify( iSessionId, 0,
MNcmConnectionMultiplexerObserver::ESessionCreated,
aError );
iSessionObserver.SessionCreationFailed( iSessionId );
aError = aError;
*/
return KErrNone;
}
// ---------------------------------------------------------------------------
// CNcmSession::StreamByIdL
// ---------------------------------------------------------------------------
//
CNcmStream* CNcmSession::StreamByIdL(
TUint aStreamId )
{
TInt ind( iStreams.Count() );
while ( ind-- )
{
if ( iStreams[ind]->StreamId() == aStreamId )
{
return iStreams[ind];
}
}
return NULL;
}
// ---------------------------------------------------------------------------
// CNcmSession::StreamIndexL
// ---------------------------------------------------------------------------
//
TUint CNcmSession::StreamIndexL( TUint aStreamId )
{
TInt streamCount( iStreams.Count() );
for ( TInt i = 0; i < streamCount; i++ )
{
if ( iStreams[i]->StreamId() == aStreamId )
{
return i;
}
}
User::Leave( KErrNotFound );
return KErrNone; // for warning removal on compile
}
// ---------------------------------------------------------------------------
// CNcmSession::SocketServer
// ---------------------------------------------------------------------------
//
RSocketServ& CNcmSession::SocketServer()
{
return iSocketServ;
}
// ---------------------------------------------------------------------------
// CNcmSession::Connection
// ---------------------------------------------------------------------------
//
RConnection& CNcmSession::Connection()
{
return iConnection;
}
// ---------------------------------------------------------------------------
// CNcmSession::GetConnectionName
// ---------------------------------------------------------------------------
//
TInt CNcmSession::GetConnectionName( TName& aConnectionName )
{
iConnection.Name( aConnectionName );
return 0;
}
// -----------------------------------------------------------------------------
// CNcmSession::GenerateStreamId
// -----------------------------------------------------------------------------
//
TUint CNcmSession::GenerateStreamId() const
{
return ( static_cast<TUint>( Math::Random() ) );
// return 222;
}
/*
// ---------------------------------------------------------------------------
// CNcmSession::PortStore
// ---------------------------------------------------------------------------
//
CNcmPortStore& CNcmSession::PortStore() const
{
__CONNECTIONMULTIPLEXER( "CNcmSession::PortStore" )
return *iPortStore;
}
// ---------------------------------------------------------------------------
// CNcmSession::HandleIcmpErrorL
// ---------------------------------------------------------------------------
void CNcmSession::HandleIcmpErrorL( const TInetAddr& aAddress )
{
__CONNECTIONMULTIPLEXER(
"CNcmSession::HandleIcmpErrorL" )
TInt ind( iStreams.Count() );
TUint mediaConnectionId( 0 );
while ( ind-- )
{
mediaConnectionId = iStreams[ind]->DefaultConnectionId();
if ( iStreams[ind]->ConnectionL( mediaConnectionId )->Destination()->
CheckSenderValidityToSending( aAddress ) &&
!iStreams[ind]->IcmpErrorReceived() )
{
iStreams[ind]->SetIcmpErrorReceived( ETrue );
iObserver.Notify( iSessionId, iStreams[ind]->StreamId(),
MNcmConnectionMultiplexerObserver::ESessionCreated,
KErrCommsLineFail );
return;
}
}
User::Leave( KErrNotFound );
}
// ---------------------------------------------------------------------------
// CNcmSession::Initialized
// ---------------------------------------------------------------------------
//
/*TBool CNcmSession::Initialized() const
{
return iInitialized;
}
*/
// ---------------------------------------------------------------------------
// CNcmSession::ResolveDestinationAddressL
// ---------------------------------------------------------------------------
//
/*void CNcmSession::ResolveDestinationAddressL( const TDesC8& aAddress,
TUint aPort, TInetAddr& aResult )
{
__CONNECTIONMULTIPLEXER_STR(
"CNcmSession::ResolveDestinationAddressL, FQDN", aAddress )
HBufC* addrBuf = HBufC::NewLC( aAddress.Length() );
TPtr addrPtr( addrBuf->Des() );
User::LeaveIfError(
CnvUtfConverter::ConvertToUnicodeFromUtf8( addrPtr, aAddress ) );
RHostResolver resolver;
CleanupClosePushL( resolver );
User::LeaveIfError( resolver.Open(
iSocketServ, KAfInet, KProtocolInetUdp, iConnection ) );
TNameEntry entry;
User::LeaveIfError( resolver.GetByName( *addrBuf, entry ) );
CleanupStack::PopAndDestroy( 2, addrBuf );
aResult = TInetAddr::Cast( entry().iAddr );
aResult.SetPort( aPort );
__CONNECTIONMULTIPLEXER_ADDRLOG(
"CNcmSession::ResolveDestinationAddressL, IP", aResult )
}
*/
// ---------------------------------------------------------------------------
// CNcmSession::LocalIPv4Address
// ---------------------------------------------------------------------------
//
TInetAddr& CNcmSession::LocalIPv4Address()
{
return iIpv4Addr;
}
// ---------------------------------------------------------------------------
// CNcmSession::LocalIPv6Address
// ---------------------------------------------------------------------------
//
TInetAddr& CNcmSession::LocalIPv6Address()
{
return iIpv6Addr;
}
// ---------------------------------------------------------------------------
// CNcmSession::IcmpError()
// ---------------------------------------------------------------------------
//
void CNcmSession::IcmpError( const TInetAddr& /*aAddress*/,
TInetAddr& /*aLocalAddress*/, TInetAddr& /*aRemoteAddress*/ )
{
// TRAP_IGNORE( this->HandleIcmpErrorL( aSessionId, aAddress ) );
}
// ---------------------------------------------------------------------------
// CNcmSession::HandleIcmpErrorL()
// ---------------------------------------------------------------------------
//
void CNcmSession::HandleIcmpErrorL( const TInetAddr& /*aAddress*/,
TInetAddr& /*aLocalAddress*/, TInetAddr& /*aRemoteAddress*/ )
{
/* TUint streamId( 0 );
TUint connectionId( 0 );
SessionByIdL( aSessionId )->
GetStreamAndConnectionIdByDestinationAddressL( streamId,
connectionId,
aAddress );
iObserver.IcmpError( aSessionId, streamId, aAddress );
StreamByIdL( streamId )->ConnectionObserverHandler().
ConnectionNotify( streamId, connectionId,
EMultiplexerConnectionError, KErrCommsLineFail );*/
}