datacommsserver/esockserver/ssock/ss_sapshim.cpp
changeset 22 592244873960
parent 2 dee179edb159
child 25 e53adc4c49de
equal deleted inserted replaced
5:68ef71f0cd72 22:592244873960
    90 
    90 
    91 void CTransportFlowShim::Unbind( MUpperDataReceiver* /*aReceiver*/, MUpperControl* aControl)
    91 void CTransportFlowShim::Unbind( MUpperDataReceiver* /*aReceiver*/, MUpperControl* aControl)
    92     {
    92     {
    93     (void)aControl;
    93     (void)aControl;
    94     __ASSERT_DEBUG(aControl == iHostResolverNotify, User::Panic(KSpecAssert_ESockSSocksspshm, 1));
    94     __ASSERT_DEBUG(aControl == iHostResolverNotify, User::Panic(KSpecAssert_ESockSSocksspshm, 1));
    95     __ASSERT_DEBUG(iDCIdle <= EClientsPresent, User::Panic(KSpecAssert_ESockSSocksspshm, 2));
    95     __ASSERT_DEBUG(!(Idle() || IdleSent()), User::Panic(KSpecAssert_ESockSSocksspshm, 2));
    96     iDCIdle = EIdle;
    96     SetIdle();
       
    97 	
    97     iHostResolverNotify = NULL;
    98     iHostResolverNotify = NULL;
    98     if(iSubConnectionProvider.IsOpen())	// legacy flows have no control side
    99     if(iSubConnectionProvider.IsOpen())	// legacy flows have no control side
    99     	{
   100     	{
   100     	ProcessDCIdleState();
   101     	ProcessDCIdleState();
   101     	}
   102     	}
   161 	if(iListenerControlNotify)
   162 	if(iListenerControlNotify)
   162 		{
   163 		{
   163 		iListenerControlNotify->DisconnectFromListener(*this);
   164 		iListenerControlNotify->DisconnectFromListener(*this);
   164 		}
   165 		}
   165 
   166 
   166 	if(!iDetaching)
   167 	if(!Detaching())
   167 		{
   168 		{
   168 		delete iProvider;
   169 		delete iProvider;
   169 		iProvider = NULL;
   170 		iProvider = NULL;
   170 		}
   171 		}
   171 
   172 
   281 	// Legacy support for host resolvers
   282 	// Legacy support for host resolvers
   282 	if(iHostResolverNotify)
   283 	if(iHostResolverNotify)
   283 		{
   284 		{
   284 		__ASSERT_DEBUG(!iProvider, User::Panic(KSpecAssert_ESockSSocksspshm, 9));	// can't have both HR & SAP
   285 		__ASSERT_DEBUG(!iProvider, User::Panic(KSpecAssert_ESockSSocksspshm, 9));	// can't have both HR & SAP
   285 
   286 
   286 		LOG( ESockLog::Printf(_L8("CTransportFlowShim %08x:\tUnbind(): iBearerExpected %d"), this, iBearerExpected) );
   287 		LOG( ESockLog::Printf(_L8("CTransportFlowShim %08x:\tUnbind(): iBearerExpected %d"), this, BearerExpected()) );
   287 		if (!iBearerExpected)
   288 		if (!BearerExpected())
   288 			{
   289 			{
   289 			delete this;
   290 			delete this;
   290 			}
   291 			}
   291 		else
   292 		else
   292 			{
   293 			{
   293 			iDeleteUponBearerReception = ETrue;
   294 			SetDeleteUponBearerReception();
   294 			iHostResolverNotify = NULL;
   295 			iHostResolverNotify = NULL;
   295 			}
   296 			}
   296 		return;
   297 		return;
   297 		}
   298 		}
   298 
   299 
   299 	if (iProvider)
   300 	if (iProvider)
   300 		{
   301 		{
   301 		iProvider->SetNotify(NULL);
   302 		iProvider->SetNotify(NULL);
   302 
   303 
   303 		if (!iDetaching)
   304 		if (!Detaching())
   304 			{
   305 			{
   305 			delete iProvider;
   306 			delete iProvider;
   306 			iProvider = NULL;
   307 			iProvider = NULL;
   307 			}
   308 			}
   308 		}
   309 		}
   410 Do the actual no Bearer call.
   411 Do the actual no Bearer call.
   411 @return ETrue if the NoBearer post was actually done, EFalse otherwise
   412 @return ETrue if the NoBearer post was actually done, EFalse otherwise
   412 */
   413 */
   413 	{
   414 	{
   414 	TInt ret = EFalse;
   415 	TInt ret = EFalse;
   415 	if(!iIsStopped)
   416 	if(!Stopped())
   416 		{ // Prevent sending NoBearer if DataClientStop was received
   417 		{ // Prevent sending NoBearer if DataClientStop was received
   417 		if (LockToConnectionInfo() != KErrNone)
   418 		if (LockToConnectionInfo() != KErrNone)
   418 		    {
   419 		    {
   419 	        __ASSERT_DEBUG(iSubConnectionProvider.IsOpen(), User::Panic(KSpecAssert_ESockSSocksspshm, 66));
   420 	        __ASSERT_DEBUG(iSubConnectionProvider.IsOpen(), User::Panic(KSpecAssert_ESockSSocksspshm, 66));
   420 			PostNoBearer();
   421 			PostNoBearer();
   421 			ret = ETrue;
   422 			ret = ETrue;
   422 		    }
   423 		    }
   423 		iUseBearerErrors = EFalse;
   424 		ClearUseBearerErrors();
       
   425 
   424 		ClearDataClientRoutedGuard();
   426 		ClearDataClientRoutedGuard();
   425 		}
   427 		}
   426 	return ret;
   428 	return ret;
   427 	}
   429 	}
   428 
   430 
   630 @param option The shutdown type. */
   632 @param option The shutdown type. */
   631 	{
   633 	{
   632 	__ASSERT_DEBUG(iProvider, User::Panic(KSpecAssert_ESockSSocksspshm, 24));
   634 	__ASSERT_DEBUG(iProvider, User::Panic(KSpecAssert_ESockSSocksspshm, 24));
   633 	if (aOption == MSessionControl::EImmediate)
   635 	if (aOption == MSessionControl::EImmediate)
   634 		{
   636 		{
   635 		iShuttingDown = ETrue;
   637 		SetShuttingDown();
   636 		}
   638 		}
   637 
   639 
   638 	// It is possible for the provider to be null if an error occurs immediatly
   640 	// It is possible for the provider to be null if an error occurs immediatly
   639 	// after socket creation before the flow is bound and the provider is received
   641 	// after socket creation before the flow is bound and the provider is received
   640 	// from the protocol.
   642 	// from the protocol.
   878 	{
   880 	{
   879 	LOG( ESockLog::Printf(_L("CTransportFlowShim %08x:\tCanClose() aDelete %d"), this, aDelete) );
   881 	LOG( ESockLog::Printf(_L("CTransportFlowShim %08x:\tCanClose() aDelete %d"), this, aDelete) );
   880 
   882 
   881 	if(iSessionControlNotify)
   883 	if(iSessionControlNotify)
   882 		{
   884 		{
   883 		iDetaching = aDelete == MSocketNotify::EDetach;
   885 		aDelete == MSocketNotify::EDetach ? SetDetaching() : ClearDetaching();
       
   886 		
   884 		iSessionControlNotify->CanClose(MSessionControlNotify::TDelete(aDelete));
   887 		iSessionControlNotify->CanClose(MSessionControlNotify::TDelete(aDelete));
   885         if(aDelete==MSocketNotify::EDetach)
   888         if(aDelete==MSocketNotify::EDetach)
   886             {
   889             {
   887             iProvider = NULL;
   890             iProvider = NULL;
   888             }
   891             }
   901 	{
   904 	{
   902 	LOG( ESockLog::Printf(_L("CTransportFlowShim %08x:\tCanClose() aDisconnectData %08x, aDelete %d"), this, aDisconnectData.Ptr(), aDelete) );
   905 	LOG( ESockLog::Printf(_L("CTransportFlowShim %08x:\tCanClose() aDisconnectData %08x, aDelete %d"), this, aDisconnectData.Ptr(), aDelete) );
   903 
   906 
   904 	if(iSessionControlNotify)
   907 	if(iSessionControlNotify)
   905 		{
   908 		{
   906         iDetaching = aDelete == MSocketNotify::EDetach;
   909 		aDelete == MSocketNotify::EDetach ? SetDetaching() : ClearDetaching();
   907 		iSessionControlNotify->CanClose(aDisconnectData, MSessionControlNotify::TDelete(aDelete));
   910 		iSessionControlNotify->CanClose(aDisconnectData, MSessionControlNotify::TDelete(aDelete));
   908 		if(aDelete==MSocketNotify::EDetach)
   911 		if(aDelete==MSocketNotify::EDetach)
   909 			{
   912 			{
   910 			iProvider = NULL;
   913 			iProvider = NULL;
   911 			}
   914 			}
   943 		{
   946 		{
   944 		LOG( ESockLog::Printf(_L("CTransportFlowShim %08x:\tError() no control above us to notify (open was likely passive and has not been accepted yet) so simply unbinding"), this) );
   947 		LOG( ESockLog::Printf(_L("CTransportFlowShim %08x:\tError() no control above us to notify (open was likely passive and has not been accepted yet) so simply unbinding"), this) );
   945 
   948 
   946 		// No control above us - likely cause is that we're the result of a passive open that
   949 		// No control above us - likely cause is that we're the result of a passive open that
   947 		// hasn't yet been accepted.
   950 		// hasn't yet been accepted.
   948 		iDetaching = MSocketNotify::EDetach;
   951 		SetDetaching();
   949 		Unbind();
   952 		Unbind();
   950 		}
   953 		}
   951 	}
   954 	}
   952 
   955 
   953 void CTransportFlowShim::Disconnect(void)
   956 void CTransportFlowShim::Disconnect(void)
   962 		{
   965 		{
   963 		LOG( ESockLog::Printf(_L("CTransportFlowShim %08x:\tDisconnect() no control above us to notify (open was likely passive and has not been accepted yet) so simply unbinding"), this) );
   966 		LOG( ESockLog::Printf(_L("CTransportFlowShim %08x:\tDisconnect() no control above us to notify (open was likely passive and has not been accepted yet) so simply unbinding"), this) );
   964 
   967 
   965 		// No control above us - likely cause is that we're the result of a passive open that
   968 		// No control above us - likely cause is that we're the result of a passive open that
   966 		// hasn't yet been accepted.
   969 		// hasn't yet been accepted.
   967 		iDetaching = MSocketNotify::EDetach;
   970 		SetDetaching();
   968 		Unbind();
   971 		Unbind();
   969 		}
   972 		}
   970 	}
   973 	}
   971 
   974 
   972 void CTransportFlowShim::Disconnect(TDesC8& aDisconnectData)
   975 void CTransportFlowShim::Disconnect(TDesC8& aDisconnectData)
   981 		{
   984 		{
   982 		LOG( ESockLog::Printf(_L("CTransportFlowShim %08x:\tDisconnect() no control above us to notify (open was likely passive and has not been accepted yet) so simply unbinding"), this) );
   985 		LOG( ESockLog::Printf(_L("CTransportFlowShim %08x:\tDisconnect() no control above us to notify (open was likely passive and has not been accepted yet) so simply unbinding"), this) );
   983 
   986 
   984 		// No control above us - likely cause is that we're the result of a passive open that
   987 		// No control above us - likely cause is that we're the result of a passive open that
   985 		// hasn't yet been accepted.
   988 		// hasn't yet been accepted.
   986 		iDetaching = MSocketNotify::EDetach;
   989 		SetDetaching();
   987 		Unbind();
   990 		Unbind();
   988 		}
   991 		}
   989 	}
   992 	}
   990 
   993 
   991 void CTransportFlowShim::IoctlComplete(TDesC8 *aBuf)
   994 void CTransportFlowShim::IoctlComplete(TDesC8 *aBuf)
  1025 	if (TConnectionInfo::IsLocalBearer(aConnectionInfo))
  1028 	if (TConnectionInfo::IsLocalBearer(aConnectionInfo))
  1026 		{
  1029 		{
  1027 		return;
  1030 		return;
  1028 		}
  1031 		}
  1029 
  1032 
  1030 	iUseBearerErrors = ETrue;
  1033 	SetUseBearerErrors();
  1031 	LocalName(iLocalAddress);
  1034 	LocalName(iLocalAddress);
  1032 	iLocalAddressSet = ETrue;
  1035 	SetLocalAddressSet();
  1033 	RemName(iRemoteAddress);
  1036 	RemName(iRemoteAddress);
  1034 	iRemoteAddressSet = ETrue;
  1037 	SetRemoteAddressSet();
  1035 	__ASSERT_DEBUG(iSubConnectionProvider.IsOpen(), User::Panic(KSpecAssert_ESockSSocksspshm, 41));	// legacy flows have no control side; should never get here
  1038 	__ASSERT_DEBUG(iSubConnectionProvider.IsOpen(), User::Panic(KSpecAssert_ESockSSocksspshm, 41));	// legacy flows have no control side; should never get here
  1036 
  1039 
  1037 	PostDataClientRouted();
  1040 	PostDataClientRouted();
  1038 	}
  1041 	}
  1039 
  1042 
  1084     	//(2) Rejoing this flow. During rejoin scenario, it's the new owner obtains its new
  1087     	//(2) Rejoing this flow. During rejoin scenario, it's the new owner obtains its new
  1085     	//dataclient ('this') before ('this') dataclient knowing. The rejoin procedure is make
  1088     	//dataclient ('this') before ('this') dataclient knowing. The rejoin procedure is make
  1086     	//before break, hence it tries to apply the new owner, during which time the new
  1089     	//before break, hence it tries to apply the new owner, during which time the new
  1087     	//owner starts and hence attempts to TBindTo his new child. The child hates it
  1090     	//owner starts and hence attempts to TBindTo his new child. The child hates it
  1088     	//as it arrives from an unknown node. The rejoin protocol needs rethinking.
  1091     	//as it arrives from an unknown node. The rejoin protocol needs rethinking.
  1089 		RClientInterface::OpenPostMessageClose(Id(), aSender, TCFDataClient::TBindToComplete(KErrNone).CRef());
  1092 		RClientInterface::OpenPostMessageClose(Id(), aSender, TCFDataClient::TBindToComplete().CRef());
  1090     	return;
  1093     	return;
  1091     	}
  1094     	}
  1092     CNetworkFlow::ReceivedL(aSender, aRecipient, aMessage);
  1095     CNetworkFlow::ReceivedL(aSender, aRecipient, aMessage);
  1093 #ifdef SYMBIAN_NETWORKING_UPS
  1096 #ifdef SYMBIAN_NETWORKING_UPS
  1094 	// Allow derived classes to process received messages.
  1097 	// Allow derived classes to process received messages.
  1156 			{
  1159 			{
  1157 			TCFDataClient::TBindTo& bindToMsg(static_cast<TCFDataClient::TBindTo&>(aMessage));
  1160 			TCFDataClient::TBindTo& bindToMsg(static_cast<TCFDataClient::TBindTo&>(aMessage));
  1158 			TRAPD(err,BindToL(bindToMsg));
  1161 			TRAPD(err,BindToL(bindToMsg));
  1159 			// Ensure that TBindToComplete message gets sent before TIdle so that it gets to the destination
  1162 			// Ensure that TBindToComplete message gets sent before TIdle so that it gets to the destination
  1160 			// before destroy processing.
  1163 			// before destroy processing.
  1161 			RClientInterface::OpenPostMessageClose(Id(), aSender, TCFDataClient::TBindToComplete(err).CRef());
  1164 			if(err == KErrNone)
       
  1165 			    {
       
  1166 			    RClientInterface::OpenPostMessageClose(Id(), aSender, TCFDataClient::TBindToComplete().CRef());
       
  1167 			    }
       
  1168 			else
       
  1169 			    {
       
  1170 			    RClientInterface::OpenPostMessageClose(Id(), aSender, TEBase::TError(aMessage.MessageId(), err).CRef());
       
  1171 			    }
       
  1172 			
       
  1173 			
  1162 			ProcessDCIdleState();	// in case we were waiting to send idle
  1174 			ProcessDCIdleState();	// in case we were waiting to send idle
  1163 			//If we have received TDataClientStart before (when we did not yet have a bearer),
  1175 			//If we have received TDataClientStart before (when we did not yet have a bearer),
  1164 			//we complete the start here as well
  1176 			//we complete the start here as well
  1165 			if (err != KErrNone)
  1177 			if (err != KErrNone)
  1166 				{
  1178 				{
  1168 				//we complete the start here as well
  1180 				//we complete the start here as well
  1169 				if (iStartRequest.IsOpen())
  1181 				if (iStartRequest.IsOpen())
  1170 					{
  1182 					{
  1171 					CompleteStart(err);
  1183 					CompleteStart(err);
  1172 					}
  1184 					}
  1173                iBearerExpected = ETrue;
  1185 				SetBearerExpected();
  1174 				}
  1186 				}
  1175 			else
  1187 			else
  1176 		    	{
  1188 		    	{
  1177 				// If we get a TBindTo message then the TNoBearer request has succeeded
  1189 				// If we get a TBindTo message then the TNoBearer request has succeeded
  1178 				// and we can inform the client.
  1190 				// and we can inform the client.
  1247 		//we complete the start here as well
  1259 		//we complete the start here as well
  1248 		if (iStartRequest.IsOpen())
  1260 		if (iStartRequest.IsOpen())
  1249 			{
  1261 			{
  1250 			CompleteStart(KErrNone);
  1262 			CompleteStart(KErrNone);
  1251 			}
  1263 			}
  1252 		LOG( ESockLog::Printf(_L8("CTransportFlowShim %08x:\tReceivedL(): TBearer: iDeleteUponBearerReception %d"), this, iDeleteUponBearerReception) );
  1264 		LOG( ESockLog::Printf(_L8("CTransportFlowShim %08x:\tReceivedL(): TBearer: iDeleteUponBearerReception %d"), this, DeleteUponBearerReception()));
  1253 
  1265 
  1254 		ClearNoBearerGuard();
  1266 		ClearNoBearerGuard();
  1255 		ProcessDCIdleState();
  1267 		ProcessDCIdleState();
  1256 		NoBearerCompletion();		// may delete this !
  1268 		NoBearerCompletion();		// may delete this !
  1257 		}
  1269 		}
  1264 		}
  1276 		}
  1265     }
  1277     }
  1266 
  1278 
  1267 void CTransportFlowShim::NoBearerCompletion()
  1279 void CTransportFlowShim::NoBearerCompletion()
  1268 	{
  1280 	{
  1269 	iBearerExpected = EFalse;
  1281 	ClearBearerExpected();
  1270 	if (iDeleteUponBearerReception)
  1282 
       
  1283 	if (DeleteUponBearerReception())
  1271 		{
  1284 		{
  1272 		delete this;
  1285 		delete this;
  1273 		}
  1286 		}
  1274 	}
  1287 	}
  1275 
  1288 
  1281 void CTransportFlowShim::CompleteStart(TInt aError)
  1294 void CTransportFlowShim::CompleteStart(TInt aError)
  1282 	{
  1295 	{
  1283 	if (aError==KErrNone)
  1296 	if (aError==KErrNone)
  1284 		{
  1297 		{
  1285 		iStartRequest.ReplyTo(Id(), TCFDataClient::TStarted().CRef());
  1298 		iStartRequest.ReplyTo(Id(), TCFDataClient::TStarted().CRef());
  1286 		iIsStarted = ETrue;
  1299 		SetStarted();
  1287 		iIsStopped = EFalse;
  1300 		ClearStopped();
  1288 		}
  1301 		}
  1289 	else
  1302 	else
  1290 		{
  1303 		{
  1291 		iStartRequest.ReplyTo(Id(), TEBase::TError(TCFDataClient::TStart::Id(),aError).CRef());
  1304 		iStartRequest.ReplyTo(Id(), TEBase::TError(TCFDataClient::TStart::Id(),aError).CRef());
  1292 		}
  1305 		}
  1331 	//the sub-connection
  1344 	//the sub-connection
  1332 
  1345 
  1333 	NM_LOG((KESockServerTag, _L8("CTransportFlowShim %08x:\tSynchronous call: From=%08x To=%08x Func=BindToL"),
  1346 	NM_LOG((KESockServerTag, _L8("CTransportFlowShim %08x:\tSynchronous call: From=%08x To=%08x Func=BindToL"),
  1334 			this, static_cast<Messages::ANode*>(this), &aBindTo.iNodeId.Node()) )
  1347 			this, static_cast<Messages::ANode*>(this), &aBindTo.iNodeId.Node()) )
  1335 
  1348 
  1336 	if (iShuttingDown)
  1349 	if (ShuttingDown())
  1337 		{
  1350 		{
  1338 		User::Leave(KErrCancel);
  1351 		User::Leave(KErrCancel);
  1339 		return;
  1352 		return;
  1340 		}
  1353 		}
  1341 
  1354 
  1342 	CNetworkFlow::BindToL(aBindTo);
  1355 	CNetworkFlow::BindToL(aBindTo);
  1343 	if (iLowerFlow && IsBoundToSession())
  1356 	if (iLowerFlow && IsBoundToSession())
  1344 		{
  1357 		{
  1345 		LockToConnectionInfo();
  1358 		LockToConnectionInfo();
  1346 		LocalName(iLocalAddress);
  1359 		LocalName(iLocalAddress);
  1347 		iLocalAddressSet = ETrue;
  1360 		SetLocalAddressSet();
  1348 		RemName(iRemoteAddress);
  1361 		RemName(iRemoteAddress);
  1349 		iRemoteAddressSet = ETrue;
  1362 		SetRemoteAddressSet();
       
  1363 		
  1350 		__ASSERT_DEBUG(iSubConnectionProvider.IsOpen(), User::Panic(KSpecAssert_ESockSSocksspshm, 48));	// legacy flows have no control side; should never get here
  1364 		__ASSERT_DEBUG(iSubConnectionProvider.IsOpen(), User::Panic(KSpecAssert_ESockSSocksspshm, 48));	// legacy flows have no control side; should never get here
  1351 		}
  1365 		}
  1352 	else if (iHostResolverNotify)
  1366 	else if (iHostResolverNotify)
  1353 	    {//workaroud to indicate to CHostResolver we've got connection info
  1367 	    {//workaroud to indicate to CHostResolver we've got connection info
  1354 	    if (aBindTo.iNodeId.Ptr())
  1368 	    if (aBindTo.iNodeId.Ptr())
  1380         }
  1394         }
  1381     }
  1395     }
  1382 
  1396 
  1383 void CTransportFlowShim::StartFlowL(const TRuntimeCtxId& aSender)
  1397 void CTransportFlowShim::StartFlowL(const TRuntimeCtxId& aSender)
  1384 	{
  1398 	{
  1385 	__ASSERT_DEBUG(!iIsStarted, User::Panic(KSpecAssert_ESockSSocksspshm, 49));
  1399 	__ASSERT_DEBUG(!Started(), User::Panic(KSpecAssert_ESockSSocksspshm, 49));
  1386 	__ASSERT_DEBUG(iSubConnectionProvider.IsOpen(), User::Panic(KSpecAssert_ESockSSocksspshm, 50));	// legacy flows have no control side; should never get here
  1400 	__ASSERT_DEBUG(iSubConnectionProvider.IsOpen(), User::Panic(KSpecAssert_ESockSSocksspshm, 50));	// legacy flows have no control side; should never get here
  1387 
  1401 
  1388 	//We will wait for it and complete the start after we have received it
  1402 	//We will wait for it and complete the start after we have received it
  1389 	User::LeaveIfError(iStartRequest.Open(iSubConnectionProvider, aSender));
  1403 	User::LeaveIfError(iStartRequest.Open(iSubConnectionProvider, aSender));
  1390 
  1404 
  1391 	if (iDCIdle != EClientsPresent)
  1405 	if (Idle())
  1392 		{
  1406 		{
  1393 		iStartRequest.ReplyTo(Id(), TEBase::TError(TCFDataClient::TStart::Id(), KErrNotReady).CRef());
  1407 		iStartRequest.ReplyTo(Id(), TEBase::TError(TCFDataClient::TStart::Id(), KErrNotReady).CRef());
  1394 		iStartRequest.Close();
  1408 		iStartRequest.Close();
  1395 		return;
  1409 		return;
  1396 		}
  1410 		}
  1397 
  1411 
  1398 	if (iLowerFlow)
  1412 	if (iLowerFlow)
  1399 		{
  1413 		{
  1400 		iStartRequest.ReplyTo(Id(), TCFDataClient::TStarted().CRef());
  1414 		iStartRequest.ReplyTo(Id(), TCFDataClient::TStarted().CRef());
  1401 		iStartRequest.Close();
  1415 		iStartRequest.Close();
  1402 		iIsStarted = ETrue;
  1416 		SetStarted();
  1403 		iIsStopped = EFalse;
  1417 		ClearStopped();
  1404 		return;
  1418 		return;
  1405 		}
  1419 		}
  1406 
  1420 
  1407 	//We need a bearer
  1421 	//We need a bearer
  1408 		PostNoBearer(); //Ask for bearer if not requested already
  1422 		PostNoBearer(); //Ask for bearer if not requested already
  1409 
  1423 
  1410 	}
  1424 	}
  1411 
  1425 
  1412 void CTransportFlowShim::StopFlow(TCFDataClient::TStop& aMessage)
  1426 void CTransportFlowShim::StopFlow(TCFDataClient::TStop& aMessage)
  1413 	{
  1427 	{
  1414 	__ASSERT_DEBUG(iIsStarted, User::Panic(KSpecAssert_ESockSSocksspshm, 51)); //Must be started now
       
  1415 	__ASSERT_DEBUG(iSubConnectionProvider.IsOpen(), User::Panic(KSpecAssert_ESockSSocksspshm, 52));	// legacy flows have no control side; should never get here
  1428 	__ASSERT_DEBUG(iSubConnectionProvider.IsOpen(), User::Panic(KSpecAssert_ESockSSocksspshm, 52));	// legacy flows have no control side; should never get here
  1416 
  1429 
  1417 	// We need to error the socket if the lower protocol stack is not going to do this.  Once a
  1430 	// We need to error the socket if the lower protocol stack is not going to do this.  Once a
  1418 	// Bearer() upcall has been received, the lower protocol will call Error() if the connection
  1431 	// Bearer() upcall has been received, the lower protocol will call Error() if the connection
  1419 	// goes down.  Before this point, the lower protocol will not call Error(), so StopFlow() calls
  1432 	// goes down.  Before this point, the lower protocol will not call Error(), so StopFlow() calls
  1423 	// has attached a flow to a route (and hence an interface) which, in turn, only occurs once the
  1436 	// has attached a flow to a route (and hence an interface) which, in turn, only occurs once the
  1424 	// interface is up and data has been sent over the socket.  Note that opening an RSocket on an
  1437 	// interface is up and data has been sent over the socket.  Note that opening an RSocket on an
  1425 	// RConnection but not transferring any data will not cause the TCP/IP stack to attach the flow
  1438 	// RConnection but not transferring any data will not cause the TCP/IP stack to attach the flow
  1426 	// to the route and hence not call Error() if the interface comes down.
  1439 	// to the route and hence not call Error() if the interface comes down.
  1427 
  1440 
  1428 	if (IsBoundToSession() && !iUseBearerErrors)
  1441 	if (IsBoundToSession() && aMessage.iValue == KErrForceDisconnected)
       
  1442 		{
       
  1443 		Error(KErrDisconnected, EErrorAllOperations);
       
  1444 		}
       
  1445 	else if (IsBoundToSession() && !UseBearerErrors())
  1429 	    {
  1446 	    {
  1430     	Error(aMessage.iValue, EErrorAllOperations);
  1447     	Error(aMessage.iValue, EErrorAllOperations);
  1431 	    }
  1448 	    }
  1432 
  1449 
  1433 	if (iLowerFlow)
  1450 	if (iLowerFlow)
  1436 		iLowerFlow = NULL;
  1453 		iLowerFlow = NULL;
  1437 		}
  1454 		}
  1438 	iLowerControl = NULL;
  1455 	iLowerControl = NULL;
  1439 
  1456 
  1440 	iSubConnectionProvider.PostMessage(Id(), TCFDataClient::TStopped(aMessage.iValue).CRef());
  1457 	iSubConnectionProvider.PostMessage(Id(), TCFDataClient::TStopped(aMessage.iValue).CRef());
  1441 	iIsStarted = EFalse;
  1458 	ClearStarted();
  1442 	iIsStopped = ETrue;
  1459 	SetStopped();
  1443 	}
  1460 	}
  1444 
  1461 
  1445 void CTransportFlowShim::InitDestroy()
  1462 void CTransportFlowShim::InitDestroy()
  1446 	{
  1463 	{
  1447     __ASSERT_DEBUG(iDCIdle <= EClientsPresent, User::Panic(KSpecAssert_ESockSSocksspshm, 53));
  1464 	__ASSERT_DEBUG(!(Idle() || IdleSent()), User::Panic(KSpecAssert_ESockSSocksspshm, 53));
  1448     iDCIdle = EIdle;
  1465     SetIdle();
  1449 
  1466 
  1450     if(iSubConnectionProvider.IsOpen())	// legacy flows have no control side
  1467     if(iSubConnectionProvider.IsOpen())	// legacy flows have no control side
  1451     	{
  1468     	{
  1452     	ProcessDCIdleState();
  1469     	ProcessDCIdleState();
  1453     	}
  1470     	}
  1471 		}
  1488 		}
  1472 	}
  1489 	}
  1473 
  1490 
  1474 void CTransportFlowShim::PostDataClientRouted()
  1491 void CTransportFlowShim::PostDataClientRouted()
  1475 	{
  1492 	{
  1476  	if (iLocalAddressSet && iRemoteAddressSet
  1493 	if (LocalAddressSet() && RemoteAddressSet()
  1477 	&& iRemoteAddress.Family() != KAFUnspec && !iDataClientRoutedGuard)
  1494 		&& iRemoteAddress.Family() != KAFUnspec && !DataClientRoutedGuard())
  1478 		{
  1495 		{
  1479 		iSubConnectionProvider.PostMessage(
  1496 		iSubConnectionProvider.PostMessage(
  1480 			Id(),
  1497 			Id(),
  1481 			TCFIPMessages::TDataClientRouted(
  1498 			TCFIPMessages::TDataClientRouted(
  1482 				TAddrUpdate(
  1499 				TAddrUpdate(
  1484 					iRemoteAddress,
  1501 					iRemoteAddress,
  1485 					iFlowParams.iProtocol,
  1502 					iFlowParams.iProtocol,
  1486 					iIfInfo.iIAPId)
  1503 					iIfInfo.iIAPId)
  1487 				).CRef()
  1504 				).CRef()
  1488 			);
  1505 			);
  1489 		iDataClientRoutedGuard = ETrue;
  1506 		SetDataClientRoutedGuard();
  1490 		}
  1507 		}
  1491 	}
  1508 	}
  1492 
       
  1493 void CTransportFlowShim::ClearDataClientRoutedGuard()
       
  1494 	{
       
  1495 	iDataClientRoutedGuard = EFalse;
       
  1496 	}
       
  1497 
       
  1498 
  1509 
  1499 /*
  1510 /*
  1500 Store the provision information passed from the Control side.
  1511 Store the provision information passed from the Control side.
  1501 @param TProvisionConfig Message recd.
  1512 @param TProvisionConfig Message recd.
  1502 */
  1513 */
  1768 			Error(result, MSocketNotify::EErrorSend | MSocketNotify::EErrorConnect);
  1779 			Error(result, MSocketNotify::EErrorSend | MSocketNotify::EErrorConnect);
  1769 			return;
  1780 			return;
  1770 			}
  1781 			}
  1771 		}
  1782 		}
  1772 
  1783 
  1773 	if(!IsStopped())
  1784 	if(!Stopped())
  1774 		{ // Prevent sending NoBearer if DataClientStop was received
  1785 		{ // Prevent sending NoBearer if DataClientStop was received
  1775 		ParseNoBearerParams(aConnectionParams);
  1786 		ParseNoBearerParams(aConnectionParams);
  1776 		if (iIsScoped)
  1787 		if (iIsScoped)
  1777 		    {
  1788 		    {
  1778 		    if (!disableUpsCheck && UpsEnabled())
  1789 		    if (!disableUpsCheck && UpsEnabled())
  1885 @param aResponse TPolicyCheckResponse message
  1896 @param aResponse TPolicyCheckResponse message
  1886 */
  1897 */
  1887 	{
  1898 	{
  1888 	SetPolicyCheckRequestPending(EFalse);
  1899 	SetPolicyCheckRequestPending(EFalse);
  1889 
  1900 
  1890 	if (iDCIdle == EIdle)
  1901 	if (Idle() && !IdleSent())
  1891 		{
  1902 		{
  1892 		ProcessDCIdleState();
  1903 		ProcessDCIdleState();
  1893 		}
  1904 		}
  1894 	else
  1905 	else
  1895 		{
  1906 		{