datacommsserver/esockserver/ssock/ss_connectionsession.cpp
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @internalTechnology
       
    19  @released since v9.5
       
    20 */
       
    21 
       
    22 
       
    23 #include <comms-infras/ss_log.h>
       
    24 #include <ss_std.h>
       
    25 #include <comms-infras/esockmessages.h>
       
    26 #include <in_sock.h> //for KAfInet
       
    27 #include <elements/factorynotify.h>
       
    28 
       
    29 #include <ss_glob.h>
       
    30 #include <comms-infras/ss_roles.h>
       
    31 
       
    32 #include <es_enum.h>
       
    33 
       
    34 #include "ss_connectionsession.h"
       
    35 #include <comms-infras/es_connectionservermessages.h>
       
    36 
       
    37 #include <comms-infras/ss_tiermanager.h>
       
    38 #include "ss_apiext_messages.h"
       
    39 
       
    40 #include <elements/nm_messages_child.h>
       
    41 #include <comms-infras/ss_nodemessages_tiermanager.h>
       
    42 #include <comms-infras/ss_nodemessages_factory.h>
       
    43 #include <comms-infras/ss_nodemessages_tiermanagerfactory.h>
       
    44 
       
    45 #include <comms-infras/es_connectionservparameterbundletrace.h>
       
    46 #include <comms-infras/es_connectionservparameterbundletraceimpl.h> // include this once per dll
       
    47 
       
    48 
       
    49 #ifdef _DEBUG
       
    50 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
       
    51 // (if it could happen through user error then you should give it an explicit, documented, category + code)
       
    52 _LIT(KSpecAssert_ESockSSockscnctn, "ESockSSockscnctn");
       
    53 #endif
       
    54 
       
    55 using namespace ConnectionServ;
       
    56 using namespace ESock;
       
    57 using namespace Messages;
       
    58 using namespace MeshMachine;
       
    59 
       
    60 using namespace CommsDat;
       
    61 
       
    62 
       
    63 //Panic codes
       
    64 _LIT(KConnectionSessionPanic, "ConnectionSession");
       
    65 enum TConnectionSessionPanic
       
    66 	{
       
    67 	EExpectedServiceProvider = 0,     //
       
    68     };
       
    69 
       
    70 
       
    71 /**
       
    72 Constructor
       
    73 */
       
    74 CConnectionSession::CConnectionSession(TUidType aUid, Den::TSessionUniqueId aSessionUniqueId)
       
    75 	: CWorkerSession(aUid, aSessionUniqueId)
       
    76 	{
       
    77 //    LOG_NODE_CREATE(KESockConnectionTag, CConnectionSession);
       
    78 	}
       
    79 
       
    80 
       
    81 /*static*/ CConnectionSession* CConnectionSession::NewL(TProcessId aProcessId, TUidType aUid, Den::TSessionUniqueId aSessionUniqueId)
       
    82 	{
       
    83 	CConnectionSession* self = new (ELeave) CConnectionSession(aUid, aSessionUniqueId);
       
    84 	CleanupStack::PushL(self);
       
    85 	self->ConstructL(aProcessId);
       
    86 	CleanupStack::Pop(self);
       
    87 	return self;
       
    88 	}
       
    89 
       
    90 
       
    91 CConnectionSession::~CConnectionSession()
       
    92 	{
       
    93 	// No handshaking code required - cancelling any outstanding requests was already performed by the client side
       
    94 	//  which synchonously waited for everything to shut down before issuing the close on the session.
       
    95 
       
    96 	// Best make sure though.. :-)
       
    97 
       
    98 	__ASSERT_DEBUG(iStatusMessage.IsNull(), User::Panic(KSpecAssert_ESockSSockscnctn, 1));
       
    99 	__ASSERT_DEBUG(!iStatusBundle, User::Panic(KSpecAssert_ESockSSockscnctn, 2));
       
   100 
       
   101 	__ASSERT_DEBUG(!iNotificationActive, User::Panic(KSpecAssert_ESockSSockscnctn, 3));
       
   102 	__ASSERT_DEBUG(iNotificationMessage.IsNull(), User::Panic(KSpecAssert_ESockSSockscnctn, 4));
       
   103 	__ASSERT_DEBUG(iNotificationQueue.Count()==0, User::Panic(KSpecAssert_ESockSSockscnctn, 5));
       
   104 	iNotificationQueue.Close();
       
   105 
       
   106 	LeaveServiceProvider();
       
   107     LOG_NODE_DESTROY(KESockConnectionTag, CConnectionSession)
       
   108 	}
       
   109 
       
   110 
       
   111 
       
   112 TInt CConnectionSession::CheckPolicy(const TSecurityPolicy& aPolicy, const char *aDiagnostic)
       
   113 /**
       
   114 Check the security policy of a process.
       
   115 Called from a socket or resolver provider to check whether the process conforms to the security policy passed as
       
   116 argument.
       
   117 @see MProvdSecurityChecker
       
   118 */
       
   119 	{
       
   120 	RProcess process;
       
   121 	TInt ret = aPolicy.CheckPolicy(process, aDiagnostic) ? KErrNone : KErrPermissionDenied;
       
   122 	process.Close();
       
   123 	return ret;
       
   124 	}
       
   125 
       
   126 
       
   127 void CConnectionSession::CompleteMessage(const RMessage2& aMessage, TInt aResult)
       
   128 	{
       
   129 	__ASSERT_DEBUG(!aMessage.IsNull(), User::Panic(KSpecAssert_ESockSSockscnctn, 6));
       
   130 	if(!aMessage.IsNull())
       
   131 		{
       
   132 		LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CConnectionSession(%08x):\tCompleteMessage(%08x) with %d"), this, aMessage.Handle(), aResult) );
       
   133 		aMessage.Complete(aResult);
       
   134 		}
       
   135 	__ASSERT_DEBUG(aMessage.IsNull(), User::Panic(KSpecAssert_ESockSSockscnctn, 7));
       
   136 	}
       
   137 
       
   138 
       
   139 /**
       
   140  Handle messages for this server.
       
   141  @param aMessage Standard IPC request from client side
       
   142 */
       
   143 void CConnectionSession::ServiceL(const RMessage2& aMessage)
       
   144 	{
       
   145 	LOG(
       
   146 		TBuf8<64> messName;
       
   147 		ESockLog::ConnServIPCMessName((TConnectionServerMessage) aMessage.Function(), messName);
       
   148 		ESockLog::Printf(KESockServerTag, _L8("CConnectionSession(%08x):\tServiceL, Message(%08x) [%S]"),
       
   149 				this, aMessage.Handle(), &messName);
       
   150 		);
       
   151 
       
   152 	const Den::RSafeMessage& safeMessage(static_cast<const Den::RSafeMessage&>(aMessage));
       
   153 
       
   154     const TInt function = aMessage.Function();
       
   155 	LOG_DETAILED( ESockLog::Printf(KESockConnectionTag, _L("CConnectionSession %08x:\tCommand %d"), this, aMessage.Function()) );
       
   156     /* Cases handled without a subsession */
       
   157 	switch (function)
       
   158         {
       
   159 		case ECMAttachToTierManager:
       
   160 			StartAttachToTierManager(aMessage);
       
   161 			break;
       
   162 
       
   163 		case ECMAccessPointStatusQuery_DoThenGetResultOrSize:
       
   164 			{
       
   165 			const Messages::TNodeId& sp = ServiceProviderL();
       
   166 			
       
   167 			// ensure not already active. Should be guarded by client side code
       
   168             if (!iStatusMessage.IsNull())
       
   169                 {
       
   170                 CompleteMessage(aMessage, KErrInUse);
       
   171                 return;
       
   172                 }
       
   173 
       
   174 			// unpack bundle
       
   175 			TInt length = aMessage.GetDesLengthL(0);
       
   176 			RBuf8 buffer;
       
   177 			buffer.CreateL(length);
       
   178 			CleanupClosePushL(buffer);
       
   179 			aMessage.ReadL(0, buffer);
       
   180 			CConnectionServParameterBundle* queryBundle = CConnectionServParameterBundle::LoadL(buffer);
       
   181 			CleanupStack::PopAndDestroy(&buffer);
       
   182 			CleanupStack::PushL(queryBundle);
       
   183 
       
   184 			CRefCountOwnedParameterBundle* bundleOwner = new(ELeave)CRefCountOwnedParameterBundle(queryBundle);
       
   185 			CleanupStack::Pop();
       
   186 			bundleOwner->Open();
       
   187 			CleanupClosePushL(*bundleOwner);
       
   188 
       
   189 			// create and send message
       
   190 			TNodeCtxId us(ETierStatusActivity, NodeId()); //We pretend to be a MM node :)
       
   191 
       
   192 			// ownership of bundle travels with message
       
   193 			RClientInterface::OpenPostMessageClose(us, sp,
       
   194 				TCFTierStatusProvider::TTierStatusQuery(bundleOwner, &aMessage).CRef());
       
   195 
       
   196             CleanupStack::Pop();
       
   197 
       
   198 			// remember client request
       
   199 			iStatusMessage = aMessage;
       
   200 			}
       
   201 			break;
       
   202 
       
   203 		case ECMAccessPointStatusQuery_GetResult:
       
   204 			{
       
   205 			if (!iStatusBundle)
       
   206 			    {
       
   207 			    CompleteMessage(aMessage, KErrNotReady);
       
   208 			    return;
       
   209 			    }
       
   210 
       
   211 			CRefCountOwnedParameterBundle* bundleOwner = iStatusBundle;
       
   212 			const CConnectionServParameterBundle& bundle = *static_cast<const CConnectionServParameterBundle*>(bundleOwner->PtrL());
       
   213 			iStatusBundle = NULL;
       
   214 			CleanupClosePushL(*bundleOwner);
       
   215 
       
   216 			TInt length = bundle.Length();
       
   217 
       
   218 			// we should only be calling this after a realloc on the client side.
       
   219 			//  so there should be no way the bundle won't fit
       
   220 			if (length > safeMessage.GetDesMaxLengthL(0))
       
   221 			    {
       
   222 			    CompleteMessage(aMessage, KErrOverflow);
       
   223 			    CleanupStack::PopAndDestroy(bundleOwner);
       
   224 			    return;
       
   225 			    }
       
   226 
       
   227 			RBuf8 buffer;
       
   228 			buffer.CreateL(length);
       
   229 			CleanupClosePushL(buffer);
       
   230 			User::LeaveIfError(bundle.Store(buffer));
       
   231 			aMessage.WriteL(0, buffer);
       
   232 			CompleteMessage(aMessage, KErrNone);
       
   233 			CleanupStack::PopAndDestroy(&buffer);
       
   234 			CleanupStack::PopAndDestroy(bundleOwner);
       
   235 			}
       
   236 			break;
       
   237 
       
   238 		case ECMAccessPointStatusQuery_Cancel:
       
   239 			{
       
   240 			// complete the original IPC
       
   241 			if (iStatusMessage.IsNull())
       
   242 			    {
       
   243 			    // nothing to cancel
       
   244 			    CompleteMessage(aMessage, KErrNone);
       
   245 			    return;
       
   246 			    }
       
   247 
       
   248 			CompleteMessage(iStatusMessage, KErrCancel);
       
   249 
       
   250 			// create and send message
       
   251 			TNodeCtxId us(ETierStatusActivity, NodeId()); //Pretend to be a MM node
       
   252 			__ASSERT_DEBUG(ServiceProvider()!=Messages::TNodeId::NullId(),User::Panic(KConnectionSessionPanic,EExpectedServiceProvider));
       
   253 			RClientInterface::OpenPostMessageClose(us, ServiceProviderL(), TEBase::TCancel().CRef());
       
   254 
       
   255         	if (iStatusBundle)
       
   256         	    {
       
   257     			iStatusBundle->Close();
       
   258     			iStatusBundle = NULL;
       
   259         	    }
       
   260 
       
   261 			// we'll complete when we get the response.
       
   262 			iStatusMessage = aMessage;
       
   263 			}
       
   264 			break;
       
   265 
       
   266 		case ECMAccessPointNotification_SetupThenAwaitThenGetResultOrSize:
       
   267 			{
       
   268 			const Messages::TNodeId& sp = ServiceProviderL();
       
   269 
       
   270 			// ensure not already active. Should be guarded by client side code
       
   271 			if (iNotificationActive)
       
   272 			    {
       
   273 			    CompleteMessage(aMessage, KErrInUse);
       
   274 			    return;
       
   275 			    }
       
   276 
       
   277 			// unpack bundle
       
   278 			TInt length = aMessage.GetDesLengthL(0);
       
   279 			RBuf8 buffer;
       
   280 			buffer.CreateL(length);
       
   281 			CleanupClosePushL(buffer);
       
   282 			aMessage.ReadL(0, buffer);
       
   283 			CConnectionServParameterBundle* queryBundle = CConnectionServParameterBundle::LoadL(buffer);
       
   284 			CleanupStack::PopAndDestroy(&buffer);
       
   285 			CleanupStack::PushL(queryBundle);
       
   286 
       
   287 			CRefCountOwnedParameterBundle* bundleOwner = new (ELeave)CRefCountOwnedParameterBundle(queryBundle);
       
   288 			CleanupStack::Pop();
       
   289 			bundleOwner->Open();
       
   290 			CleanupClosePushL(*bundleOwner);
       
   291 
       
   292 			// create and send message
       
   293 			TNodeCtxId us(ETierNotificationActivity, NodeId()); //Pretend to be a MM node
       
   294 			RClientInterface::OpenPostMessageClose(us, sp,
       
   295 				TCFTierStatusProvider::TTierNotificationRegistration(bundleOwner, &aMessage).CRef());
       
   296 
       
   297 			CleanupStack::Pop();
       
   298 
       
   299 			// remember client request
       
   300 			iNotificationActive = ETrue;
       
   301 			iNotificationMessage = aMessage;
       
   302 			}
       
   303 			break;
       
   304 
       
   305 
       
   306 		case ECMAccessPointNotification_AwaitThenGetResultOrSize:
       
   307 			{
       
   308 			// ensure already active but no outstanding request. Should be guarded by client side code
       
   309 			if (!iNotificationActive)
       
   310 			    {
       
   311 			    CompleteMessage(aMessage, KErrNotReady);
       
   312 			    return;
       
   313 			    }
       
   314 
       
   315             if (!iNotificationMessage.IsNull())
       
   316 			    {
       
   317 			    CompleteMessage(aMessage, KErrInUse);
       
   318 			    return;
       
   319 			    }
       
   320 
       
   321 			// pick from queue if anything in it..
       
   322 			if(iNotificationQueue.Count())
       
   323 				{
       
   324 				CRefCountOwnedParameterBundle* bundleOwner = iNotificationQueue[0];
       
   325 				const CConnectionServParameterBundle* queuedNotification = static_cast<const CConnectionServParameterBundle*>(bundleOwner->PtrL());
       
   326 				TInt length = queuedNotification->Length();
       
   327 
       
   328 				if (length > safeMessage.GetDesMaxLengthL(1))
       
   329 					{
       
   330 					// we're gonna need a bigger boat
       
   331 					CompleteMessage(aMessage, length);
       
   332 					}
       
   333 				else
       
   334 					{
       
   335 					iNotificationQueue.Remove(0);
       
   336 					CleanupClosePushL(*bundleOwner);
       
   337 					RBuf8 buffer;
       
   338 					buffer.CreateL(length);
       
   339 					CleanupClosePushL(buffer);
       
   340 					User::LeaveIfError(queuedNotification->Store(buffer));
       
   341 					aMessage.WriteL(1, buffer);
       
   342 					CompleteMessage(aMessage,KErrNone);
       
   343 					CleanupStack::PopAndDestroy(&buffer);
       
   344 					CleanupStack::PopAndDestroy(bundleOwner); // close ref on bundle
       
   345 					}
       
   346 				}
       
   347 			else // we have to wait for a notification coming back from the tier so park the request
       
   348 				{
       
   349 				iNotificationMessage = aMessage;
       
   350 				}
       
   351 
       
   352 			}
       
   353 			break;
       
   354 
       
   355 
       
   356 		case ECMAccessPointNotification_GetResult:
       
   357 			{
       
   358 			if (!iNotificationActive || iNotificationQueue.Count() == 0)
       
   359 			    {
       
   360 			    CompleteMessage(aMessage, KErrNotReady);
       
   361 			    return;
       
   362 			    }
       
   363 
       
   364 			CRefCountOwnedParameterBundle* bundleOwner = iNotificationQueue[0];
       
   365 			const CConnectionServParameterBundle* queuedNotification = static_cast<const CConnectionServParameterBundle*>(bundleOwner->PtrL());
       
   366 			iNotificationQueue.Remove(0);
       
   367 			CleanupClosePushL(*bundleOwner);
       
   368 			TInt length = queuedNotification->Length();
       
   369 
       
   370 			// we should only be calling this after a realloc on the client side.
       
   371 			//  so there should be no way the bundle won't fit
       
   372 			if (length > safeMessage.GetDesMaxLengthL(1))
       
   373 			    {
       
   374 			    CompleteMessage(aMessage, KErrOverflow);
       
   375 			    CleanupStack::PopAndDestroy(&bundleOwner);
       
   376 			    return;
       
   377 			    }
       
   378 
       
   379 			RBuf8 buffer;
       
   380 			buffer.CreateL(length);
       
   381 			CleanupClosePushL(buffer);
       
   382 			User::LeaveIfError(queuedNotification->Store(buffer));
       
   383 			aMessage.WriteL(1, buffer);
       
   384 			CompleteMessage(aMessage, KErrNone);
       
   385 			CleanupStack::PopAndDestroy(&buffer);
       
   386 			CleanupStack::PopAndDestroy(bundleOwner); // close ref on bundle
       
   387 			}
       
   388 			break;
       
   389 
       
   390 
       
   391 		case ECMAccessPointNotification_Cancel:
       
   392 			{
       
   393 			// complete the original IPC
       
   394 			if (!iNotificationActive)
       
   395 			    {
       
   396 			    // nothing to cancel
       
   397 			    CompleteMessage(aMessage, KErrNone);
       
   398 			    return;
       
   399 			    }
       
   400 			if (!iNotificationMessage.IsNull())
       
   401 			    {
       
   402 			    //TODO RZ we should really panic the client here.
       
   403 			    //raising a defect to do this.
       
   404 			    CompleteMessage(iNotificationMessage, KErrCancel);
       
   405 			    }
       
   406 
       
   407 			// create and send message
       
   408 			TNodeCtxId us(ETierNotificationActivity, NodeId()); //Pretend to be a MM node
       
   409 			__ASSERT_DEBUG(ServiceProvider()!=Messages::TNodeId::NullId(),User::Panic(KConnectionSessionPanic,EExpectedServiceProvider));
       
   410 			RClientInterface::OpenPostMessageClose(us, ServiceProviderL(), TEBase::TCancel().CRef());
       
   411 
       
   412 			// splat the queue
       
   413 			iNotificationQueue.ResetAndDestroy();
       
   414 
       
   415 			// we'll complete when we get the response.
       
   416 			iNotificationMessage = aMessage;
       
   417 			}
       
   418 			break;
       
   419 
       
   420         case ECMApiExtBindIface:
       
   421         	CommsApiExtBindIfaceL(aMessage);
       
   422         	break;
       
   423 		case ECMApiExtIfaceSend:
       
   424         case ECMApiExtIfaceSendReceive:
       
   425 			CommsApiExtIfaceSendReceiveL(aMessage);
       
   426 			break;
       
   427 		case ECMApiExtIfaceClose:
       
   428 			CloseExtensionInterface(aMessage);
       
   429 			break;
       
   430 
       
   431 
       
   432 		default:
       
   433 			CompleteMessage(aMessage,KErrNotSupported);
       
   434 		}
       
   435 	}
       
   436 
       
   437 void CConnectionSession::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage)
       
   438 /**
       
   439 Entry point to CConnectionSession node
       
   440 */
       
   441 	{
       
   442     // void to remove build warning
       
   443     (void)aSender;
       
   444 
       
   445 	if ( aMessage.IsMessage<TEBase::TError>() )
       
   446 		{
       
   447 		TUint16 activityId = address_cast<TNodeCtxId>(&aRecipient)? address_cast<TNodeCtxId>(aRecipient).NodeCtx() : KActivityNull;
       
   448         ProcessError(activityId, aMessage);
       
   449 		}
       
   450 	else if ( aMessage.IsMessage<TCFTierStatusProvider::TTierStatus>() )
       
   451 	    {
       
   452 		HandleTierStatus(aMessage);
       
   453 		}
       
   454 	else if ( aMessage.IsMessage<TCFTierStatusProvider::TTierNotification>() )
       
   455 		{
       
   456 		HandleTierNotification(aMessage);
       
   457 		}
       
   458 	else if ( aMessage.IsMessage<TCFFactory::TPeerFoundOrCreated>() )
       
   459 		{
       
   460 		TCFFactory::TPeerFoundOrCreated& msg = message_cast<TCFFactory::TPeerFoundOrCreated>(aMessage);
       
   461 		AttachToTierManager(msg.iNodeId);
       
   462 		}
       
   463 	else if ( aMessage.IsMessage<TCFServiceProvider::TJoinComplete>() )
       
   464 		{
       
   465 		__ASSERT_DEBUG(aSender == iTierManager, User::Panic(KSpecAssert_ESockSSockscnctn, 8));
       
   466 		CompleteMessage(iAttachMessage, KErrNone);
       
   467 		}
       
   468 	else
       
   469 		{
       
   470 		LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CConnectionSession(%08x):\tReceivedL - Unexpected message"), this));
       
   471 		__ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 9));
       
   472 		}
       
   473 	aMessage.ClearMessageId();
       
   474 	}
       
   475 
       
   476 
       
   477 
       
   478 void CConnectionSession::HandleTierStatus(const Messages::TSignatureBase& aCFMessage)
       
   479     {
       
   480 	const TCFTierStatusProvider::TTierStatus& msg = message_cast<const TCFTierStatusProvider::TTierStatus>(aCFMessage);
       
   481 
       
   482 	CRefCountOwnedParameterBundle* bundle = msg.iBundle;
       
   483 	if( bundle == NULL || bundle->Ptr() == NULL)
       
   484 		{
       
   485 		__CFLOG_VAR((KTierTag,KConnServSubTag,_L8("Null bundle received. Discarding it.")));
       
   486 		if(bundle)
       
   487 			{
       
   488 			bundle->Close();
       
   489 			}
       
   490 		return;
       
   491 		}
       
   492 
       
   493     const CConnectionServParameterBundle& statusBundle = *static_cast<const CConnectionServParameterBundle*>(bundle->Ptr());
       
   494 	if (iStatusMessage.IsNull())
       
   495 		{
       
   496 		_LOG_BUNDLE("Received status bundle when no outstanding request.", &statusBundle);
       
   497 		// shouldn't have received this.
       
   498 		__ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 10));
       
   499 		// swallow it in release mode
       
   500 
       
   501 		bundle->Close();
       
   502 		return;
       
   503 		}
       
   504 
       
   505 	TInt function = iStatusMessage.Function();
       
   506 	switch (function)
       
   507 		{
       
   508 		case ECMAccessPointStatusQuery_DoThenGetResultOrSize:
       
   509 			{
       
   510 			__ASSERT_DEBUG(iStatusBundle == NULL, User::Panic(KSpecAssert_ESockSSockscnctn, 11));
       
   511 
       
   512 			TInt length = statusBundle.Length();
       
   513 
       
   514             const Den::RSafeMessage& safeStatusMessage(static_cast<const Den::RSafeMessage&>(iStatusMessage));
       
   515 			if (length > safeStatusMessage.GetDesMaxLengthL(1))
       
   516 				{
       
   517 				// we're gonna need a bigger boat
       
   518 				iStatusBundle = msg.iBundle;
       
   519 				CompleteMessage(iStatusMessage, length);
       
   520 				}
       
   521 			else
       
   522 				{
       
   523 				RBuf8 buffer;
       
   524 				TInt err = buffer.Create(length);
       
   525 				if (err == KErrNone)
       
   526 				    {
       
   527     				err = statusBundle.Store(buffer);
       
   528     				if (err == KErrNone)
       
   529     				    {
       
   530         				err = iStatusMessage.Write(1, buffer);
       
   531     				    }
       
   532 				    }
       
   533 				CompleteMessage(iStatusMessage, err);
       
   534 				buffer.Close();
       
   535 				msg.iBundle->Close();
       
   536 				}
       
   537 			}
       
   538 			break;
       
   539 
       
   540 		case ECMAccessPointStatusQuery_Cancel:
       
   541 			__CFLOG_VAR((KTierTag,KConnServSubTag,_L8("Received bundle when already cancelling. Discarding it.")));
       
   542 			msg.iBundle->Close();
       
   543 			break;
       
   544 
       
   545 		case ECMAccessPointStatusQuery_GetResult:
       
   546 		default:
       
   547 		    // Consume the bundle if we didn't expect it
       
   548 			msg.iBundle->Close();
       
   549 			__ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 12));
       
   550 		}
       
   551     }
       
   552 
       
   553 
       
   554 void CConnectionSession::HandleTierNotification(const Messages::TSignatureBase& aCFMessage)
       
   555     {
       
   556 	const TCFTierStatusProvider::TTierNotification& msg = message_cast<const TCFTierStatusProvider::TTierNotification>(aCFMessage);
       
   557 
       
   558 	CRefCountOwnedParameterBundle* bundle = msg.iBundle;
       
   559 	if( bundle == NULL || bundle->Ptr() == NULL)
       
   560 		{
       
   561 		__CFLOG_VAR((KTierTag,KConnServSubTag,_L8("Null bundle received. Discarding it.")));
       
   562 		if(bundle)
       
   563 			{
       
   564 			bundle->Close();
       
   565 			}
       
   566 		return;
       
   567 		}
       
   568 
       
   569 	const CConnectionServParameterBundle* newNotification = static_cast<const CConnectionServParameterBundle*>(bundle->Ptr());
       
   570 
       
   571 	if (!iNotificationActive)
       
   572 		{
       
   573 		// shouldn't have received this.
       
   574 		__ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 13));
       
   575 		// swallow it in production mode
       
   576 		// RJL log here
       
   577 		msg.iBundle->Close();
       
   578 		return;
       
   579 		}
       
   580 
       
   581 	TInt function = iNotificationMessage.Function();
       
   582 	if (iNotificationMessage.IsNull())
       
   583 		{
       
   584 		iNotificationQueue.Append(msg.iBundle);
       
   585 		}
       
   586 	else
       
   587 		{
       
   588 		switch (function)
       
   589 			{
       
   590 			case ECMAccessPointNotification_SetupThenAwaitThenGetResultOrSize:
       
   591 			case ECMAccessPointNotification_AwaitThenGetResultOrSize:
       
   592 				{
       
   593 				__ASSERT_DEBUG(iNotificationQueue.Count() == 0, User::Panic(KSpecAssert_ESockSSockscnctn, 14));
       
   594 
       
   595 				TInt length = newNotification->Length();
       
   596 
       
   597                 const Den::RSafeMessage& safeNotificationMessage(static_cast<const Den::RSafeMessage&>(iNotificationMessage));
       
   598 				if (length > safeNotificationMessage.GetDesMaxLengthL(1))
       
   599 					{
       
   600 					// we're gonna need a bigger boat
       
   601 					iNotificationQueue.Append(msg.iBundle);
       
   602 					CompleteMessage(iNotificationMessage, length);
       
   603 					}
       
   604 				else
       
   605 					{
       
   606 					RBuf8 buffer;
       
   607 					TInt err = buffer.Create(length);
       
   608 					if (err == KErrNone)
       
   609 					    {
       
   610 					    err = newNotification->Store(buffer);
       
   611 					    if (err == KErrNone)
       
   612 					        {
       
   613         					err = iNotificationMessage.Write(1, buffer);
       
   614 					        }
       
   615 					    }
       
   616 					CompleteMessage(iNotificationMessage, err);
       
   617     				buffer.Close();
       
   618 
       
   619 					msg.iBundle->Close();
       
   620 					}
       
   621 				}
       
   622 				break;
       
   623 
       
   624 			case ECMAccessPointNotification_Cancel:
       
   625 				// swallow it. RJL log here
       
   626 				msg.iBundle->Close();
       
   627 				break;
       
   628 
       
   629 			case ECMAccessPointNotification_GetResult:
       
   630 			default:
       
   631         		msg.iBundle->Close();
       
   632 				__ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 15));
       
   633 			}
       
   634 		}
       
   635     }
       
   636 
       
   637 
       
   638 // error from comms framework
       
   639 //
       
   640 void CConnectionSession::ProcessError(TUint16 aActId, Messages::TSignatureBase& aCFMessage)
       
   641 	{
       
   642 	TEBase::TError& inMsg = message_cast<TEBase::TError>(aCFMessage);
       
   643 
       
   644 	if (inMsg.iMsgId == TCFFactory::TFindOrCreatePeer::Id())
       
   645 	    {
       
   646 	    __ASSERT_DEBUG(!iAttachMessage.IsNull(), User::Panic(KSpecAssert_ESockSSockscnctn, 16));
       
   647 	    CompleteMessage(iAttachMessage, inMsg.iValue);
       
   648 	    }
       
   649 	else
       
   650 	    {
       
   651     	TInt errCode = inMsg.iValue;
       
   652     	ProcessError(aActId, errCode);
       
   653 	    }
       
   654 	}
       
   655 
       
   656 
       
   657 void CConnectionSession::ProcessError(TUint16 aActId, TInt aErrCode)
       
   658 	{
       
   659 	switch(aActId)
       
   660 		{
       
   661 		case ETierStatusActivity:
       
   662 			{
       
   663 			__ASSERT_DEBUG( ! iStatusMessage.IsNull(), User::Panic(KSpecAssert_ESockSSockscnctn, 17));
       
   664 			switch(iStatusMessage.Function())
       
   665 				{
       
   666 				case ECMAccessPointStatusQuery_DoThenGetResultOrSize:
       
   667 				case ECMAccessPointStatusQuery_Cancel:
       
   668 					__ASSERT_DEBUG(iStatusBundle == 0, User::Panic(KSpecAssert_ESockSSockscnctn, 18));
       
   669 					// haven't yet allocated anything..
       
   670 					//  so complete with the error code.
       
   671 					CompleteMessage(iStatusMessage,aErrCode);
       
   672 					break;
       
   673 
       
   674 				case ECMAccessPointStatusQuery_GetResult:
       
   675 				default:
       
   676 					__CFLOG_VAR((KTierTag,KConnServSubTag,_L8("Unexpected state: outstanding IRC: cancel, TCFMsg: error %d"),aErrCode));
       
   677 					__ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 19));
       
   678 				}
       
   679 			}
       
   680 			break;
       
   681 
       
   682 		case ETierNotificationActivity:
       
   683 			{
       
   684 			if (iNotificationMessage.IsNull())
       
   685 			    {
       
   686 			    //TODO RZ This is all wrong and the bad clients need panicked
       
   687 			    //raising a defect.
       
   688                 iNotificationQueue.ResetAndDestroy();
       
   689 			    }
       
   690 			else
       
   691 			    {
       
   692                 switch(iNotificationMessage.Function())
       
   693                     {
       
   694                     case ECMAccessPointNotification_SetupThenAwaitThenGetResultOrSize:
       
   695                     case ECMAccessPointNotification_AwaitThenGetResultOrSize:
       
   696                     case ECMAccessPointNotification_Cancel:
       
   697                         // ok, delete queue in case we didn't already..
       
   698                         iNotificationQueue.ResetAndDestroy();
       
   699                         CompleteMessage(iNotificationMessage,aErrCode);
       
   700                         break;
       
   701     
       
   702                     case ECMAccessPointNotification_GetResult:
       
   703                     default:
       
   704                         __CFLOG_VAR((KTierTag,KConnServSubTag,_L8("Unexpected state: outstanding IRC: cancel, TCFMsg: error %d"),aErrCode));
       
   705                         __ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 20));
       
   706                     }
       
   707 			    }
       
   708 			iNotificationActive = EFalse;
       
   709 			}
       
   710 			break;
       
   711 
       
   712 		default:
       
   713 			// eek! shouldn't be receiving anything to any other activity
       
   714 			__ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnctn, 21));
       
   715 		}
       
   716 	}
       
   717 
       
   718 
       
   719 void CConnectionSession::StartAttachToTierManager(const RMessage2& aMessage)
       
   720 	{
       
   721 	if(	iNotificationActive ||
       
   722 		! iNotificationMessage.IsNull() ||
       
   723 		! iStatusMessage.IsNull())
       
   724 		{
       
   725     	CompleteMessage(aMessage, KErrInUse);
       
   726 		}
       
   727 
       
   728     CSockManData* globals = SockManGlobals::Get();
       
   729     const TNodeId tmfc = globals->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::ETierMgrPlane));
       
   730     if (tmfc.IsNull())
       
   731         {
       
   732         LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CConnectionSession(%08x):\tStartAttachToTierManager - No TierMgr FC"), this));
       
   733 
       
   734         // If the tier manager FC is null, and esock has completed booting something is very wrong.
       
   735         __ASSERT_DEBUG(globals->iWorkerThread && !globals->iWorkerThread->PitBoss().ModuleConfigurationComplete(), User::Panic(KSpecAssert_ESockSSockscnctn, 22));
       
   736 
       
   737         // Someone is trying to use the Connection Server before esock has finished booting
       
   738 		ParkIfIndeterminateRequest(aMessage, KErrNotFound);
       
   739         return;
       
   740         }
       
   741 
       
   742     iAttachMessage = aMessage;
       
   743     LeaveServiceProvider();
       
   744     TAlwaysFindFactoryQuery query;
       
   745 	RClientInterface::OpenPostMessageClose(Id(), tmfc,
       
   746 		TCFFactory::TFindOrCreatePeer(TCFPlayerRole::ETierMgrPlane, TUid::Uid(aMessage.Int0()), &query).CRef());
       
   747 	}
       
   748 
       
   749 void CConnectionSession::AttachToTierManager(const TNodeId& aTierMgrFactory)
       
   750     {
       
   751 	iTierManager = aTierMgrFactory;
       
   752 	RClientInterface::OpenPostMessageClose(Id(), iTierManager,
       
   753 		TCFServiceProvider::TJoinRequest(Id(), TCFClientType::ECtrl).CRef());
       
   754     }
       
   755 
       
   756 void CConnectionSession::LeaveServiceProvider()
       
   757 	{
       
   758 	const TNodeId& sp = ServiceProvider();
       
   759 
       
   760 	if(!sp.IsNull())
       
   761 		{
       
   762 		const TNodeId& selfId(NodeId());
       
   763 		RClientInterface::OpenPostMessageClose(selfId, sp, TEChild::TLeft().CRef());
       
   764 		iTierManager.SetNull();
       
   765 		}
       
   766 	}
       
   767 
       
   768 
       
   769 void CConnectionSession::CommsApiExtBindIfaceL(const RMessage2& aMessage)
       
   770 	{
       
   771 	const Messages::TNodeId& sp = ServiceProvider();
       
   772 	if(!sp.IsNull())
       
   773 		{
       
   774 		TSupportedCommsApiExt interfaceId = static_cast<TSupportedCommsApiExt>(aMessage.Int0());
       
   775 		sp.PostTo(Id(), TOpenExtensionInterface(UniqueId(), interfaceId, aMessage));
       
   776 		}
       
   777 	}
       
   778 
       
   779 void CConnectionSession::CommsApiExtIfaceSendReceiveL(const RMessage2& aMessage)
       
   780 	{
       
   781 	const Messages::TNodeId& sp = ServiceProvider();
       
   782 	if(!sp.IsNull())
       
   783     	{
       
   784 		Elements::RResponseMsg responseMsg(aMessage, aMessage.Int0(), 1, 2);
       
   785 		sp.PostTo(Id(), TApiExtMsgDispatcher(UniqueId(), responseMsg));
       
   786     	}
       
   787     else
       
   788         {
       
   789         User::Leave(KErrNotReady);
       
   790         }
       
   791 
       
   792 	}
       
   793 
       
   794 void CConnectionSession::CloseExtensionInterface(const RMessage2& aMessage)
       
   795 	{
       
   796 	const Messages::TNodeId& sp = ServiceProvider();
       
   797 	if(!sp.IsNull())
       
   798     	{
       
   799 		TSupportedCommsApiExt interfaceId = static_cast<TSupportedCommsApiExt>(aMessage.Int0());
       
   800 		sp.PostTo(Id(), TCloseExtensionInterface(UniqueId(), interfaceId, aMessage));
       
   801     	}
       
   802 	}
       
   803 
       
   804 void CConnectionSession::CancelAndCloseAllClientExtIfaces()
       
   805 	{
       
   806 	const Messages::TNodeId& sp = ServiceProvider();
       
   807 	if(!sp.IsNull())
       
   808 		{
       
   809 		sp.PostTo(Id(), TCancelAndCloseAllClientExtItf(UniqueId()));
       
   810 		}
       
   811 	}
       
   812 
       
   813 
       
   814 
       
   815