linklayerprotocols/tunnelnif/src/tunnelFlow.cpp
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2002-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 // tunnelnif.cpp
       
    15 //
       
    16 //
       
    17 
       
    18 #include <es_mbuf.h>
       
    19 //#include <flogger.h>
       
    20 
       
    21 #include <agenterrors.h>
       
    22 
       
    23 //#include "TunnelNifVar.h"
       
    24 #include "tunnelFlow.h"
       
    25 #include "tunnelBinders.h"
       
    26 #include "tunnelProvision.h"
       
    27 #include <comms-infras/linkmessages.h>
       
    28 #include <comms-infras/ss_metaconnprov.h>					// for SAccessPointConfig
       
    29 #include <comms-infras/commsdebugutility.h>
       
    30 #include <elements/nm_messages_base.h>
       
    31 #include <elements/nm_messages_child.h>
       
    32 
       
    33 using namespace Messages;
       
    34 using namespace MeshMachine;
       
    35 using namespace ESock;
       
    36 
       
    37 /*
       
    38  * This sections defines a whole load of constants etc... not very exciting
       
    39  */
       
    40 #if defined (_DEBUG)
       
    41 	#define LOG(a) a
       
    42 #else
       
    43 	#define LOG(a)
       
    44 #endif
       
    45 
       
    46 _LIT8(KDescIp6, "ip6");
       
    47 _LIT8(KDescIp, "ip");
       
    48 
       
    49 // Note: The "tunnel" logging string has been repeated here but should be unified throughout
       
    50 // the Tunnel CFProtocol.  The main logging relies on 16-bit RFileLogger calls whereas the
       
    51 // CFNode logging requires an 8-bit string.  An attempt to make everything 8-bit resulted
       
    52 // in undefined RFileLogger symbols.
       
    53 #ifdef SYMBIAN_TRACE_ENABLE
       
    54 _LIT8(KTunnel, "tunnel");
       
    55 #endif
       
    56 
       
    57 /*
       
    58  * The Link class
       
    59  */
       
    60 
       
    61 CTunnelFlow::CTunnelFlow(CSubConnectionFlowFactoryBase& aFactory, const TNodeId& aSubConnId, CProtocolIntfBase* aProtocolIntf)
       
    62 	: CSubConnectionFlowBase(aFactory, aSubConnId, aProtocolIntf)
       
    63 /**
       
    64 Constructor.
       
    65 
       
    66 @param aFactory Reference to the factory which created this object.
       
    67 @param aSubConnId Id of SubConnection Provider - for sending messages to it.
       
    68 @param aProtocolIntf Protocol Interface corresponding to the Flow.
       
    69 */
       
    70     {
       
    71     LOG_NODE_CREATE(KTunnel, CTunnelFlow);
       
    72     }
       
    73 
       
    74 CTunnelFlow::~CTunnelFlow()
       
    75     {
       
    76     LOG_NODE_DESTROY(KTunnel, CTunnelFlow);
       
    77     }
       
    78 
       
    79 TInt CTunnelFlow::Notification(TTunnelAgentMessage::TTunnelSetAddress& aMessage)
       
    80     {
       
    81 	if (iNifIf4)
       
    82 		{
       
    83 		return iNifIf4->Notification(aMessage);
       
    84 		}
       
    85 	if (iNifIf6)
       
    86 		{
       
    87 		return iNifIf6->Notification(aMessage);
       
    88 		}
       
    89 	return KErrNotSupported;
       
    90 	}
       
    91 
       
    92 
       
    93 // =====================================================================================
       
    94 // CSubConnectionFlowBase
       
    95 // =====================================================================================
       
    96 
       
    97 MFlowBinderControl* CTunnelFlow::DoGetBinderControlL()
       
    98 	{
       
    99 	return this;
       
   100 	}
       
   101 
       
   102 // =====================================================================================
       
   103 // MFlowBinderControl methods
       
   104 // =====================================================================================
       
   105 
       
   106 MLowerControl* CTunnelFlow::GetControlL(const TDesC8& aProtocol)
       
   107 	{
       
   108 
       
   109 	if (aProtocol.CompareF(KDescIp6) == 0)
       
   110 		{
       
   111 		if ( iNifIf6 )
       
   112 			{
       
   113 			CTunnelNcpLog::Printf(_L("CTunnelFlow:\tGetControlL already bound to %S"), &aProtocol);
       
   114 			User::Leave(KErrInUse);
       
   115 			return NULL;
       
   116 			}
       
   117 		iNifIf6 = CTunnelNcp6::ConstructL(*this);
       
   118 		return iNifIf6;
       
   119         }
       
   120 	else if (aProtocol.CompareF(KDescIp) == 0)
       
   121 	    {
       
   122 		if ( iNifIf4 )
       
   123             {
       
   124             CTunnelNcpLog::Printf(_L("CTunnelFlow:\tGetControlL already bound to %S"), &aProtocol);
       
   125 			User::Leave(KErrInUse);
       
   126             return NULL;
       
   127             }
       
   128         iNifIf4 = CTunnelNcp4::ConstructL(*this);
       
   129 		return iNifIf4;
       
   130         }
       
   131 	Panic(ETunnelPanic_BadBind);
       
   132 	return NULL;
       
   133 	}
       
   134 
       
   135 MLowerDataSender* CTunnelFlow::BindL(const TDesC8& aProtocol, MUpperDataReceiver* aReceiver, MUpperControl* aControl)
       
   136 /**
       
   137  * Binds upper CFProtocol to this CFProtocol
       
   138  *
       
   139  * @param aUpperReceiver A pointer to Upper layer Receive class
       
   140  * @param aUpperControl A pointer to Upper layer control class
       
   141  */
       
   142 	{
       
   143 	MLowerDataSender* lowerDataSender = NULL;
       
   144 	if (aProtocol.CompareF(KDescIp6) == 0)
       
   145 		{
       
   146 		ASSERT(iNifIf6);
       
   147 		lowerDataSender = iNifIf6->Bind(aReceiver, aControl);
       
   148         }
       
   149 	else if (aProtocol.CompareF(KDescIp) == 0)
       
   150 		{
       
   151 		ASSERT(iNifIf4);
       
   152 		lowerDataSender = iNifIf4->Bind(aReceiver, aControl);
       
   153 		}
       
   154 	else
       
   155 		{
       
   156 		// GetControlL() should already have been called.
       
   157 		Panic(ETunnelPanic_BadBind);
       
   158 		}
       
   159 
       
   160 	if (lowerDataSender)
       
   161     	{
       
   162     	iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TActive().CRef());
       
   163     	}
       
   164 
       
   165 	return lowerDataSender;
       
   166 	}
       
   167 
       
   168 void CTunnelFlow::Unbind(MUpperDataReceiver* aUpperReceiver, MUpperControl* aUpperControl)
       
   169     {
       
   170 	if (iNifIf4 && iNifIf4->MatchesUpperControl(aUpperControl))
       
   171 		{
       
   172 		iNifIf4->Unbind(aUpperReceiver, aUpperControl);
       
   173 		delete iNifIf4;
       
   174 		iNifIf4 = NULL;
       
   175 		}
       
   176 	else
       
   177 	if (iNifIf6 && iNifIf6->MatchesUpperControl(aUpperControl))
       
   178 		{
       
   179 		iNifIf6->Unbind(aUpperReceiver, aUpperControl);
       
   180 		delete iNifIf6;
       
   181 		iNifIf6 = NULL;
       
   182 		}
       
   183 	else
       
   184 		{
       
   185 		Panic(ETunnelPanic_BadUnbind);
       
   186 		}
       
   187 	MaybePostDataClientIdle();
       
   188     }
       
   189 
       
   190 CSubConnectionFlowBase* CTunnelFlow::Flow()
       
   191 /**
       
   192 Return the Flow corresponding to the MFlowBinderControl
       
   193 */
       
   194 	{
       
   195 	return this;
       
   196 	}
       
   197 
       
   198 // =====================================================================================
       
   199 // Messages::ANode
       
   200 // =====================================================================================
       
   201 
       
   202 void CTunnelFlow::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage)
       
   203     {
       
   204     CSubConnectionFlowBase::ReceivedL(aSender, aRecipient, aMessage);
       
   205 
       
   206 	if (aMessage.IsMessage<TEBase::TError>())
       
   207 		{
       
   208 		}
       
   209 	else if (TEChild::ERealmId == aMessage.MessageId().Realm())
       
   210 		{
       
   211 		switch (aMessage.MessageId().MessageId())
       
   212 			{
       
   213 		case TEChild::TDestroy::EId :
       
   214 			Destroy();
       
   215 			break;
       
   216 		default:
       
   217 //TODO - logging
       
   218 			ASSERT(EFalse);
       
   219 			}
       
   220 		}
       
   221 	else if (TCFDataClient::ERealmId == aMessage.MessageId().Realm())
       
   222 		{
       
   223 		switch (aMessage.MessageId().MessageId())
       
   224 			{
       
   225 		case TCFDataClient::TStart::EId :
       
   226 			StartFlowL();
       
   227 			break;
       
   228 		case TCFDataClient::TStop::EId :
       
   229 			StopFlow(static_cast<TCFDataClient::TStop&>(aMessage).iValue);
       
   230 			break;
       
   231 		case TCFDataClient::TBindTo::EId:
       
   232             {
       
   233 			TCFDataClient::TBindTo& bindToReq = message_cast<TCFDataClient::TBindTo>(aMessage);
       
   234 			if (!bindToReq.iNodeId.IsNull())
       
   235 				{
       
   236 				User::Leave(KErrNotSupported);
       
   237 				}
       
   238 			RClientInterface::OpenPostMessageClose(Id(), aSender, TCFDataClient::TBindToComplete().CRef());
       
   239             }
       
   240 			break;
       
   241 		case TCFDataClient::TProvisionConfig::EId:
       
   242 			ProvisionConfig(static_cast<TCFDataClient::TProvisionConfig&>(aMessage).iConfig);
       
   243 			break;
       
   244 		default:
       
   245 //TODO - logging
       
   246 			ASSERT(EFalse);
       
   247 			}
       
   248 		}
       
   249    	else if (TTunnelAgentMessage::ERealmId == aMessage.MessageId().Realm())
       
   250 		{
       
   251 		switch (aMessage.MessageId().MessageId())
       
   252 			{
       
   253 		case TTunnelAgentMessage::TTunnelSetAddress::EId:
       
   254 			{
       
   255 			Notification(static_cast<TTunnelAgentMessage::TTunnelSetAddress&>(aMessage));
       
   256 			break;
       
   257 			}
       
   258 		default:
       
   259 			Panic(ETunnelPanic_UnexpectedMessage);
       
   260 			}
       
   261 		}
       
   262 	else	// realm is not TCFMessage or TTunnelAgentMessage
       
   263 		{
       
   264 		Panic(ETunnelPanic_UnexpectedMessage);
       
   265 		}
       
   266     }
       
   267 
       
   268 // =====================================================================================
       
   269 //
       
   270 // Methods for handling incoming SCPR messages
       
   271 //
       
   272 
       
   273 void CTunnelFlow::StartFlowL()
       
   274     {
       
   275     // NOTE: according to the NAF docs the sequence should really be StartSending(), then LinkLayerUp() then Progress()
       
   276     // for DNS to work.  However, this tunnel NIF doesn't support DNS.
       
   277     //
       
   278 	CTunnelNcpLog::Write(_L("CTunnelFlow:\tStartFlow()"));
       
   279 
       
   280 	// Process any errors that may have occurred during processing of the ProvisionConfig message earlier.
       
   281 	// ProvisionConfig has no response, so error the StartFlow here.
       
   282 	User::LeaveIfError(iSavedError);
       
   283 
       
   284 
       
   285 	PostDataClientStartedMessage();
       
   286 	if (iNifIf4)
       
   287 		{
       
   288 		iNifIf4->StartSending();
       
   289 		}
       
   290 	if (iNifIf6)
       
   291 		{
       
   292 		iNifIf6->StartSending();
       
   293 		}
       
   294 	iMMState = EStarted;
       
   295     }
       
   296 
       
   297 void CTunnelFlow::StopFlow(TInt aError)
       
   298     {
       
   299     CTunnelNcpLog::Printf(_L("CTunnelFlow:\tStop(aError %d)"), aError);
       
   300    
       
   301     PostFlowDownMessage(aError);
       
   302     }
       
   303 
       
   304 void CTunnelFlow::MaybePostDataClientIdle()
       
   305     {
       
   306 	if (iNifIf4 == NULL && iNifIf4 == NULL)
       
   307 		{
       
   308    		iSubConnectionProvider.RNodeInterface::PostMessage(Id(), TCFControlProvider::TIdle().CRef());
       
   309 		}
       
   310     }
       
   311 /*
       
   312 Provisioning description for Tunnel CFProtocol Flow:
       
   313 
       
   314 - on receipt of the TProvisionConfig message, the provisioning information contained within
       
   315   the AccessPointConfig array is validated:
       
   316 	- TTunnelProvision must be present.  It is added by the Tunnel MCPr and populated from CommsDat.  A pointer to it
       
   317 	  is stored in iProvisionInfo. If missing, TError(TCFDataClient::TStart, KErrCorrupt) message is signalled back
       
   318   	  to the SCPr on the next StartFlow message (ProvisionConfig has no response message).
       
   319 */
       
   320 
       
   321 
       
   322 void CTunnelFlow::ProvisionConfig(const ESock::RMetaExtensionContainerC& aConfigData)
       
   323 /**
       
   324 Handle ProvisionConfig message from SCPR.
       
   325 */
       
   326 	{
       
   327 	iSavedError = KErrNone;
       
   328 	CTunnelNcpLog::Printf(_L("CTunnelFlow:\tProvisionConfig message received"));
       
   329 	
       
   330 	AccessPointConfig().Close();
       
   331 	AccessPointConfig().Open(aConfigData);
       
   332 	
       
   333     const TTunnelProvision* provision = static_cast<const TTunnelProvision*>(AccessPointConfig().FindExtension(
       
   334     		STypeId::CreateSTypeId(TTunnelProvision::EUid, TTunnelProvision::ETypeId)));
       
   335     if (provision == NULL)
       
   336         {
       
   337         CTunnelNcpLog::Printf(_L("CTunnelFlow:\tProcessProvisionConfigL() - no Tunnel configuration"));
       
   338 		iSavedError = KErrCorrupt;
       
   339         }
       
   340 
       
   341 	ASSERT(iProvisionInfo == NULL);
       
   342 	iProvisionInfo = &provision->iInfo;
       
   343 	ASSERT(iProvisionInfo);
       
   344 	}
       
   345 
       
   346 void CTunnelFlow::Destroy()
       
   347 /**
       
   348 Handle Destroy message from SCPR.
       
   349 */
       
   350 	{
       
   351 	ASSERT(iNifIf4 == NULL);		// must not still be bound from above before being destroyed
       
   352 	ASSERT(iNifIf6 == NULL);
       
   353 	DeleteThisFlow();
       
   354 	}
       
   355 
       
   356 //
       
   357 // Utility functions
       
   358 //
       
   359 
       
   360 void CTunnelFlow::PostProgressMessage(TInt aStage, TInt aError)
       
   361 	{
       
   362 	iSubConnectionProvider.RNodeInterface::PostMessage(Id(), TCFMessage::TStateChange(Elements::TStateChange(aStage, aError)).CRef());
       
   363 	}
       
   364 
       
   365 void Panic(TTunnelPanic aPanic)
       
   366 	{
       
   367 	_LIT(KTunnelPanicTag, "Tunnel");
       
   368 	User::Panic(KTunnelPanicTag, aPanic);
       
   369 	}
       
   370