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 } |
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 |
1247 //we complete the start here as well |
1250 //we complete the start here as well |
1248 if (iStartRequest.IsOpen()) |
1251 if (iStartRequest.IsOpen()) |
1249 { |
1252 { |
1250 CompleteStart(KErrNone); |
1253 CompleteStart(KErrNone); |
1251 } |
1254 } |
1252 LOG( ESockLog::Printf(_L8("CTransportFlowShim %08x:\tReceivedL(): TBearer: iDeleteUponBearerReception %d"), this, iDeleteUponBearerReception) ); |
1255 LOG( ESockLog::Printf(_L8("CTransportFlowShim %08x:\tReceivedL(): TBearer: iDeleteUponBearerReception %d"), this, DeleteUponBearerReception())); |
1253 |
1256 |
1254 ClearNoBearerGuard(); |
1257 ClearNoBearerGuard(); |
1255 ProcessDCIdleState(); |
1258 ProcessDCIdleState(); |
1256 NoBearerCompletion(); // may delete this ! |
1259 NoBearerCompletion(); // may delete this ! |
1257 } |
1260 } |
1281 void CTransportFlowShim::CompleteStart(TInt aError) |
1285 void CTransportFlowShim::CompleteStart(TInt aError) |
1282 { |
1286 { |
1283 if (aError==KErrNone) |
1287 if (aError==KErrNone) |
1284 { |
1288 { |
1285 iStartRequest.ReplyTo(Id(), TCFDataClient::TStarted().CRef()); |
1289 iStartRequest.ReplyTo(Id(), TCFDataClient::TStarted().CRef()); |
1286 iIsStarted = ETrue; |
1290 SetStarted(); |
1287 iIsStopped = EFalse; |
1291 ClearStopped(); |
1288 } |
1292 } |
1289 else |
1293 else |
1290 { |
1294 { |
1291 iStartRequest.ReplyTo(Id(), TEBase::TError(TCFDataClient::TStart::Id(),aError).CRef()); |
1295 iStartRequest.ReplyTo(Id(), TEBase::TError(TCFDataClient::TStart::Id(),aError).CRef()); |
1292 } |
1296 } |
1331 //the sub-connection |
1335 //the sub-connection |
1332 |
1336 |
1333 NM_LOG((KESockServerTag, _L8("CTransportFlowShim %08x:\tSynchronous call: From=%08x To=%08x Func=BindToL"), |
1337 NM_LOG((KESockServerTag, _L8("CTransportFlowShim %08x:\tSynchronous call: From=%08x To=%08x Func=BindToL"), |
1334 this, static_cast<Messages::ANode*>(this), &aBindTo.iNodeId.Node()) ) |
1338 this, static_cast<Messages::ANode*>(this), &aBindTo.iNodeId.Node()) ) |
1335 |
1339 |
1336 if (iShuttingDown) |
1340 if (ShuttingDown()) |
1337 { |
1341 { |
1338 User::Leave(KErrCancel); |
1342 User::Leave(KErrCancel); |
1339 return; |
1343 return; |
1340 } |
1344 } |
1341 |
1345 |
1342 CNetworkFlow::BindToL(aBindTo); |
1346 CNetworkFlow::BindToL(aBindTo); |
1343 if (iLowerFlow && IsBoundToSession()) |
1347 if (iLowerFlow && IsBoundToSession()) |
1344 { |
1348 { |
1345 LockToConnectionInfo(); |
1349 LockToConnectionInfo(); |
1346 LocalName(iLocalAddress); |
1350 LocalName(iLocalAddress); |
1347 iLocalAddressSet = ETrue; |
1351 SetLocalAddressSet(); |
1348 RemName(iRemoteAddress); |
1352 RemName(iRemoteAddress); |
1349 iRemoteAddressSet = ETrue; |
1353 SetRemoteAddressSet(); |
|
1354 |
1350 __ASSERT_DEBUG(iSubConnectionProvider.IsOpen(), User::Panic(KSpecAssert_ESockSSocksspshm, 48)); // legacy flows have no control side; should never get here |
1355 __ASSERT_DEBUG(iSubConnectionProvider.IsOpen(), User::Panic(KSpecAssert_ESockSSocksspshm, 48)); // legacy flows have no control side; should never get here |
1351 } |
1356 } |
1352 else if (iHostResolverNotify) |
1357 else if (iHostResolverNotify) |
1353 {//workaroud to indicate to CHostResolver we've got connection info |
1358 {//workaroud to indicate to CHostResolver we've got connection info |
1354 if (aBindTo.iNodeId.Ptr()) |
1359 if (aBindTo.iNodeId.Ptr()) |
1380 } |
1385 } |
1381 } |
1386 } |
1382 |
1387 |
1383 void CTransportFlowShim::StartFlowL(const TRuntimeCtxId& aSender) |
1388 void CTransportFlowShim::StartFlowL(const TRuntimeCtxId& aSender) |
1384 { |
1389 { |
1385 __ASSERT_DEBUG(!iIsStarted, User::Panic(KSpecAssert_ESockSSocksspshm, 49)); |
1390 __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 |
1391 __ASSERT_DEBUG(iSubConnectionProvider.IsOpen(), User::Panic(KSpecAssert_ESockSSocksspshm, 50)); // legacy flows have no control side; should never get here |
1387 |
1392 |
1388 //We will wait for it and complete the start after we have received it |
1393 //We will wait for it and complete the start after we have received it |
1389 User::LeaveIfError(iStartRequest.Open(iSubConnectionProvider, aSender)); |
1394 User::LeaveIfError(iStartRequest.Open(iSubConnectionProvider, aSender)); |
1390 |
1395 |
1391 if (iDCIdle != EClientsPresent) |
1396 if (Idle()) |
1392 { |
1397 { |
1393 iStartRequest.ReplyTo(Id(), TEBase::TError(TCFDataClient::TStart::Id(), KErrNotReady).CRef()); |
1398 iStartRequest.ReplyTo(Id(), TEBase::TError(TCFDataClient::TStart::Id(), KErrNotReady).CRef()); |
1394 iStartRequest.Close(); |
1399 iStartRequest.Close(); |
1395 return; |
1400 return; |
1396 } |
1401 } |
1397 |
1402 |
1398 if (iLowerFlow) |
1403 if (iLowerFlow) |
1399 { |
1404 { |
1400 iStartRequest.ReplyTo(Id(), TCFDataClient::TStarted().CRef()); |
1405 iStartRequest.ReplyTo(Id(), TCFDataClient::TStarted().CRef()); |
1401 iStartRequest.Close(); |
1406 iStartRequest.Close(); |
1402 iIsStarted = ETrue; |
1407 SetStarted(); |
1403 iIsStopped = EFalse; |
1408 ClearStopped(); |
1404 return; |
1409 return; |
1405 } |
1410 } |
1406 |
1411 |
1407 //We need a bearer |
1412 //We need a bearer |
1408 PostNoBearer(); //Ask for bearer if not requested already |
1413 PostNoBearer(); //Ask for bearer if not requested already |
1409 |
1414 |
1410 } |
1415 } |
1411 |
1416 |
1412 void CTransportFlowShim::StopFlow(TCFDataClient::TStop& aMessage) |
1417 void CTransportFlowShim::StopFlow(TCFDataClient::TStop& aMessage) |
1413 { |
1418 { |
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 |
1419 __ASSERT_DEBUG(iSubConnectionProvider.IsOpen(), User::Panic(KSpecAssert_ESockSSocksspshm, 52)); // legacy flows have no control side; should never get here |
1416 |
1420 |
1417 // We need to error the socket if the lower protocol stack is not going to do this. Once a |
1421 // 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 |
1422 // 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 |
1423 // 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 |
1427 // 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 |
1428 // 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 |
1429 // 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. |
1430 // to the route and hence not call Error() if the interface comes down. |
1427 |
1431 |
1428 if (IsBoundToSession() && !iUseBearerErrors) |
1432 if (IsBoundToSession() && aMessage.iValue == KErrForceDisconnected) |
|
1433 { |
|
1434 Error(KErrDisconnected, EErrorAllOperations); |
|
1435 } |
|
1436 else if (IsBoundToSession() && !UseBearerErrors()) |
1429 { |
1437 { |
1430 Error(aMessage.iValue, EErrorAllOperations); |
1438 Error(aMessage.iValue, EErrorAllOperations); |
1431 } |
1439 } |
1432 |
1440 |
1433 if (iLowerFlow) |
1441 if (iLowerFlow) |
1436 iLowerFlow = NULL; |
1444 iLowerFlow = NULL; |
1437 } |
1445 } |
1438 iLowerControl = NULL; |
1446 iLowerControl = NULL; |
1439 |
1447 |
1440 iSubConnectionProvider.PostMessage(Id(), TCFDataClient::TStopped(aMessage.iValue).CRef()); |
1448 iSubConnectionProvider.PostMessage(Id(), TCFDataClient::TStopped(aMessage.iValue).CRef()); |
1441 iIsStarted = EFalse; |
1449 ClearStarted(); |
1442 iIsStopped = ETrue; |
1450 SetStopped(); |
1443 } |
1451 } |
1444 |
1452 |
1445 void CTransportFlowShim::InitDestroy() |
1453 void CTransportFlowShim::InitDestroy() |
1446 { |
1454 { |
1447 __ASSERT_DEBUG(iDCIdle <= EClientsPresent, User::Panic(KSpecAssert_ESockSSocksspshm, 53)); |
1455 __ASSERT_DEBUG(!(Idle() || IdleSent()), User::Panic(KSpecAssert_ESockSSocksspshm, 53)); |
1448 iDCIdle = EIdle; |
1456 SetIdle(); |
1449 |
1457 |
1450 if(iSubConnectionProvider.IsOpen()) // legacy flows have no control side |
1458 if(iSubConnectionProvider.IsOpen()) // legacy flows have no control side |
1451 { |
1459 { |
1452 ProcessDCIdleState(); |
1460 ProcessDCIdleState(); |
1453 } |
1461 } |