datacommsserver/esockserver/ssock/ss_subconnflow.cpp
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2004-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 #include "ss_subconnflow.h"
       
    16 
       
    17 
       
    18 #include <comms-infras/ss_log.h>
       
    19 #include <comms-infras/ss_mcprnodemessages.h>
       
    20 #include <comms-infras/ss_protflow.h>
       
    21 #include <es_ini.h>
       
    22 #include <ss_glob.h>
       
    23 #include <ss_protprov.h>
       
    24 #include <comms-infras/ss_sapshim.h>
       
    25 #include "ss_sapfactshim.h"
       
    26 #include <elements/cftransport.h>
       
    27 #include <ecom/ecom.h>
       
    28 #include <elements/nm_messages_child.h>
       
    29 
       
    30 #include <comms-infras/ss_nodemessages_factory.h>
       
    31 
       
    32 
       
    33 #ifdef _DEBUG
       
    34 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
       
    35 // (if it could happen through user error then you should give it an explicit, documented, category + code)
       
    36 _LIT(KSpecAssert_ESockSSocksbcnfl, "ESockSSocksbcnfl");
       
    37 #endif
       
    38 
       
    39 using namespace ESock;
       
    40 using namespace Messages;
       
    41 using namespace CommsFW;
       
    42 using namespace Factories;
       
    43 
       
    44 
       
    45 //-=====================================================================
       
    46 //
       
    47 //
       
    48 // CSubConnectionFlowFactoryContainer
       
    49 //
       
    50 //
       
    51 //-=====================================================================
       
    52 CSubConnectionFlowFactoryContainer::CSubConnectionFlowFactoryContainer()
       
    53 :CCommsFactoryContainer((CCommsFactoryContainer::TContaineeType)CSubConnectionFlowFactoryContainer::EId)
       
    54 	{
       
    55 	LOG_NODE_CREATE(KESockDataFactTag, CSubConnectionFlowFactoryContainer)
       
    56 	}
       
    57 
       
    58 CSubConnectionFlowFactoryContainer::~CSubConnectionFlowFactoryContainer()
       
    59 	{
       
    60 	TCFLegacyMessage::DeRegister();
       
    61 	LOG_NODE_DESTROY(KESockDataFactTag, CSubConnectionFlowFactoryContainer)
       
    62 	}
       
    63 
       
    64 CSubConnectionFlowFactoryContainer* CSubConnectionFlowFactoryContainer::NewL()
       
    65 /** Create a new instance of a sub-connection factory container
       
    66 
       
    67 @exception Leaves in out of memory conditions
       
    68 @return Pointer to new instance of a sub-connection factory container
       
    69 */
       
    70 	{
       
    71 	using namespace CommsFW;
       
    72 	LOG( ESockLog::Printf(KESockDataFactTag, _L8("CSubConnectionFlowFactoryContainer:\tNewL()")) );
       
    73 
       
    74 	// For the self-dispatching TLegacyConnectionEnumRequest
       
    75 	TCFLegacyMessage::RegisterL();
       
    76 
       
    77 	CSubConnectionFlowFactoryContainer* provcont = new (ELeave) CSubConnectionFlowFactoryContainer();
       
    78 	CleanupStack::PushL(provcont);
       
    79 	CTransportFlowShimFactory::NewL(TUid::Uid(CTransportFlowShimFactory::iUid), *provcont);
       
    80 	CleanupStack::Pop(provcont);
       
    81 	return provcont;
       
    82 	}
       
    83 
       
    84 void CSubConnectionFlowFactoryContainer::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& /*aRecipient*/, TSignatureBase& aMessage)
       
    85 	{
       
    86 	if (aMessage.IsMessage<TCFFactory::TFindOrCreatePeer>())
       
    87 		{
       
    88 		TCFFactory::TFindOrCreatePeer& msg = message_cast<TCFFactory::TFindOrCreatePeer>(aMessage);
       
    89 		CCommsFactoryBase* factory = static_cast<CCommsFactoryBase*>(FindOrCreateFactoryL(msg.iUid));
       
    90         ACommsFactoryNodeId* flow = factory->FindOrCreateObjectL(*(msg.iQuery));
       
    91 
       
    92         // Send "DataClientJoined"
       
    93    #ifndef __GCCXML__
       
    94    	    RClientInterface::OpenPostMessageClose(Id(), aSender,
       
    95    	    	TCFFactory::TPeerFoundOrCreated(flow? flow->Id() : TNodeId::NullId(), 0).CRef());
       
    96    #endif
       
    97         aMessage.ClearMessageId();
       
    98 		}
       
    99 	else
       
   100 		{
       
   101 		NM_LOG_START_BLOCK(KESockMetaConnectionTag, _L8("CSubConnectionFlowFactoryContainer:ReceivedL"));
       
   102 		NM_LOG((KESockMetaConnectionTag, _L8("ERROR: KErrNotSupported [this=0x%08x] "), this));
       
   103 		NM_LOG_MESSAGE(KESockMetaConnectionTag, aMessage);
       
   104         NM_LOG_END_BLOCK(KESockMetaConnectionTag, _L8("CSubConnectionFlowFactoryContainer:ReceivedL"));
       
   105 
       
   106 		__ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockSSocksbcnfl, 1)); //For debug configurations
       
   107 		User::Leave(KErrNotSupported); //For release configurations
       
   108 		}
       
   109 	}
       
   110 
       
   111 
       
   112 
       
   113 //-=====================================================================
       
   114 //
       
   115 //
       
   116 // CSubConnectionFlowFactoryBase
       
   117 //
       
   118 //
       
   119 //-=====================================================================
       
   120 EXPORT_C CSubConnectionFlowFactoryBase::CSubConnectionFlowFactoryBase(TUid aFactoryId, CSubConnectionFlowFactoryContainer& aParentContainer)
       
   121 /** Sub-connection flow factory constructor
       
   122 
       
   123 @param aFactoryId Unique Integer Identifier of the sub-connection provider factory
       
   124 @param aParentContainer Container to add the factory to */
       
   125 	: CCommsFactoryBase(aFactoryId, aParentContainer)
       
   126 	{
       
   127 	}
       
   128 
       
   129 EXPORT_C ACommsFactoryNodeId* CSubConnectionFlowFactoryBase::DoCreateObjectL(TFactoryQueryBase& aQuery)
       
   130 	{
       
   131 	const TDefaultFlowFactoryQuery& flowQuery = static_cast<const TDefaultFlowFactoryQuery&>(aQuery);
       
   132 	TDefaultProtocolIntfFactoryQuery pintfQuery (flowQuery.iCprId);
       
   133 
       
   134 	CProtocolIntfBase* proto = SockManGlobals::Get()->iProtocolIntfFactories->FindOrCreateProtocolIntfL(Uid(), pintfQuery);
       
   135 	if (NULL == proto)
       
   136     	{
       
   137     	LOG( ESockLog::Printf(KESockDataFactTag, _L8("CSubConnectionFlowFactoryBase %08x:\tCreateFlowL(protocolId '%08x') Cannot find protocol interface, bailing out"), this, Uid()) );
       
   138     	User::Leave(KErrNotFound);
       
   139     	}
       
   140     // A null CPR indicates that there is no real control side at all, meaning it's a legacy protocol and the FlowRequest is puppeteering this
       
   141     // creation. In such a case we must be creating a CTransportFlowShim, which understands that a null SCPR is to be ignored
       
   142     __ASSERT_DEBUG(!flowQuery.iCprId.IsNull() || proto->Factory().Uid().iUid == CTransportFlowShimFactory::iUid, User::Panic(KSpecAssert_ESockSSocksbcnfl, 2));
       
   143     ACommsFactoryNodeId* flow = DoCreateFlowL(proto, aQuery);
       
   144 	LOG( ESockLog::Printf(KESockDataFactTag, _L8("CSubConnectionFlowFactoryBase %08x:\tCreateFlowL(protocolId '%08x'): flow %08x"), this, Uid(), &flow) );
       
   145 	return flow;
       
   146 	}
       
   147 
       
   148 EXPORT_C TServerProtocolDesc* CSubConnectionFlowFactoryBase::CreateFlowDescriptionL(TInt aProtocol)
       
   149 	{
       
   150 	// Defer to derived implementation
       
   151 	return DoCreateFlowDescriptionL(aProtocol);
       
   152 	}
       
   153 
       
   154 EXPORT_C TServerProtocolDesc* CSubConnectionFlowFactoryBase::DoCreateFlowDescriptionL(TInt /*aProtocol*/)
       
   155 	{
       
   156 	__ASSERT_DEBUG(0, Panic(EMisconfigured));
       
   157 	User::Leave(KErrNotSupported);
       
   158 	return NULL;
       
   159 	}
       
   160 
       
   161 EXPORT_C CSubConnectionFlowFactoryBase::~CSubConnectionFlowFactoryBase()
       
   162 	{
       
   163 	}
       
   164 
       
   165 
       
   166 
       
   167 //-=====================================================================
       
   168 // Default PINT
       
   169 //-=====================================================================
       
   170 class CDefaultProtocolIntf : public CProtocolIntfBase
       
   171 /**
       
   172 This is the internal, dummy, default CProtocolIntfBase implementation
       
   173 that will by default accompany any flow unless the flow factory
       
   174 decides to overload its CreateProtocolIntfFactoryL method.
       
   175 
       
   176 @internalTechnology
       
   177 */
       
   178 	{
       
   179 public:
       
   180 	CDefaultProtocolIntf(CProtocolIntfFactoryBase& aFactory,const Messages::TNodeId& aCprId);
       
   181 
       
   182 	// from CProtocolIntfBase
       
   183 	virtual void DoFlowCreated(ESock::CSubConnectionFlowBase& aFlow);
       
   184 	virtual void DoFlowBeingDeleted(ESock::CSubConnectionFlowBase& aFlow);
       
   185 	};
       
   186 
       
   187 class CDefaultProtocolIntfFactory : public CProtocolIntfFactoryBase
       
   188 /**
       
   189 This is the internal, dummy, default CProtocolIntfBase implementation
       
   190 that will by default accompany any flow unless the flow factory
       
   191 decides to overload its CreateProtocolIntfFactoryL method.
       
   192 
       
   193 @internalTechnology
       
   194 */
       
   195 	{
       
   196 public:
       
   197 	virtual CProtocolIntfBase* DoCreateProtocolIntfL(TFactoryQueryBase& aQuery);
       
   198 	static CDefaultProtocolIntfFactory* NewL(TUid aFactoryId, ESock::CProtocolIntfFactoryContainer& aParentContainer);
       
   199 protected:
       
   200 	CDefaultProtocolIntfFactory(TUid aFactoryId, ESock::CProtocolIntfFactoryContainer& aParentContainer);
       
   201 	};
       
   202 CDefaultProtocolIntfFactory* CDefaultProtocolIntfFactory::NewL(TUid aFactoryId, ESock::CProtocolIntfFactoryContainer& aParentContainer)
       
   203 	{
       
   204     CDefaultProtocolIntfFactory* factory = new (ELeave) CDefaultProtocolIntfFactory(aFactoryId, aParentContainer);
       
   205     CleanupStack::PushL(factory);
       
   206     factory->ConstructL();
       
   207     CleanupStack::Pop(factory);
       
   208     return factory;
       
   209 	}
       
   210 
       
   211 CDefaultProtocolIntf::CDefaultProtocolIntf(CProtocolIntfFactoryBase& aFactory,const Messages::TNodeId& aCprId)
       
   212 :CProtocolIntfBase(aFactory,aCprId)
       
   213     {
       
   214     }
       
   215 
       
   216 void CDefaultProtocolIntf::DoFlowCreated(ESock::CSubConnectionFlowBase& /*aFlow*/)
       
   217     {
       
   218     }
       
   219 
       
   220 void CDefaultProtocolIntf::DoFlowBeingDeleted(ESock::CSubConnectionFlowBase& /*aFlow*/)
       
   221     {
       
   222     }
       
   223 
       
   224 CProtocolIntfBase* CDefaultProtocolIntfFactory::DoCreateProtocolIntfL(TFactoryQueryBase& aQuery)
       
   225     {
       
   226     const TDefaultProtocolIntfFactoryQuery& query = static_cast<const TDefaultProtocolIntfFactoryQuery&>(aQuery);
       
   227     return new (ELeave) CDefaultProtocolIntf(*this,query.iCprId);
       
   228     }
       
   229 
       
   230 CDefaultProtocolIntfFactory::CDefaultProtocolIntfFactory(TUid aFactoryId, CProtocolIntfFactoryContainer& aParentContainer)
       
   231 :	CProtocolIntfFactoryBase(aFactoryId, aParentContainer)
       
   232     {
       
   233 	}
       
   234 
       
   235 EXPORT_C CProtocolIntfFactoryBase* CSubConnectionFlowFactoryBase::CreateProtocolIntfFactoryL(CProtocolIntfFactoryContainer& aParentContainer)
       
   236     {
       
   237     return CDefaultProtocolIntfFactory::NewL (Uid(), aParentContainer);
       
   238     }
       
   239 
       
   240 
       
   241 //-=====================================================================
       
   242 //
       
   243 //
       
   244 // CSubConnectionFlowBase
       
   245 //
       
   246 //
       
   247 //-=====================================================================
       
   248 EXPORT_C CSubConnectionFlowBase::CSubConnectionFlowBase(CSubConnectionFlowFactoryBase& aFactory, const TNodeId& aSubConnId,
       
   249                                                         CProtocolIntfBase* aProtocolIntf)
       
   250 :	ACommsFactoryNodeId(aFactory),
       
   251 	iProtocolIntf(aProtocolIntf)
       
   252 	{
       
   253 	__ASSERT_DEBUG(iProtocolIntf, User::Panic(KSpecAssert_ESockSSocksbcnfl, 3));
       
   254     iSubConnectionProvider.Open(aSubConnId);
       
   255 	// Signal the ProtocolIntf that a Flow has been created.
       
   256 	iProtocolIntf->FlowCreated(*this);
       
   257 	}
       
   258 
       
   259 EXPORT_C CSubConnectionFlowBase::~CSubConnectionFlowBase()
       
   260 	{
       
   261 	if(iLastRequestOriginator.IsOpen())
       
   262 		{
       
   263 		iLastRequestOriginator.ReplyTo(Id(), TEChild::TLeft().CRef());
       
   264 		}
       
   265     iProtocolIntf->FlowBeingDeleted(*this);
       
   266 	LOG( ESockLog::Printf(KESockDataFactTag, _L8("CSubConnectionFlowBase %08x:\t~CSubConnectionFlowBase"), this) );
       
   267 	}
       
   268 
       
   269 EXPORT_C void CSubConnectionFlowBase::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& /*aRecipient*/, TSignatureBase& aMessage)
       
   270     {
       
   271     if (iLastRequestOriginator.Open(iSubConnectionProvider, aSender) != KErrNone)
       
   272         {
       
   273         if(!iSubConnectionProvider.IsOpen())
       
   274 	        {
       
   275 	    	// Legacy flows legitimately lack a sub-connection provider
       
   276 	        return;
       
   277 	        }
       
   278 		else if(aMessage.IsMessage<TEBase::TError>())
       
   279 			{
       
   280 			//[TODO EC120] RZ: WHoa! What is this?! Flow receives a TError and as a response sends TError
       
   281 			//(leaves from ::ReceivedL are handled by sending TError).
       
   282 			__ASSERT_DEBUG(static_cast<TEBase::TError&>(aMessage).iValue != KErrNone, User::Panic(KSpecAssert_ESockSSocksbcnfl, 4));
       
   283 			User::Leave(static_cast<TEBase::TError&>(aMessage).iValue);	// don't mutate the error into KErrArgument
       
   284 			}
       
   285 		User::Leave(KErrArgument);
       
   286         }
       
   287     }
       
   288 
       
   289 EXPORT_C void CSubConnectionFlowBase::SubConnectionGoingDown()
       
   290 	{
       
   291 	LOG( ESockLog::Printf(KESockDataFactTag, _L8("CSubConnectionFlowBase %08x:\tSubConnectionGoingDown"), this) );
       
   292 	iSubConnectionProvider.Close();
       
   293 	DeleteThisFlow();
       
   294 	}
       
   295 
       
   296 EXPORT_C NetInterfaces::TInterfaceControl* CSubConnectionFlowBase::FetchNodeInterfaceControlL(TInt aInterfaceId)
       
   297     {
       
   298     return DoFetchInterfaceControlL(aInterfaceId);
       
   299     }
       
   300 
       
   301 EXPORT_C MFlowBinderControl* CSubConnectionFlowBase::GetBinderControlL()
       
   302 	{
       
   303 	return DoGetBinderControlL();
       
   304 	}
       
   305 
       
   306 EXPORT_C void CSubConnectionFlowBase::DeleteThisFlow()
       
   307 /**
       
   308 Called from Flows to delete themselves, usually as a result of a received Destroy() message.
       
   309 
       
   310 */
       
   311 	{
       
   312 
       
   313 	DeleteMeNow();
       
   314 	// "this" no longer valid after this point.
       
   315 
       
   316 	}
       
   317 
       
   318 EXPORT_C CProtocolIntfBase* CSubConnectionFlowBase::ProtocolIntf() const
       
   319 /**
       
   320 Return the ProtocolIntf associated with this Flow
       
   321 */
       
   322 	{
       
   323 	return iProtocolIntf;
       
   324 	}
       
   325 
       
   326