lbs/internal/lbstestserver/src/csecuresessionsubsessionbase.cpp
branchSymbian2
changeset 1 8758140453c0
child 6 c108117318cb
equal deleted inserted replaced
0:e8c1ea2c6496 1:8758140453c0
       
     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 the License "Symbian Foundation License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <e32debug.h>
       
    17 #include "csecuresessionsubsessionbase.h"
       
    18 #include "csubsessionbase.h"
       
    19 #include "lbsmessageenums.h"
       
    20 #include "messageutils.h"
       
    21 #include "lbsdevloggermacros.h"
       
    22 
       
    23 /** 
       
    24 constructor, call the CSecureSessionBase base class constructor
       
    25 
       
    26 @internalTechnology
       
    27 @released
       
    28  */	
       
    29 CSecureSessionSubSessionBase::CSecureSessionSubSessionBase() : CSecureSessionBase()
       
    30 	{
       
    31 	LBSLOG(ELogP3, "CSecureSessionSubSessionBase::CSecureSessionSubSessionBase()");
       
    32 	}
       
    33 
       
    34 /** 
       
    35 destructor, release the subsession handler container
       
    36 
       
    37 @internalTechnology
       
    38 @released
       
    39  */	
       
    40 CSecureSessionSubSessionBase::~CSecureSessionSubSessionBase()
       
    41 	{
       
    42 	LBSLOG(ELogP3, "->CSecureSessionSubSessionBase::~CSecureSessionSubSessionBase()");
       
    43 
       
    44 	if (iObjectIx)
       
    45 		{
       
    46 		TInt count = iObjectIx->Count();
       
    47 		for(TInt i=0; i<count; i++)
       
    48 			{
       
    49 			CObject* theObj = (*iObjectIx)[i];
       
    50 			if (theObj)
       
    51 				{
       
    52 				TInt handle = iObjectIx->At(theObj);
       
    53 				// if we reach here somethingbad has happened. The server class
       
    54 				// (i.e. the session object) is being closed by the client, BEFORE
       
    55 				// the client has closes all of the open subsessions.
       
    56 				// So the only reasonable thingto do here is:
       
    57 				// delete the subsession - without closing it first. 'Cos this is
       
    58 				// _exactly_ what the client side has asked for (for some reason).
       
    59 				// The may or may not be legal, or even a good idea depending on the type of server
       
    60 				// that is being developeds. But the server framework should NOT
       
    61 				// prevent this from happening. Generating a panic is a 
       
    62 				// server developers choice, not a framework developers choice.
       
    63 				// We delete by calling CObjectIdx::Remove(). This will call CObject::Close.
       
    64 				// This in turn calls MSubSessionImpl::MRelease::VirtualRelease
       
    65 				// which will destroy the sub session for us.
       
    66 				// CloseSubSession should not be called directly.
       
    67 				iObjectIx->Remove(handle);
       
    68 				
       
    69 				//
       
    70 				// If the array length has changed, then update count and move back one space,
       
    71 				// so that the same cell will be re-inspected during the next iteration of the
       
    72 				// loop  This is because we have removed the current cell and therefore the
       
    73 				// next cell is actually in iObjectIx[i] (i.e. the current one).
       
    74 				TInt newCount = iObjectIx->Count();
       
    75 				
       
    76 				if (newCount != count)
       
    77 					{
       
    78 					count = newCount;
       
    79 					i--;
       
    80 					}
       
    81 
       
    82 				}
       
    83 			}
       
    84 		delete iObjectIx;
       
    85 		}
       
    86 	if (iContainerIx)
       
    87 		{
       
    88 		iContainerIx->Remove(iObjectCon);
       
    89 		delete iContainerIx;
       
    90 		}
       
    91 	// session decrementing handled in the parent class
       
    92 	LBSLOG(ELogP3, "<-CSecureSessionSubSessionBase::~CSecureSessionSubSessionBase()");
       
    93 	}
       
    94 	
       
    95 /** 
       
    96 called as part of the CSession2 construction. 
       
    97 Create subsession handler container and call the session CreateL function to increase the session count
       
    98 
       
    99 @internalTechnology
       
   100 @released
       
   101  */	
       
   102 void CSecureSessionSubSessionBase::CreateL()
       
   103 	{
       
   104 	LBSLOG(ELogP3, "->CSecureSessionSubSessionBase::CreateL");
       
   105 	iObjectIx = CObjectIx::NewL();
       
   106 	iContainerIx = CObjectConIx::NewL();
       
   107 	iObjectCon = iContainerIx->CreateL();
       
   108 	CSecureSessionBase::CreateL(); // call the parent class to inc the session count
       
   109 	iBaseCreateCalled = ETrue;
       
   110 	LBSLOG(ELogP3, "<-CSecureSessionSubSessionBase::CreateL");
       
   111 	}
       
   112 	
       
   113 /** 
       
   114 Do the real thing for subsession construction.
       
   115 Check whether the session constructL function is called or not first. If not, panic the server,
       
   116 Create a subsession and push it to stack, get the implementation of subsession and invoke the 
       
   117 real subsession creation implementation.
       
   118 
       
   119 Add the subsession handler to container and write the handler to client address space through message object
       
   120 Complete the creating message.
       
   121 
       
   122 @param aMessage A RMessage2 reference.
       
   123 @internalTechnology
       
   124 @released
       
   125  */	
       
   126 void CSecureSessionSubSessionBase::CreateSubSessionL(const RMessage2& aMessage)
       
   127 	{
       
   128 	__ASSERT_ALWAYS(iBaseCreateCalled, Server()->PanicServer(CSecureServerBase::EBaseCreateNotCalled));
       
   129 	CSubSessionBase* subSession = new (ELeave) CSubSessionBase();
       
   130 	// Note: Use the CObject::Close() function instead of usual destructor
       
   131 	// because it is needed to correctly decrement the reference count.
       
   132 	// Close() will destruct subSession anyway if the ref count == 0.
       
   133 	CleanupClosePushL(*subSession);
       
   134 
       
   135 	MSubSessionImpl* impl = subSession->GetImplL(aMessage);
       
   136 	CleanupVirtualReleasePushL(*impl); // call Release() on destruction
       
   137 	//CleanupVirtualRelease::PushL(*impl);
       
   138 	subSession->SetImpl(impl); // will take ownership(!)
       
   139 	CleanupStack::Pop(impl);
       
   140 
       
   141 	// We need to pass a handle to the controllign server down to the subsession object.
       
   142 	// Since the subsession impl object is a CBase object (NOT a CSession2 object)
       
   143 	// we haev to do this outherwise the subsession will not be able to referene the
       
   144 	// server - which seems like a useful thing to do.
       
   145 	const CSecureServerBase* server = reinterpret_cast<const CSecureServerBase*>(Server()); 	
       
   146 	impl->CreateSubSessionL(aMessage, server);
       
   147 	
       
   148 	iObjectCon->AddL(subSession);
       
   149 	TInt handle = iObjectIx->AddL(subSession);
       
   150 	TPckgC<TInt> pH(handle);
       
   151 	MessageUtils::Write(aMessage, 3, pH);
       
   152 	aMessage.Complete(KErrNone);
       
   153 	CleanupStack::Pop(subSession);
       
   154 	}
       
   155 	
       
   156 /** 
       
   157 Do the real thing for subsession destruction.
       
   158 Check whether the session constructL function is called or not first. If not, panic the server,
       
   159 get a subsession handler from container and complete the message if subsession is already close, 
       
   160 if not, close subsession and remove it from container then complete the message.
       
   161 
       
   162 @param aMessage A RMessage2 reference.
       
   163 @internalTechnology
       
   164 @released
       
   165  */	
       
   166 void CSecureSessionSubSessionBase::DestroySubSession(const RMessage2& aMessage)
       
   167 	{
       
   168 	__ASSERT_ALWAYS(iBaseCreateCalled, Server()->PanicServer(CSecureServerBase::EBaseCreateNotCalled));
       
   169 	CSubSessionBase* subSession = reinterpret_cast<CSubSessionBase*>(iObjectIx->At(aMessage.Int3()));
       
   170 	
       
   171 	if (subSession == NULL)
       
   172 		{
       
   173 		aMessage.Complete(KErrBadHandle);
       
   174 		}
       
   175 	else
       
   176 		{
       
   177 		// we have been asked to close a subsession by the client side so
       
   178 		// do just that :). c.f. CSecureSessionSubSessionBase::~CSecureSessionSubSessionBase() above.
       
   179 		// In this case we do need to call CloseSubSession before deleting
       
   180 		// the subsession object.
       
   181 		// We delete by calling CObjectIdx::Remove().This will call CObject::Close.
       
   182 		// This in turn calls MSubSessionImpl::MRelease::VirtualRelease
       
   183 		// which willdestroy the sub session for us.
       
   184 		CSubSessionBase* subSession = static_cast<CSubSessionBase*>(iObjectIx->At(aMessage.Int3()));
       
   185 		iObjectIx->Remove(aMessage.Int3());
       
   186 		aMessage.Complete(KErrNone);
       
   187 		}
       
   188 	}
       
   189 
       
   190 /** 
       
   191 Check whether the session constructL function is called or not first. If not, panic the server,
       
   192 
       
   193 Dispatch the message at session level, only two types of message are handled here:
       
   194 SubSession Open and Close.
       
   195 The other messages are fwd to subsession via DispatchMessage.
       
   196 
       
   197 @param aMessage A RMessage2 reference.
       
   198 @internalTechnology
       
   199 @released
       
   200  */	
       
   201 void CSecureSessionSubSessionBase::DispatchL(const RMessage2& aMessage)
       
   202 	{
       
   203 	__ASSERT_ALWAYS(iBaseCreateCalled, Server()->PanicServer(CSecureServerBase::EBaseCreateNotCalled));
       
   204 	switch(aMessage.Function())
       
   205 		{
       
   206 		case ESecureSubSessionBaseOpen:
       
   207 			CreateSubSessionL(aMessage);
       
   208 			break;
       
   209 		case ESecureSubSessionBaseClose:
       
   210 			DestroySubSession(aMessage);
       
   211 			break;
       
   212 		default:
       
   213 			// the message could be EITHER a session operation - which we have to handle here, or an operation
       
   214 			// handled by the subsession which we have to forward
       
   215 			DispatchMessageL(aMessage);
       
   216 			break;
       
   217 		}
       
   218 		
       
   219 	}
       
   220 
       
   221 /** 
       
   222 Check whether the session constructL function is called or not first. If not, panic the server,
       
   223 
       
   224 Check whether the message are for session or subsession
       
   225 Dispatch the message at subsession level
       
   226 get the subsession handler from container and dispatch the message to subsession implementation!
       
   227 
       
   228 @param aMessage A RMessage2 reference.
       
   229 @internalTechnology
       
   230 @released
       
   231  */	
       
   232 void CSecureSessionSubSessionBase::DispatchMessageL(const RMessage2& aMessage)
       
   233 	{
       
   234 	__ASSERT_ALWAYS(iBaseCreateCalled, Server()->PanicServer(CSecureServerBase::EBaseCreateNotCalled));
       
   235 	// NB the test is intened to ignore a function enum of ELastSessionMessageId - this is not a valid command
       
   236 	if(aMessage.Function()<ELastSessionMessageId)
       
   237 		{
       
   238 		// the message is for the session
       
   239 		ServiceMessageL(aMessage); // implmented in the DERIVED CSessionBase class.
       
   240 		}
       
   241 	else if(aMessage.Function()>ELastSessionMessageId)
       
   242 		{
       
   243 		// MUST be a message for the subsystem object - delegate
       
   244 		CSubSessionBase* subSession = static_cast<CSubSessionBase*>(iObjectIx->At(aMessage.Int3()));
       
   245 		subSession->Impl()->DispatchL(aMessage);
       
   246 		}
       
   247 	}
       
   248 
       
   249 /** 
       
   250 Return the server
       
   251 
       
   252 @return Pointer to server base
       
   253 @internalTechnology
       
   254 @released
       
   255  */	
       
   256 const CSecureServerBase* CSecureSessionSubSessionBase::Server() const
       
   257 	{
       
   258 	return reinterpret_cast<const CSecureServerBase*>(CSession2::Server());
       
   259 	}
       
   260 
       
   261 /** 
       
   262 Check whether the session constructL function is called or not first. If not, panic the server,
       
   263 
       
   264 Dispatch the message at session level, only two types of message are handled here:
       
   265 SubSession Open and Close.
       
   266 If error happened when open subsession, destroy the subsession.
       
   267 
       
   268 otherwise, pop the error messages to session or fwd to subsession via DispatchError.
       
   269 
       
   270 @param aMessage A RMessage2 reference.
       
   271 @param aError Error code.
       
   272 @internalTechnology
       
   273 @released
       
   274  */	
       
   275 void CSecureSessionSubSessionBase::DispatchError(const RMessage2& aMessage, TInt aError)
       
   276 	{
       
   277 	__ASSERT_ALWAYS(iBaseCreateCalled, Server()->PanicServer(CSecureServerBase::EBaseCreateNotCalled));
       
   278 	CSubSessionBase* subSession = NULL;
       
   279 	switch(aMessage.Function())
       
   280 		{
       
   281 		case ESecureSubSessionBaseOpen:
       
   282 			if(aError == KErrArgument)
       
   283 				{
       
   284 				// panic the client we have NO idea what sort
       
   285 				// of sub session class the user was tryign to create. 
       
   286 				// This is a client side failure!, so shoot the client
       
   287 				MessageUtils::PanicClient(aMessage, KServerFrameworkPanic, ESecureSubSessionBaseUnknownSubSessionType);
       
   288 				// NB there is NOTHING to clean up here, everything is deleted via
       
   289 				// the cleanup stack, and the subsession object was never added to the
       
   290 				// obejct containers.... See CreateSubSessionL above
       
   291 				}
       
   292 			else
       
   293 				{
       
   294 				// CreateSubSessionL() has caused a Leave, so there is 
       
   295 				// no sub session object to clear up - just complete the
       
   296 				// message with an error
       
   297 				aMessage.Complete(aError);
       
   298 				}
       
   299 			break;
       
   300 		case ESecureSubSessionBaseClose:
       
   301 			// Panic? Non-leaving function that just left?
       
   302 			break;
       
   303 		default:
       
   304 			// DisplatchMessageL above has left - this could be becuase ServiceMessageL left or the subsession DisplatchL
       
   305 			// NB the test is intened to ignore a function enum of ELastSessionMessageId - this is not a valid command
       
   306 			if(aMessage.Function()<ELastSessionMessageId)
       
   307 				{
       
   308 				// the message is for the session
       
   309 				ServiceMessageError(aMessage, aError); // implmented in the DERIVED CSessionBase class.
       
   310 				}
       
   311 			else if(aMessage.Function()>ELastSessionMessageId)
       
   312 				{
       
   313 				// MUST be a message for the subsystem object - delegate
       
   314 				subSession = static_cast<CSubSessionBase*>(iObjectIx->At(aMessage.Int3()));
       
   315 				subSession->Impl()->DispatchError(aMessage, aError);
       
   316 				}
       
   317 			break;
       
   318 		}
       
   319 	}