telephonyprotocols/rawipnif/rawipnif2/src/RawIP2Flow.cpp
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
child 42 3adadc800673
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     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 // Implements the CRawIPFlow class, which provides a central point for the NIF
       
    15 // to communicate with NifMan and the BCA controllers. This class creates an interface
       
    16 // to the IPv4 protocol when it is required.
       
    17 // 
       
    18 //
       
    19 
       
    20 /**
       
    21  @file
       
    22 */
       
    23 
       
    24 #include <f32file.h>
       
    25 #include <nifman.h>
       
    26 #include <nifmbuf.h>
       
    27 #include <in_iface.h>
       
    28 #include <nifvar.h>
       
    29 #include "IPv4Binder.h"
       
    30 #include "IPv6Binder.h"
       
    31 #include "RawIP2Flow.h"
       
    32 #include "BcaController.h"
       
    33 #include <comms-infras/linkprovision.h>
       
    34 #include <comms-infras/linkmessages.h>
       
    35 #include <comms-infras/ss_metaconnprov.h>					// for SAccessPointConfig
       
    36 #include <elements/nm_messages_base.h>
       
    37 #include <elements/nm_messages_child.h>
       
    38 #include <comms-infras/ss_nodemessages_flow.h>
       
    39 
       
    40 using namespace Messages;
       
    41 using namespace MeshMachine;
       
    42 
       
    43 #ifdef __FLOG_ACTIVE
       
    44 //These variables are used only if flog is active.
       
    45 _LIT8(KTcpDumpFirstTag,"TcpDump");
       
    46 static const TUint16 KTcpDumpLinkType = 12;
       
    47 #endif
       
    48 
       
    49 CRawIP2Flow::CRawIP2Flow(ESock::CSubConnectionFlowFactoryBase& aFactory, const Messages::TNodeId& aSubConnId, ESock::CProtocolIntfBase* aProtocolIntf, CBttLogger* aTheLogger)
       
    50 /**
       
    51  * Constructor.
       
    52  *
       
    53  * @param aFactory Reference to the factory which created this object.
       
    54  * @param aSubConnId Reference to the node id for sub connection.
       
    55  * @param aProtocolIntf pointer to the CProtocolIntfBase
       
    56  * @param aTheLogger The logging object, ownership is passed to this object
       
    57  */
       
    58 	: CSubConnectionFlowBase(aFactory, aSubConnId, aProtocolIntf),
       
    59 	  iTheLogger(aTheLogger),
       
    60 	  iInitError(KErrNone),
       
    61 	  iStarted(EFalse),
       
    62 	  iStopping(EFalse)
       
    63 	{
       
    64 	LOG_NODE_CREATE(KNifSubDir, CRawIP2Flow);
       
    65 	}
       
    66 
       
    67 void CRawIP2Flow::ConstructL()
       
    68 /**
       
    69  * Second-phase constructor. Creates the Etel
       
    70  * control engine
       
    71  *
       
    72  * @param aName The name of the NIF (unused)
       
    73  */
       
    74 	{
       
    75 	_LOG_L1C2(_L8("CRawIP2Flow %08x:\tConstructL()"), this);
       
    76 	
       
    77     iBinderControl = new (ELeave) TBinderControlProxy(*this);
       
    78 	iBcaController = CBcaController::NewL(*this, iTheLogger);
       
    79 	}
       
    80 
       
    81 CRawIP2Flow::~CRawIP2Flow()
       
    82 /**
       
    83  * Destructor. Cancels and deletes all owned active objects.
       
    84  */
       
    85 	{
       
    86 	// Note that we don't delete iBinder because it's not owned by us.
       
    87 	delete iBcaController;
       
    88 	// This class also deletes the logging object
       
    89 	delete iTheLogger;
       
    90 
       
    91 	ASSERT(iBinder == NULL);
       
    92 	
       
    93 	delete iBinderControl;	
       
    94 	LOG_NODE_DESTROY(KNifSubDir, CRawIP2Flow);
       
    95 	// Cleanup when stop was not called - harmless as it null's the pointer
       
    96 	__PACKETLOG_DELETE;
       
    97 	}
       
    98 
       
    99 void CRawIP2Flow::StartFlowL()
       
   100 /**
       
   101  * Starts the Flow up. This process involves connecting to the BCA.  
       
   102  *
       
   103  * Called in response to corresponding SCPR message.
       
   104  *
       
   105  * @return Allways KErrNone
       
   106  */
       
   107 	{
       
   108 	ASSERT(iStarting==EFalse);
       
   109 	iStarting = ETrue;
       
   110 	_LOG_L1C2(_L8("CRawIP2Flow %08x:\tStartFlowL()"), this);
       
   111 
       
   112 	// If there were any errors during earlier processing of the ProvisionConfig message
       
   113 	// then send an Error message in response to the StartFlow (because ProvisionConfig
       
   114 	// does not have a response code).
       
   115 	if (iProvisionError != KErrNone)
       
   116 		{
       
   117 		User::Leave(iProvisionError);
       
   118 		}
       
   119 
       
   120 	// Retrieve Agent provisioned information only available at StartFlow time
       
   121 	DynamicProvisionConfigL();
       
   122 	InitialiseL();
       
   123 	
       
   124 	// associate the binder object with the lowersender
       
   125 	iBinder->SetSender(&(iBcaController->Bca()->GetSender()));
       
   126 	//the name calculation should be done only if logging is enabled
       
   127 #ifdef __FLOG_ACTIVE
       
   128 	const TUint KModemNameLen = KCommsDbSvrMaxColumnNameLength + 10;  // need enough for ppp-XXX.txt - e.g. ppp-comm-1.txt, ppp-btcomm-10.txt etc
       
   129 	TBuf8<KModemNameLen> modemName;
       
   130 
       
   131 	_LIT8(KDoubleColon, "::");
       
   132 
       
   133 	modemName.Copy(iBCAProvisionConfig->GetPortName());
       
   134 	const TInt pos = modemName.FindC((const TDesC8&)KDoubleColon);
       
   135 	if(pos != KErrNotFound)
       
   136 		{
       
   137 		modemName.Delete(pos, 2);
       
   138 		}
       
   139 
       
   140 	//append time stamp
       
   141 	const TUint KTimeStampLen = 8;
       
   142 	TBuf8<KTimeStampLen> logFileName;
       
   143 
       
   144 	_LIT8(KTimeFormat, "%08X");
       
   145 	TUint32 counter = User::FastCounter();
       
   146 	logFileName.Format(KTimeFormat, counter);
       
   147 
       
   148 	TRAPD(err,__PACKETLOG_NEWL(KTcpDumpFirstTag, logFileName, CPacketLogger::ETcpDump, KTcpDumpLinkType));
       
   149 	if (err)
       
   150 		{
       
   151 		_LOG_L1C1(_L8("Trapped leave from __PACKETLOG_NEWL"));
       
   152 		}
       
   153 
       
   154 	const TUint KLogTextLen = KModemNameLen+KTimeStampLen+30;
       
   155 	TBuf8<KLogTextLen> logText;
       
   156 	_LIT8(KLogTimeText, "TcpDump log file time stamp:");
       
   157 	_LIT8(KLogModemText, " for modem:");
       
   158 	logText.Append(KLogTimeText);
       
   159 	logText.Append(logFileName);
       
   160 	logText.Append(KLogModemText);
       
   161 	logText.Append(modemName);
       
   162 	_LOG_L1C1(logText);
       
   163 #endif
       
   164 	}
       
   165 
       
   166 
       
   167 void CRawIP2Flow::LinkLayerUp()
       
   168 /**
       
   169  * This function is called when initialisation is complete and the Flow is
       
   170  * ready to send/receive data. It notifies NifMan and the IP interface that it's
       
   171  * ready to go.
       
   172  */
       
   173 	{
       
   174 	_LOG_L1C2(_L8("CRawIP2Flow %08x:\tLinkLayerUp()"), this);
       
   175 
       
   176 	iLastRequestOriginator.ReplyTo(Id(), ESock::TCFDataClient::TStarted().CRef());
       
   177 	
       
   178 	iStarted = ETrue;
       
   179 	iStarting = EFalse;
       
   180 	}
       
   181 
       
   182 void CRawIP2Flow::LinkLayerDown(TInt aError)
       
   183 /**
       
   184  * This function is called when the context has been deactivated and the NIF
       
   185  * is ready to be deleted, or if there is an error on startup. Its job is to
       
   186  * notify NifMan that the link has gone down, so it can delete the NIF.
       
   187  *
       
   188  * @param aError An error code to propagate to NifMan
       
   189  */
       
   190 	{
       
   191 	_LOG_L1C3(_L8("CRawIP2Flow %08x:\tLinkLayerDown(aError %d)"), this, aError);
       
   192 	__PACKETLOG_DELETE;
       
   193 
       
   194 	if (iStopping)
       
   195 		{
       
   196 		iLastRequestOriginator.ReplyTo(Id(), ESock::TCFDataClient::TStopped(aError).CRef());
       
   197 		}
       
   198     else if (iStarting)
       
   199 		{
       
   200 		iSubConnectionProvider.PostMessage(Id(), TEBase::TError(ESock::TCFServiceProvider::TStart::Id(), aError).CRef());
       
   201 		}
       
   202 	else    
       
   203 		{
       
   204 		iSubConnectionProvider.PostMessage(Id(), ESock::TCFControlProvider::TDataClientGoneDown(aError, MNifIfNotify::EDisconnect).CRef());
       
   205 		}
       
   206 
       
   207     iStarted = EFalse;
       
   208     iStarting = EFalse;
       
   209     iStopping = EFalse;
       
   210 	}
       
   211 
       
   212 void CRawIP2Flow::StopFlow(TInt aError)
       
   213 /**
       
   214  * This function is called by NifMan to bring down the link. It starts
       
   215  * the asynchronous context deactivation process; LinkLayerDown() will be
       
   216  * called when the context has been deactivated.
       
   217  *
       
   218  * @param aError A code specifying why the link is to be brought down
       
   219  * @param aAction The action to take: disconnect or reconnect
       
   220  */
       
   221 	{
       
   222 	_LOG_L1C3(_L8("CRawIP2Flow %08x:\tStopFlow(aError %d)"), this, aError);
       
   223 	__PACKETLOG_DELETE;
       
   224 	iStopping = ETrue;
       
   225 	ShutDown(aError);
       
   226 	}
       
   227 
       
   228 
       
   229 void CRawIP2Flow::InitialiseL()
       
   230 /**
       
   231  * This method controls the initialisation sequence of the different modules
       
   232  * in the Flow. When a module completes all the initialisation tasks it will
       
   233  * call again this method with the new state. If an error occurs then the
       
   234  * ShutDown() method will be called.
       
   235  *
       
   236  * @param aState The current initialisation step
       
   237  * @param aError A possible error
       
   238  */
       
   239 	{
       
   240 	_LOG_L1C2(_L8("CRawIPFlow %08x:\tInitialiseL"),this);		
       
   241 
       
   242 	// Update local state from TSY information originally from Agent.
       
   243 	GetBinder()->UpdateContextConfigL(*iAgentProvision->iGprsConfig);
       
   244 	GetBinder()->UpdateConnectionSpeed(iAgentProvision->iConnectionSpeed);
       
   245 
       
   246 	UpdateContextState(RPacketContext::EStatusActive, KErrNone);
       
   247 
       
   248 	iBcaController->StartLoadL(iBCAProvisionConfig,iBinder,iBinder);
       
   249 	}
       
   250 
       
   251 void CRawIP2Flow::ShutDown(TInt aError)
       
   252 /**
       
   253  * This method controls the shutdown sequence of the different modules
       
   254  * in the Flow. When a module completes all the shutdown tasks it will
       
   255  * call again this method with the new state.
       
   256  *
       
   257  * @param aState The current state
       
   258  * @param aError A possible error (only during initialisation)
       
   259  */
       
   260 	{
       
   261 	_LOG_L1C3(_L8("CRawIPFlow %08x:\tShutDown(aError %d)"),this, aError);	
       
   262 			
       
   263 	if (aError != KErrNone)
       
   264 		{
       
   265 		// Flow is shutting down due to an error.
       
   266 		// The error code must be stored in order to call linklayer down
       
   267 		// passing that value
       
   268 		iInitError = aError;
       
   269 		}
       
   270 
       
   271 	iBcaController->Stop(aError);
       
   272 	LinkLayerDown(iInitError);
       
   273 	}
       
   274 
       
   275 CBinderBase* CRawIP2Flow::GetBinder()
       
   276 /**
       
   277  * Returns a pointer to the Binder class
       
   278  *
       
   279  * @return a pointer to a CBinderBase derived class
       
   280  */
       
   281 	{
       
   282 	return iBinder;
       
   283 	}
       
   284 
       
   285 CBcaController* CRawIP2Flow::GetBcaController()
       
   286 /**
       
   287  * Returns a pointer to the CBcaIoController class
       
   288  *
       
   289  * @return a pointer to CBcaIoController
       
   290  */
       
   291 	{
       
   292 	return iBcaController;
       
   293 	}
       
   294 
       
   295 void CRawIP2Flow::UpdateContextState(
       
   296 	RPacketContext::TContextStatus aState, TInt /*aError*/)
       
   297 /**
       
   298  * Updates the state of the iContextState variable
       
   299  *
       
   300  * @param aState The new state
       
   301  * @param aError A possible error
       
   302  */
       
   303 	{
       
   304 	_LOG_L1C3(_L8("CRawIP2Flow %08x:\tUpdateContextState(aState %d)"), this, aState);
       
   305 
       
   306 	// Note that we do not need to close the Flow down if there's been an
       
   307 	// error, as the context state machine will do this for us.
       
   308 
       
   309 	iContextStatus = aState;
       
   310 	}
       
   311 
       
   312 // =====================================================================================
       
   313 //
       
   314 // CSubConnectionFlowBase
       
   315 //
       
   316 
       
   317 ESock::MFlowBinderControl* CRawIP2Flow::DoGetBinderControlL()
       
   318 	{
       
   319 	return iBinderControl;
       
   320 	}
       
   321 
       
   322 // =====================================================================================
       
   323 //
       
   324 // MFlowBinderControl methods
       
   325 //
       
   326 
       
   327 ESock::MLowerControl* CRawIP2Flow::GetControlL(const TDesC8& aProtocol)
       
   328 	{
       
   329 #ifdef __BTT_LOGGING__
       
   330 	//TBuf8<256> debugBuffer;
       
   331 	//debugBuffer.Copy(aProtocol);
       
   332 	_LOG_L1C3(_L8("CRawIP2Flow %08x:\tGetControlL(aProtocol %S)"), this, &aProtocol);
       
   333 #endif
       
   334 
       
   335 	// IPv4 and ICMP Protocols
       
   336 	if (aProtocol.CompareF(KDescIp()) == 0 || aProtocol.CompareF(KDescIcmp()) == 0)
       
   337 		{
       
   338 		if (!iBinder)
       
   339 			{
       
   340 			iBinder = new (ELeave) CIPv4Binder(*this, iTheLogger);
       
   341 #ifdef RAWIP_HEADER_APPENDED_TO_PACKETS			
       
   342  			iBinder->SetType(KIp4FrameType);
       
   343 #endif // RAWIP_HEADER_APPENDED_TO_PACKETS			
       
   344 			}
       
   345 		else
       
   346 			{
       
   347 			_LOG_L1C2(_L8("CRawIP2Flow %08x:\tGetControlL(): IPv4 binder already exists"), this);
       
   348 			}
       
   349 		}
       
   350 	// IPv6 Protocol
       
   351 	else if (aProtocol.CompareF(KDescIp6()) == 0)
       
   352 		{
       
   353 		if (!iBinder)
       
   354 			{
       
   355 			iBinder = new (ELeave) CIPv6Binder(*this, iTheLogger);
       
   356 #ifdef RAWIP_HEADER_APPENDED_TO_PACKETS			
       
   357  			iBinder->SetType(KIp6FrameType);
       
   358 #endif // RAWIP_HEADER_APPENDED_TO_PACKETS						
       
   359 			}
       
   360 		else
       
   361 			{
       
   362 			_LOG_L1C2(_L8("CRawIP2Flow %08x:\tGetControlL(): IPv6 binder already exists"), this);
       
   363 			}
       
   364 		}		
       
   365 	else
       
   366 		{
       
   367 		User::Leave(KErrNotSupported);
       
   368 		}
       
   369 	
       
   370     return iBinder;
       
   371 	}
       
   372 
       
   373 ESock::MLowerDataSender* CRawIP2Flow::BindL(const TDesC8& aProtocol, ESock::MUpperDataReceiver* aReceiver, ESock::MUpperControl* aControl)
       
   374 /**
       
   375  * Binds upper CFProtocol to this CFProtocol
       
   376  *
       
   377  * @param aUpperReceiver A pointer to Upper layer Receive class
       
   378  * @param aUpperControl A pointer to Upper layer control class
       
   379  */
       
   380 	{
       
   381 #ifndef _DEBUG
       
   382 	(void) aProtocol;
       
   383 #endif
       
   384 
       
   385 	ASSERT (aProtocol.CompareF(KDescIp()) == 0 || aProtocol.CompareF(KDescIcmp()) == 0
       
   386 			|| aProtocol.CompareF(KDescIp6()) == 0);
       
   387 	ASSERT(iBinder);
       
   388 	
       
   389     iSubConnectionProvider.PostMessage(Id(), ESock::TCFControlProvider::TActive().CRef());
       
   390 	return iBinder->Bind(aReceiver, aControl);
       
   391 	}
       
   392 
       
   393 void CRawIP2Flow::Unbind(ESock::MUpperDataReceiver* aUpperReceiver, ESock::MUpperControl* aUpperControl)
       
   394     {
       
   395     _LOG_L1C2(_L8("CRawIP2Flow %08x:\tUnbind()"), this);
       
   396 
       
   397 	ASSERT(iBinder);
       
   398 	iBinder->Unbind(aUpperReceiver, aUpperControl);
       
   399 
       
   400     delete iBinder;
       
   401     iBinder = NULL;
       
   402 
       
   403     SendDataClientIdleIfNoClients();
       
   404     }
       
   405 
       
   406 
       
   407 void CRawIP2Flow::SendDataClientIdleIfNoClients()
       
   408     {
       
   409     if (iBinder == NULL)
       
   410         {
       
   411         iSubConnectionProvider.PostMessage(Id(), ESock::TCFControlProvider::TIdle().CRef());
       
   412         }
       
   413     }
       
   414 
       
   415 ESock::CSubConnectionFlowBase* CRawIP2Flow::Flow()
       
   416 /**
       
   417 Return the Flow corresponding to the MFlowBinderControl
       
   418 */
       
   419 	{
       
   420 	return this;
       
   421 	}
       
   422 
       
   423 // =====================================================================================
       
   424 //
       
   425 // MCFNode
       
   426 //
       
   427 
       
   428 void CRawIP2Flow::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage)
       
   429     {
       
   430     CSubConnectionFlowBase::ReceivedL(aSender, aRecipient, aMessage);
       
   431 
       
   432 	if (aMessage.IsMessage<TEBase::TError>())
       
   433 		{
       
   434 		SubConnectionError(static_cast<TEBase::TError&>(aMessage).iValue);
       
   435 		}
       
   436 	else if (TEChild::ERealmId == aMessage.MessageId().Realm())
       
   437 		{
       
   438 		switch (aMessage.MessageId().MessageId())
       
   439 			{
       
   440 		case TEChild::TDestroy::EId :
       
   441 			Destroy();
       
   442 			break;
       
   443 		default:
       
   444 //TODO - logging
       
   445 			ASSERT(EFalse);
       
   446 			}
       
   447 		}
       
   448 	else if (ESock::TCFDataClient::ERealmId == aMessage.MessageId().Realm())
       
   449 		{
       
   450 		switch (aMessage.MessageId().MessageId())
       
   451 			{
       
   452 		case ESock::TCFDataClient::TStart::EId :
       
   453 			StartFlowL();
       
   454 			break;
       
   455 		case ESock::TCFDataClient::TStop::EId :
       
   456 			StopFlow(static_cast<ESock::TCFDataClient::TStop&>(aMessage).iValue);
       
   457 			break;
       
   458 		case ESock::TCFDataClient::TProvisionConfig::EId:
       
   459 			ProvisionConfig(static_cast<ESock::TCFDataClient::TProvisionConfig&>(aMessage).iConfig);
       
   460 			break;
       
   461 		case ESock::TCFDataClient::TBindTo::EId:
       
   462             {
       
   463             ESock::TCFDataClient::TBindTo& bindToReq = message_cast<ESock::TCFDataClient::TBindTo>(aMessage);
       
   464 			if (!bindToReq.iNodeId.IsNull())
       
   465 				{
       
   466 				User::Leave(KErrNotSupported);
       
   467 				}
       
   468 			RClientInterface::OpenPostMessageClose(Id(), aSender, ESock::TCFDataClient::TBindToComplete().CRef());
       
   469             }
       
   470 			break;
       
   471 		default:
       
   472 //TODO - logging
       
   473 			ASSERT(EFalse);
       
   474 			}
       
   475 		}
       
   476 	else if (ESock::TCFFlow::ERealmId == aMessage.MessageId().Realm())
       
   477 		{
       
   478 		switch (aMessage.MessageId().MessageId())
       
   479 			{
       
   480 		case ESock::TCFFlow::TBlock::EId :
       
   481 			iBlocked = ETrue;
       
   482 			break;
       
   483 		case ESock::TCFFlow::TUnBlock::EId :
       
   484 			iBlocked = EFalse;
       
   485 			if (iBinder)
       
   486 				{
       
   487 				iBinder->StartSending();
       
   488 				}
       
   489 			break;
       
   490 		case ESock::TCFFlow::TRejoin::EId:
       
   491 			{
       
   492 			ESock::TCFFlow::TRejoin& rejoinMsg = message_cast<ESock::TCFFlow::TRejoin>(aMessage);
       
   493 			ESock::TDefaultFlowFactoryQuery query(rejoinMsg.iNodeId);
       
   494 			CRawIP2Flow* otherFlow = static_cast<CRawIP2Flow*>(Factory().Find(query));
       
   495 			ASSERT(otherFlow);
       
   496 
       
   497 			//This rather ugly looking snipped of code implements
       
   498 			//the scenario whereat the network tears down the default
       
   499 			//scpr and the default scpr selects a new default amongst
       
   500 			//the non-default and subsequently performs a transparant
       
   501 			//swap - i.e.: the upper layer perceives this as a
       
   502 			//non-default going down. Since the datapath is pre-bound
       
   503 			//to the flow representing the default, the datapath needs
       
   504 			//to perform a transparent swap too, so that the upper layer
       
   505 			//doesn't notice anything. It does that by swapping the
       
   506 			//flows below the binders.
       
   507 			CBinderBase* localBinder = iBinder;
       
   508 			CBttLogger* logger = localBinder->iTheLogger;
       
   509 
       
   510 			TBinderControlProxy* localBinderControl = iBinderControl;
       
   511 			iBinder = otherFlow->iBinder;
       
   512 			otherFlow->iBinder->ChangeFlow(*this);
       
   513 			localBinder->ChangeFlow(*otherFlow);
       
   514 			otherFlow->iBinder = localBinder;
       
   515 			iBinderControl = otherFlow->iBinderControl;
       
   516 			otherFlow->iBinderControl = localBinderControl;
       
   517 			otherFlow->iBinderControl->iFlow = otherFlow;
       
   518 			iBinderControl->iFlow = this;
       
   519 
       
   520 			iBinder->iTheLogger = logger;
       
   521 
       
   522 			iSubConnectionProvider.Close();
       
   523 			iSubConnectionProvider.Open(address_cast<TNodeId>(rejoinMsg.iNodeId));
       
   524 			}
       
   525 			break;
       
   526 		default:
       
   527 //TODO - logging
       
   528 			ASSERT(EFalse);
       
   529 			}
       
   530 		}
       
   531 	else	// not a recognised realm or message
       
   532 		{
       
   533 		ASSERT(EFalse);
       
   534 		}
       
   535     }
       
   536 
       
   537 
       
   538 // =====================================================================================
       
   539 //
       
   540 // Methods for handling incoming SCPR messages
       
   541 //
       
   542 
       
   543 void CRawIP2Flow::SubConnectionGoingDown()
       
   544 	{
       
   545 	}
       
   546 
       
   547 void CRawIP2Flow::SubConnectionError(TInt /*aError*/)
       
   548 	{
       
   549 	}
       
   550 
       
   551 /*
       
   552 Provisioning description for RawIp CFProtocol Flow:
       
   553 
       
   554 - on receipt of the ProvisionConfig message, the pointer contained within is stored
       
   555   in iAccessPointConfig and the provisioning information contained within it is validated:
       
   556 	- CBCAProvision must be present.  It is added by the RawIpMCPr and populated from CommsDat.  A pointer to it
       
   557 	  is stored in iProvision.
       
   558   if any are missing, an error is stored in iProvisionError and sent in response to the StartFlow
       
   559   message later on (ProvisionConfig has no response).
       
   560 
       
   561 - on receipt of the StartFlow message, further provisioning information is retrieved:
       
   562 	- CIPConfig must be present.  It is added by the RawIpMCPr and populated from CommsDat.  The binder retrieves
       
   563 	  individual fields from it.
       
   564 	- CRawIpAgentConfig must be present.  It is added by the RawIpAgentHandler and populated via calls
       
   565 	  to the Agent.  A pointer to it is stored in iAgentProvision.  Note that the iGprsConfig field
       
   566 	  is a pointer to a (large) structure in the Agent (see CRawIpAgentHandler).
       
   567   if any of the above are missing, an Error message is signalled back to the SCPr in response
       
   568   to the StartFlow.
       
   569 */
       
   570 
       
   571 void CRawIP2Flow::ProvisionConfig(const ESock::RMetaExtensionContainerC& aConfigData)
       
   572 /**
       
   573 Handle ProvisionConfig message from SCPR.
       
   574 
       
   575 Just save the pointer for now - validate it later on StartFlow.
       
   576 
       
   577 @param aData provisioning pointer from message
       
   578 */
       
   579 	{
       
   580 	_LOG_L1C2(_L8("CRawIP2Flow %08x:\tProvisionConfig()"), this);
       
   581 	iProvisionError = KErrNone;
       
   582 
       
   583 	AccessPointConfig().Close();
       
   584 	AccessPointConfig().Open(aConfigData);
       
   585 
       
   586 	ASSERT(iBCAProvisionConfig == NULL);
       
   587     iBCAProvisionConfig = static_cast<const CBCAProvision*>(AccessPointConfig().FindExtension(STypeId::CreateSTypeId(CBCAProvision::EUid, CBCAProvision::ETypeId)));
       
   588 
       
   589     if (iBCAProvisionConfig == NULL)
       
   590         {
       
   591         _LOG_L1C1(_L8("CRawIP2Flow:\tProvisionConfigL() - CBCAProvision config incomplete"));
       
   592 		iProvisionError = KErrCorrupt;
       
   593 		return;
       
   594         }
       
   595 	}
       
   596 
       
   597 void CRawIP2Flow::DynamicProvisionConfigL()
       
   598 /**
       
   599 Retrieve provisioning information available only at StartFlow time.
       
   600 */
       
   601 	{
       
   602 	ASSERT(iAgentProvision == NULL);
       
   603     iAgentProvision = static_cast<const CRawIpAgentConfig*>(AccessPointConfig().FindExtension(STypeId::CreateSTypeId(CRawIpAgentConfig::EUid, CRawIpAgentConfig::ETypeId)));
       
   604 
       
   605     if (iAgentProvision == NULL)
       
   606     	{
       
   607     	User::Leave(KErrCorrupt);
       
   608     	}
       
   609 
       
   610     const CIPConfig* wcdmaIpProvision = static_cast<const CIPConfig*>(AccessPointConfig().FindExtension(STypeId::CreateSTypeId(CIPConfig::EUid, CIPConfig::ETypeId)));
       
   611     if (wcdmaIpProvision == NULL)
       
   612         {
       
   613         _LOG_L1C2(_L8("CRawIP2Flow %08x:\tDynamicProvisionConfigL() - WCDMA config incomplete"), this);
       
   614 		iProvisionError = KErrCorrupt;
       
   615 		return;
       
   616         }
       
   617    	// Pass pointer to binder specific provisioning information to binder
       
   618 	if (iBinder)
       
   619 		{
       
   620 		iBinder->SetProvision(*wcdmaIpProvision);
       
   621 		}
       
   622 	}
       
   623 
       
   624 
       
   625 void CRawIP2Flow::Destroy()
       
   626 /**
       
   627 Handle Destroy message from SCPR.
       
   628 */
       
   629 	{
       
   630 	DeleteThisFlow();
       
   631 	}
       
   632 
       
   633 ESock::MLowerControl* CRawIP2Flow::TBinderControlProxy::GetControlL(const TDesC8& aProtocol)
       
   634     {
       
   635     return RawIP2Flow().GetControlL(aProtocol);
       
   636     }
       
   637     
       
   638 ESock::MLowerDataSender* CRawIP2Flow::TBinderControlProxy::BindL(const TDesC8& aProtocol, ESock::MUpperDataReceiver* aReceiver, ESock::MUpperControl* aControl)
       
   639     {
       
   640     return RawIP2Flow().BindL(aProtocol, aReceiver, aControl);
       
   641     }
       
   642     
       
   643 void CRawIP2Flow::TBinderControlProxy::Unbind(ESock::MUpperDataReceiver* aReceiver, ESock::MUpperControl* aControl)
       
   644     {
       
   645     return RawIP2Flow().Unbind(aReceiver, aControl);
       
   646     }
       
   647 
       
   648 ESock::CSubConnectionFlowBase* CRawIP2Flow::TBinderControlProxy::Flow()
       
   649     {
       
   650     return iFlow;
       
   651     }
       
   652     	
       
   653 // =====================================================================================
       
   654 //
       
   655 // Utility functions
       
   656 //
       
   657 
       
   658 void CRawIP2Flow::PostProgressMessage(TInt aStage, TInt aError)
       
   659 	{
       
   660 	iSubConnectionProvider.PostMessage(Id(), ESock::TCFMessage::TStateChange(Elements::TStateChange( aStage, aError)).CRef());
       
   661 	}
       
   662 
       
   663 //
       
   664 // NOTE:
       
   665 // Attribute table should be in the control side module that instantiates CRawIpProvision.
       
   666 // RawIP CFProtocol does not instantiate the CRawIpProvision object, so does not need to
       
   667 // define the attribute tables.  The attribute table can therefore be placed directly into
       
   668 // the control side module.
       
   669 //
       
   670 // The reason for this is to save splitting RawIP CFProtocol into two DLL's - ECOM and Main -
       
   671 // just for control side module to link against Main DLL to retrieve the attribute table.
       
   672 // In fact, it can be placed into control side module as "START_ATTRIBUTE_TABLE" rather
       
   673 // than "EXPORT_START_ATTRIBUTE_TABLE".  In fact, do we just need "TYPEID_TABLE" ?
       
   674 //
       
   675 // EXPORT_START_ATTRIBUTE_TABLE(CRawIpProvision, KRawIpConfigUid, KRawIpConfigType)
       
   676 // END_ATTRIBUTE_TABLE()