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