diff -r 000000000000 -r dfb7c4ff071f datacommsserver/esockserver/ssock/ss_connectionsession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/datacommsserver/esockserver/ssock/ss_connectionsession.cpp Thu Dec 17 09:22:25 2009 +0200 @@ -0,0 +1,815 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +/** + @file + @internalTechnology + @released since v9.5 +*/ + + +#include +#include +#include +#include //for KAfInet +#include + +#include +#include + +#include + +#include "ss_connectionsession.h" +#include + +#include +#include "ss_apiext_messages.h" + +#include +#include +#include +#include + +#include +#include // include this once per dll + + +#ifdef _DEBUG +// Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module +// (if it could happen through user error then you should give it an explicit, documented, category + code) +_LIT(KSpecAssert_ESockSSockscnctn, "ESockSSockscnctn"); +#endif + +using namespace ConnectionServ; +using namespace ESock; +using namespace Messages; +using namespace MeshMachine; + +using namespace CommsDat; + + +//Panic codes +_LIT(KConnectionSessionPanic, "ConnectionSession"); +enum TConnectionSessionPanic + { + EExpectedServiceProvider = 0, // + }; + + +/** +Constructor +*/ +CConnectionSession::CConnectionSession(TUidType aUid, Den::TSessionUniqueId aSessionUniqueId) + : CWorkerSession(aUid, aSessionUniqueId) + { +// LOG_NODE_CREATE(KESockConnectionTag, CConnectionSession); + } + + +/*static*/ CConnectionSession* CConnectionSession::NewL(TProcessId aProcessId, TUidType aUid, Den::TSessionUniqueId aSessionUniqueId) + { + CConnectionSession* self = new (ELeave) CConnectionSession(aUid, aSessionUniqueId); + CleanupStack::PushL(self); + self->ConstructL(aProcessId); + CleanupStack::Pop(self); + return self; + } + + +CConnectionSession::~CConnectionSession() + { + // No handshaking code required - cancelling any outstanding requests was already performed by the client side + // which synchonously waited for everything to shut down before issuing the close on the session. + + // Best make sure though.. :-) + + __ASSERT_DEBUG(iStatusMessage.IsNull(), User::Panic(KSpecAssert_ESockSSockscnctn, 1)); + __ASSERT_DEBUG(!iStatusBundle, User::Panic(KSpecAssert_ESockSSockscnctn, 2)); + + __ASSERT_DEBUG(!iNotificationActive, User::Panic(KSpecAssert_ESockSSockscnctn, 3)); + __ASSERT_DEBUG(iNotificationMessage.IsNull(), User::Panic(KSpecAssert_ESockSSockscnctn, 4)); + __ASSERT_DEBUG(iNotificationQueue.Count()==0, User::Panic(KSpecAssert_ESockSSockscnctn, 5)); + iNotificationQueue.Close(); + + LeaveServiceProvider(); + LOG_NODE_DESTROY(KESockConnectionTag, CConnectionSession) + } + + + +TInt CConnectionSession::CheckPolicy(const TSecurityPolicy& aPolicy, const char *aDiagnostic) +/** +Check the security policy of a process. +Called from a socket or resolver provider to check whether the process conforms to the security policy passed as +argument. +@see MProvdSecurityChecker +*/ + { + RProcess process; + TInt ret = aPolicy.CheckPolicy(process, aDiagnostic) ? KErrNone : KErrPermissionDenied; + process.Close(); + return ret; + } + + +void CConnectionSession::CompleteMessage(const RMessage2& aMessage, TInt aResult) + { + __ASSERT_DEBUG(!aMessage.IsNull(), User::Panic(KSpecAssert_ESockSSockscnctn, 6)); + if(!aMessage.IsNull()) + { + LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CConnectionSession(%08x):\tCompleteMessage(%08x) with %d"), this, aMessage.Handle(), aResult) ); + aMessage.Complete(aResult); + } + __ASSERT_DEBUG(aMessage.IsNull(), User::Panic(KSpecAssert_ESockSSockscnctn, 7)); + } + + +/** + Handle messages for this server. + @param aMessage Standard IPC request from client side +*/ +void CConnectionSession::ServiceL(const RMessage2& aMessage) + { + LOG( + TBuf8<64> messName; + ESockLog::ConnServIPCMessName((TConnectionServerMessage) aMessage.Function(), messName); + ESockLog::Printf(KESockServerTag, _L8("CConnectionSession(%08x):\tServiceL, Message(%08x) [%S]"), + this, aMessage.Handle(), &messName); + ); + + const Den::RSafeMessage& safeMessage(static_cast(aMessage)); + + const TInt function = aMessage.Function(); + LOG_DETAILED( ESockLog::Printf(KESockConnectionTag, _L("CConnectionSession %08x:\tCommand %d"), this, aMessage.Function()) ); + /* Cases handled without a subsession */ + switch (function) + { + case ECMAttachToTierManager: + StartAttachToTierManager(aMessage); + break; + + case ECMAccessPointStatusQuery_DoThenGetResultOrSize: + { + const Messages::TNodeId& sp = ServiceProviderL(); + + // ensure not already active. Should be guarded by client side code + if (!iStatusMessage.IsNull()) + { + CompleteMessage(aMessage, KErrInUse); + return; + } + + // unpack bundle + TInt length = aMessage.GetDesLengthL(0); + RBuf8 buffer; + buffer.CreateL(length); + CleanupClosePushL(buffer); + aMessage.ReadL(0, buffer); + CConnectionServParameterBundle* queryBundle = CConnectionServParameterBundle::LoadL(buffer); + CleanupStack::PopAndDestroy(&buffer); + CleanupStack::PushL(queryBundle); + + CRefCountOwnedParameterBundle* bundleOwner = new(ELeave)CRefCountOwnedParameterBundle(queryBundle); + CleanupStack::Pop(); + bundleOwner->Open(); + CleanupClosePushL(*bundleOwner); + + // create and send message + TNodeCtxId us(ETierStatusActivity, NodeId()); //We pretend to be a MM node :) + + // ownership of bundle travels with message + RClientInterface::OpenPostMessageClose(us, sp, + TCFTierStatusProvider::TTierStatusQuery(bundleOwner, &aMessage).CRef()); + + CleanupStack::Pop(); + + // remember client request + iStatusMessage = aMessage; + } + break; + + case ECMAccessPointStatusQuery_GetResult: + { + if (!iStatusBundle) + { + CompleteMessage(aMessage, KErrNotReady); + return; + } + + CRefCountOwnedParameterBundle* bundleOwner = iStatusBundle; + const CConnectionServParameterBundle& bundle = *static_cast(bundleOwner->PtrL()); + iStatusBundle = NULL; + CleanupClosePushL(*bundleOwner); + + TInt length = bundle.Length(); + + // we should only be calling this after a realloc on the client side. + // so there should be no way the bundle won't fit + if (length > safeMessage.GetDesMaxLengthL(0)) + { + CompleteMessage(aMessage, KErrOverflow); + CleanupStack::PopAndDestroy(bundleOwner); + return; + } + + RBuf8 buffer; + buffer.CreateL(length); + CleanupClosePushL(buffer); + User::LeaveIfError(bundle.Store(buffer)); + aMessage.WriteL(0, buffer); + CompleteMessage(aMessage, KErrNone); + CleanupStack::PopAndDestroy(&buffer); + CleanupStack::PopAndDestroy(bundleOwner); + } + break; + + case ECMAccessPointStatusQuery_Cancel: + { + // complete the original IPC + if (iStatusMessage.IsNull()) + { + // nothing to cancel + CompleteMessage(aMessage, KErrNone); + return; + } + + CompleteMessage(iStatusMessage, KErrCancel); + + // create and send message + TNodeCtxId us(ETierStatusActivity, NodeId()); //Pretend to be a MM node + __ASSERT_DEBUG(ServiceProvider()!=Messages::TNodeId::NullId(),User::Panic(KConnectionSessionPanic,EExpectedServiceProvider)); + RClientInterface::OpenPostMessageClose(us, ServiceProviderL(), TEBase::TCancel().CRef()); + + if (iStatusBundle) + { + iStatusBundle->Close(); + iStatusBundle = NULL; + } + + // we'll complete when we get the response. + iStatusMessage = aMessage; + } + break; + + case ECMAccessPointNotification_SetupThenAwaitThenGetResultOrSize: + { + const Messages::TNodeId& sp = ServiceProviderL(); + + // ensure not already active. Should be guarded by client side code + if (iNotificationActive) + { + CompleteMessage(aMessage, KErrInUse); + return; + } + + // unpack bundle + TInt length = aMessage.GetDesLengthL(0); + RBuf8 buffer; + buffer.CreateL(length); + CleanupClosePushL(buffer); + aMessage.ReadL(0, buffer); + CConnectionServParameterBundle* queryBundle = CConnectionServParameterBundle::LoadL(buffer); + CleanupStack::PopAndDestroy(&buffer); + CleanupStack::PushL(queryBundle); + + CRefCountOwnedParameterBundle* bundleOwner = new (ELeave)CRefCountOwnedParameterBundle(queryBundle); + CleanupStack::Pop(); + bundleOwner->Open(); + CleanupClosePushL(*bundleOwner); + + // create and send message + TNodeCtxId us(ETierNotificationActivity, NodeId()); //Pretend to be a MM node + RClientInterface::OpenPostMessageClose(us, sp, + TCFTierStatusProvider::TTierNotificationRegistration(bundleOwner, &aMessage).CRef()); + + CleanupStack::Pop(); + + // remember client request + iNotificationActive = ETrue; + iNotificationMessage = aMessage; + } + break; + + + case ECMAccessPointNotification_AwaitThenGetResultOrSize: + { + // ensure already active but no outstanding request. Should be guarded by client side code + if (!iNotificationActive) + { + CompleteMessage(aMessage, KErrNotReady); + return; + } + + if (!iNotificationMessage.IsNull()) + { + CompleteMessage(aMessage, KErrInUse); + return; + } + + // pick from queue if anything in it.. + if(iNotificationQueue.Count()) + { + CRefCountOwnedParameterBundle* bundleOwner = iNotificationQueue[0]; + const CConnectionServParameterBundle* queuedNotification = static_cast(bundleOwner->PtrL()); + TInt length = queuedNotification->Length(); + + if (length > safeMessage.GetDesMaxLengthL(1)) + { + // we're gonna need a bigger boat + CompleteMessage(aMessage, length); + } + else + { + iNotificationQueue.Remove(0); + CleanupClosePushL(*bundleOwner); + RBuf8 buffer; + buffer.CreateL(length); + CleanupClosePushL(buffer); + User::LeaveIfError(queuedNotification->Store(buffer)); + aMessage.WriteL(1, buffer); + CompleteMessage(aMessage,KErrNone); + CleanupStack::PopAndDestroy(&buffer); + CleanupStack::PopAndDestroy(bundleOwner); // close ref on bundle + } + } + else // we have to wait for a notification coming back from the tier so park the request + { + iNotificationMessage = aMessage; + } + + } + break; + + + case ECMAccessPointNotification_GetResult: + { + if (!iNotificationActive || iNotificationQueue.Count() == 0) + { + CompleteMessage(aMessage, KErrNotReady); + return; + } + + CRefCountOwnedParameterBundle* bundleOwner = iNotificationQueue[0]; + const CConnectionServParameterBundle* queuedNotification = static_cast(bundleOwner->PtrL()); + iNotificationQueue.Remove(0); + CleanupClosePushL(*bundleOwner); + TInt length = queuedNotification->Length(); + + // we should only be calling this after a realloc on the client side. + // so there should be no way the bundle won't fit + if (length > safeMessage.GetDesMaxLengthL(1)) + { + CompleteMessage(aMessage, KErrOverflow); + CleanupStack::PopAndDestroy(&bundleOwner); + return; + } + + RBuf8 buffer; + buffer.CreateL(length); + CleanupClosePushL(buffer); + User::LeaveIfError(queuedNotification->Store(buffer)); + aMessage.WriteL(1, buffer); + CompleteMessage(aMessage, KErrNone); + CleanupStack::PopAndDestroy(&buffer); + CleanupStack::PopAndDestroy(bundleOwner); // close ref on bundle + } + break; + + + case ECMAccessPointNotification_Cancel: + { + // complete the original IPC + if (!iNotificationActive) + { + // nothing to cancel + CompleteMessage(aMessage, KErrNone); + return; + } + if (!iNotificationMessage.IsNull()) + { + //TODO RZ we should really panic the client here. + //raising a defect to do this. + CompleteMessage(iNotificationMessage, KErrCancel); + } + + // create and send message + TNodeCtxId us(ETierNotificationActivity, NodeId()); //Pretend to be a MM node + __ASSERT_DEBUG(ServiceProvider()!=Messages::TNodeId::NullId(),User::Panic(KConnectionSessionPanic,EExpectedServiceProvider)); + RClientInterface::OpenPostMessageClose(us, ServiceProviderL(), TEBase::TCancel().CRef()); + + // splat the queue + iNotificationQueue.ResetAndDestroy(); + + // we'll complete when we get the response. + iNotificationMessage = aMessage; + } + break; + + case ECMApiExtBindIface: + CommsApiExtBindIfaceL(aMessage); + break; + case ECMApiExtIfaceSend: + case ECMApiExtIfaceSendReceive: + CommsApiExtIfaceSendReceiveL(aMessage); + break; + case ECMApiExtIfaceClose: + CloseExtensionInterface(aMessage); + break; + + + default: + CompleteMessage(aMessage,KErrNotSupported); + } + } + +void CConnectionSession::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage) +/** +Entry point to CConnectionSession node +*/ + { + // void to remove build warning + (void)aSender; + + if ( aMessage.IsMessage() ) + { + TUint16 activityId = address_cast(&aRecipient)? address_cast(aRecipient).NodeCtx() : KActivityNull; + ProcessError(activityId, aMessage); + } + else if ( aMessage.IsMessage() ) + { + HandleTierStatus(aMessage); + } + else if ( aMessage.IsMessage() ) + { + HandleTierNotification(aMessage); + } + else if ( aMessage.IsMessage() ) + { + TCFFactory::TPeerFoundOrCreated& msg = message_cast(aMessage); + AttachToTierManager(msg.iNodeId); + } + else if ( aMessage.IsMessage() ) + { + __ASSERT_DEBUG(aSender == iTierManager, User::Panic(KSpecAssert_ESockSSockscnctn, 8)); + CompleteMessage(iAttachMessage, KErrNone); + } + else + { + LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CConnectionSession(%08x):\tReceivedL - Unexpected message"), this)); + __ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 9)); + } + aMessage.ClearMessageId(); + } + + + +void CConnectionSession::HandleTierStatus(const Messages::TSignatureBase& aCFMessage) + { + const TCFTierStatusProvider::TTierStatus& msg = message_cast(aCFMessage); + + CRefCountOwnedParameterBundle* bundle = msg.iBundle; + if( bundle == NULL || bundle->Ptr() == NULL) + { + __CFLOG_VAR((KTierTag,KConnServSubTag,_L8("Null bundle received. Discarding it."))); + if(bundle) + { + bundle->Close(); + } + return; + } + + const CConnectionServParameterBundle& statusBundle = *static_cast(bundle->Ptr()); + if (iStatusMessage.IsNull()) + { + _LOG_BUNDLE("Received status bundle when no outstanding request.", &statusBundle); + // shouldn't have received this. + __ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 10)); + // swallow it in release mode + + bundle->Close(); + return; + } + + TInt function = iStatusMessage.Function(); + switch (function) + { + case ECMAccessPointStatusQuery_DoThenGetResultOrSize: + { + __ASSERT_DEBUG(iStatusBundle == NULL, User::Panic(KSpecAssert_ESockSSockscnctn, 11)); + + TInt length = statusBundle.Length(); + + const Den::RSafeMessage& safeStatusMessage(static_cast(iStatusMessage)); + if (length > safeStatusMessage.GetDesMaxLengthL(1)) + { + // we're gonna need a bigger boat + iStatusBundle = msg.iBundle; + CompleteMessage(iStatusMessage, length); + } + else + { + RBuf8 buffer; + TInt err = buffer.Create(length); + if (err == KErrNone) + { + err = statusBundle.Store(buffer); + if (err == KErrNone) + { + err = iStatusMessage.Write(1, buffer); + } + } + CompleteMessage(iStatusMessage, err); + buffer.Close(); + msg.iBundle->Close(); + } + } + break; + + case ECMAccessPointStatusQuery_Cancel: + __CFLOG_VAR((KTierTag,KConnServSubTag,_L8("Received bundle when already cancelling. Discarding it."))); + msg.iBundle->Close(); + break; + + case ECMAccessPointStatusQuery_GetResult: + default: + // Consume the bundle if we didn't expect it + msg.iBundle->Close(); + __ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 12)); + } + } + + +void CConnectionSession::HandleTierNotification(const Messages::TSignatureBase& aCFMessage) + { + const TCFTierStatusProvider::TTierNotification& msg = message_cast(aCFMessage); + + CRefCountOwnedParameterBundle* bundle = msg.iBundle; + if( bundle == NULL || bundle->Ptr() == NULL) + { + __CFLOG_VAR((KTierTag,KConnServSubTag,_L8("Null bundle received. Discarding it."))); + if(bundle) + { + bundle->Close(); + } + return; + } + + const CConnectionServParameterBundle* newNotification = static_cast(bundle->Ptr()); + + if (!iNotificationActive) + { + // shouldn't have received this. + __ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 13)); + // swallow it in production mode + // RJL log here + msg.iBundle->Close(); + return; + } + + TInt function = iNotificationMessage.Function(); + if (iNotificationMessage.IsNull()) + { + iNotificationQueue.Append(msg.iBundle); + } + else + { + switch (function) + { + case ECMAccessPointNotification_SetupThenAwaitThenGetResultOrSize: + case ECMAccessPointNotification_AwaitThenGetResultOrSize: + { + __ASSERT_DEBUG(iNotificationQueue.Count() == 0, User::Panic(KSpecAssert_ESockSSockscnctn, 14)); + + TInt length = newNotification->Length(); + + const Den::RSafeMessage& safeNotificationMessage(static_cast(iNotificationMessage)); + if (length > safeNotificationMessage.GetDesMaxLengthL(1)) + { + // we're gonna need a bigger boat + iNotificationQueue.Append(msg.iBundle); + CompleteMessage(iNotificationMessage, length); + } + else + { + RBuf8 buffer; + TInt err = buffer.Create(length); + if (err == KErrNone) + { + err = newNotification->Store(buffer); + if (err == KErrNone) + { + err = iNotificationMessage.Write(1, buffer); + } + } + CompleteMessage(iNotificationMessage, err); + buffer.Close(); + + msg.iBundle->Close(); + } + } + break; + + case ECMAccessPointNotification_Cancel: + // swallow it. RJL log here + msg.iBundle->Close(); + break; + + case ECMAccessPointNotification_GetResult: + default: + msg.iBundle->Close(); + __ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 15)); + } + } + } + + +// error from comms framework +// +void CConnectionSession::ProcessError(TUint16 aActId, Messages::TSignatureBase& aCFMessage) + { + TEBase::TError& inMsg = message_cast(aCFMessage); + + if (inMsg.iMsgId == TCFFactory::TFindOrCreatePeer::Id()) + { + __ASSERT_DEBUG(!iAttachMessage.IsNull(), User::Panic(KSpecAssert_ESockSSockscnctn, 16)); + CompleteMessage(iAttachMessage, inMsg.iValue); + } + else + { + TInt errCode = inMsg.iValue; + ProcessError(aActId, errCode); + } + } + + +void CConnectionSession::ProcessError(TUint16 aActId, TInt aErrCode) + { + switch(aActId) + { + case ETierStatusActivity: + { + __ASSERT_DEBUG( ! iStatusMessage.IsNull(), User::Panic(KSpecAssert_ESockSSockscnctn, 17)); + switch(iStatusMessage.Function()) + { + case ECMAccessPointStatusQuery_DoThenGetResultOrSize: + case ECMAccessPointStatusQuery_Cancel: + __ASSERT_DEBUG(iStatusBundle == 0, User::Panic(KSpecAssert_ESockSSockscnctn, 18)); + // haven't yet allocated anything.. + // so complete with the error code. + CompleteMessage(iStatusMessage,aErrCode); + break; + + case ECMAccessPointStatusQuery_GetResult: + default: + __CFLOG_VAR((KTierTag,KConnServSubTag,_L8("Unexpected state: outstanding IRC: cancel, TCFMsg: error %d"),aErrCode)); + __ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 19)); + } + } + break; + + case ETierNotificationActivity: + { + if (iNotificationMessage.IsNull()) + { + //TODO RZ This is all wrong and the bad clients need panicked + //raising a defect. + iNotificationQueue.ResetAndDestroy(); + } + else + { + switch(iNotificationMessage.Function()) + { + case ECMAccessPointNotification_SetupThenAwaitThenGetResultOrSize: + case ECMAccessPointNotification_AwaitThenGetResultOrSize: + case ECMAccessPointNotification_Cancel: + // ok, delete queue in case we didn't already.. + iNotificationQueue.ResetAndDestroy(); + CompleteMessage(iNotificationMessage,aErrCode); + break; + + case ECMAccessPointNotification_GetResult: + default: + __CFLOG_VAR((KTierTag,KConnServSubTag,_L8("Unexpected state: outstanding IRC: cancel, TCFMsg: error %d"),aErrCode)); + __ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 20)); + } + } + iNotificationActive = EFalse; + } + break; + + default: + // eek! shouldn't be receiving anything to any other activity + __ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 21)); + } + } + + +void CConnectionSession::StartAttachToTierManager(const RMessage2& aMessage) + { + if( iNotificationActive || + ! iNotificationMessage.IsNull() || + ! iStatusMessage.IsNull()) + { + CompleteMessage(aMessage, KErrInUse); + } + + CSockManData* globals = SockManGlobals::Get(); + const TNodeId tmfc = globals->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::ETierMgrPlane)); + if (tmfc.IsNull()) + { + LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CConnectionSession(%08x):\tStartAttachToTierManager - No TierMgr FC"), this)); + + // If the tier manager FC is null, and esock has completed booting something is very wrong. + __ASSERT_DEBUG(globals->iWorkerThread && !globals->iWorkerThread->PitBoss().ModuleConfigurationComplete(), User::Panic(KSpecAssert_ESockSSockscnctn, 22)); + + // Someone is trying to use the Connection Server before esock has finished booting + ParkIfIndeterminateRequest(aMessage, KErrNotFound); + return; + } + + iAttachMessage = aMessage; + LeaveServiceProvider(); + TAlwaysFindFactoryQuery query; + RClientInterface::OpenPostMessageClose(Id(), tmfc, + TCFFactory::TFindOrCreatePeer(TCFPlayerRole::ETierMgrPlane, TUid::Uid(aMessage.Int0()), &query).CRef()); + } + +void CConnectionSession::AttachToTierManager(const TNodeId& aTierMgrFactory) + { + iTierManager = aTierMgrFactory; + RClientInterface::OpenPostMessageClose(Id(), iTierManager, + TCFServiceProvider::TJoinRequest(Id(), TCFClientType::ECtrl).CRef()); + } + +void CConnectionSession::LeaveServiceProvider() + { + const TNodeId& sp = ServiceProvider(); + + if(!sp.IsNull()) + { + const TNodeId& selfId(NodeId()); + RClientInterface::OpenPostMessageClose(selfId, sp, TEChild::TLeft().CRef()); + iTierManager.SetNull(); + } + } + + +void CConnectionSession::CommsApiExtBindIfaceL(const RMessage2& aMessage) + { + const Messages::TNodeId& sp = ServiceProvider(); + if(!sp.IsNull()) + { + TSupportedCommsApiExt interfaceId = static_cast(aMessage.Int0()); + sp.PostTo(Id(), TOpenExtensionInterface(UniqueId(), interfaceId, aMessage)); + } + } + +void CConnectionSession::CommsApiExtIfaceSendReceiveL(const RMessage2& aMessage) + { + const Messages::TNodeId& sp = ServiceProvider(); + if(!sp.IsNull()) + { + Elements::RResponseMsg responseMsg(aMessage, aMessage.Int0(), 1, 2); + sp.PostTo(Id(), TApiExtMsgDispatcher(UniqueId(), responseMsg)); + } + else + { + User::Leave(KErrNotReady); + } + + } + +void CConnectionSession::CloseExtensionInterface(const RMessage2& aMessage) + { + const Messages::TNodeId& sp = ServiceProvider(); + if(!sp.IsNull()) + { + TSupportedCommsApiExt interfaceId = static_cast(aMessage.Int0()); + sp.PostTo(Id(), TCloseExtensionInterface(UniqueId(), interfaceId, aMessage)); + } + } + +void CConnectionSession::CancelAndCloseAllClientExtIfaces() + { + const Messages::TNodeId& sp = ServiceProvider(); + if(!sp.IsNull()) + { + sp.PostTo(Id(), TCancelAndCloseAllClientExtItf(UniqueId())); + } + } + + + +