--- /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 <comms-infras/ss_log.h>
+#include <ss_std.h>
+#include <comms-infras/esockmessages.h>
+#include <in_sock.h> //for KAfInet
+#include <elements/factorynotify.h>
+
+#include <ss_glob.h>
+#include <comms-infras/ss_roles.h>
+
+#include <es_enum.h>
+
+#include "ss_connectionsession.h"
+#include <comms-infras/es_connectionservermessages.h>
+
+#include <comms-infras/ss_tiermanager.h>
+#include "ss_apiext_messages.h"
+
+#include <elements/nm_messages_child.h>
+#include <comms-infras/ss_nodemessages_tiermanager.h>
+#include <comms-infras/ss_nodemessages_factory.h>
+#include <comms-infras/ss_nodemessages_tiermanagerfactory.h>
+
+#include <comms-infras/es_connectionservparameterbundletrace.h>
+#include <comms-infras/es_connectionservparameterbundletraceimpl.h> // 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<const Den::RSafeMessage&>(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<const CConnectionServParameterBundle*>(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<const CConnectionServParameterBundle*>(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<const CConnectionServParameterBundle*>(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<TEBase::TError>() )
+ {
+ TUint16 activityId = address_cast<TNodeCtxId>(&aRecipient)? address_cast<TNodeCtxId>(aRecipient).NodeCtx() : KActivityNull;
+ ProcessError(activityId, aMessage);
+ }
+ else if ( aMessage.IsMessage<TCFTierStatusProvider::TTierStatus>() )
+ {
+ HandleTierStatus(aMessage);
+ }
+ else if ( aMessage.IsMessage<TCFTierStatusProvider::TTierNotification>() )
+ {
+ HandleTierNotification(aMessage);
+ }
+ else if ( aMessage.IsMessage<TCFFactory::TPeerFoundOrCreated>() )
+ {
+ TCFFactory::TPeerFoundOrCreated& msg = message_cast<TCFFactory::TPeerFoundOrCreated>(aMessage);
+ AttachToTierManager(msg.iNodeId);
+ }
+ else if ( aMessage.IsMessage<TCFServiceProvider::TJoinComplete>() )
+ {
+ __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<const TCFTierStatusProvider::TTierStatus>(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<const CConnectionServParameterBundle*>(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<const Den::RSafeMessage&>(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<const TCFTierStatusProvider::TTierNotification>(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<const CConnectionServParameterBundle*>(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<const Den::RSafeMessage&>(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<TEBase::TError>(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<TSupportedCommsApiExt>(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<TSupportedCommsApiExt>(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()));
+ }
+ }
+
+
+
+