datacommsserver/esockserver/ssock/ss_connstates.cpp
branchRCL_3
changeset 26 b564fb5fd78b
parent 25 9d7ce34704c8
--- a/datacommsserver/esockserver/ssock/ss_connstates.cpp	Tue Aug 31 16:25:36 2010 +0300
+++ b/datacommsserver/esockserver/ssock/ss_connstates.cpp	Wed Sep 01 12:35:48 2010 +0100
@@ -56,7 +56,7 @@
 #include <comms-infras/ss_upsaccesspointconfigext.h>
 #include <comms-infras/upsmessages.h>
 #endif
-
+#include <comms-infras/ss_roles.h>
 #ifdef _DEBUG
 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
 // (if it could happen through user error then you should give it an explicit, documented, category + code)
@@ -252,35 +252,6 @@
 		TCFMessage::TStateChange(TStateChange(KFinishedSelection,KErrNone)).CRef());
 	}
 
-DEFINE_SMELEMENT(ConnStates::TJoinReceivedCpr, NetStateMachine::MStateTransition, ConnStates::TContext)
-void ConnStates::TJoinReceivedCpr::DoL()
-	{
-	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
-	__ASSERT_DEBUG(iContext.Node().ServiceProvider()==NULL, ConnPanic(KPanicExpectedNoServiceProvider));
-
-	TCFDataClient::TBindTo& bt = message_cast<TCFDataClient::TBindTo>(iContext.iMessage);
-    RNodeInterface* newSP = iContext.Node().AddClientL(bt.iNodeId, TClientType(TCFClientType::EServProvider, TCFClientType::EActive));
-    __ASSERT_DEBUG(iContext.Node().ServiceProvider()==newSP, ConnPanic(KPanicNoServiceProvider)); //[RZ] revise this, possibly overdefensive
-
-    //If this is attach, we need to see if we are a monitor or not
-    TClientType clientType(TCFClientType::ECtrl);
-
-    TUint selPrefs = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity).SelectionPrefs().Flags();
-    if (selPrefs & TSelectionPrefs::EMonitor)
-    	{
-		clientType.SetFlags(TCFClientType::EMonitor);
-    	iContext.Node().iIsMonitor = ETrue;
-    	}
-
-	// If it is an attach set the flag cause it is used by NetUPS to check if a JoinRequest comes from an RConnection::Attach
-	if (selPrefs & TSelectionPrefs::EAttach)
-    	{
-		clientType.SetFlags(TCFClientType::EAttach);
-    	}
-    iContext.iNodeActivity->PostRequestTo(*newSP,
-    	TCFServiceProvider::TJoinRequest(iContext.NodeId(), clientType).CRef());
-	}
-
 DEFINE_SMELEMENT(ConnStates::TJoinReceivedSCpr, NetStateMachine::MStateTransition, ConnStates::TContext)
 void ConnStates::TJoinReceivedSCpr::DoL()
 	{
@@ -470,9 +441,11 @@
 	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
     CSubConnection* waitingSubConn = iContext.Node().Session()->CSubConnectionFromHandle(static_cast<CESockClientActivityBase&>(*iContext.iNodeActivity).Int0());
 	User::LeaveIfError(waitingSubConn != NULL ? KErrNone : KErrCancel);
-
+    RNodeInterface* waitingSubConnPeer = iContext.Node().FindClient(waitingSubConn->Id()); //To my surprise SC is a peer of this (so must use peer handle when talking to it)
+    __ASSERT_DEBUG(waitingSubConnPeer, ConnPanic(KPanicNoDataClient));
+    	
     TCFServiceProvider::TCommsBinderResponse& binderResp = message_cast<TCFServiceProvider::TCommsBinderResponse>(iContext.iMessage);
-    iContext.iNodeActivity->PostRequestTo(waitingSubConn->Id(),
+    iContext.iNodeActivity->PostRequestTo(*waitingSubConnPeer,
         TCFDataClient::TBindTo(binderResp.iNodeId).CRef());
 	}
 
@@ -1301,9 +1274,61 @@
 		{
 		iNode.RemoveClient(aux->RecipientId());
 		}
+
+    if (iRegisteredForInterfaceStateChanges)
+        {
+        CCommsFactoryBase* ipProtoCprFactory = IpProtoCprFactory();
+        if (ipProtoCprFactory)
+            {
+            Factories::IFactoryNotify itf(this, GetVTable());
+            ipProtoCprFactory->DeRegisterNotifier(itf);
+            }
+        }
+
 	delete iAllInterfaceNotificationWorker; //delete this node (why via iAllInterfaceNotificationWorker??)
 	}
 
+/**
+Called by the IpProtoCpr factory to propagate an interface state change from IpProtoCpr to registered
+observers (suc as ourself).  If the interface is restarting, then we need to insert an EInterfaceDown,
+EInterfaceUp "toggle" sequence into the AllInterfaceNotification queue.  This is because, ordinarily,
+EInterfaceUp and EInterfaceDown are generated when the IpProtoCpr itself is created and destroyed,
+but not if it is restarted before being destroyed. 
+*/
+void CAllInterfaceNotificationActivity::InterfaceStateChangeNotification(const TDesC8& aInfo)
+    {
+    if (aInfo.Length() == sizeof(TInterfaceNotification))
+        {
+        const TInterfaceNotification* const info = reinterpret_cast<const TInterfaceNotification*>(aInfo.Ptr());
+        if (info && info->iState == EInterfaceRestarting)
+            {
+            LOG( ESockLog::Printf(KESockConnectionTag, _L("CAllInterfaceNotificationActivity %08x:\tInterfaceStateChangeNotification(): CConnection %08x, IapId %d, NetId %d"),
+                this, &iAllInterfaceNotificationWorker->iConnection, info->iConnectionInfo.iIapId, info->iConnectionInfo.iNetId  ));
+
+            AConnectionLegacy& legacy = iAllInterfaceNotificationWorker->iConnection.iLegacyConnection;
+            TInterfaceNotification notification(*info);
+            notification.iState = EInterfaceDown;
+            legacy.iNotificationQueue.Enque(notification);
+            notification.iState = EInterfaceUp;
+            legacy.iNotificationQueue.Enque(notification);
+            legacy.CompleteAllInterfaceNotificationL(KErrNone);
+            }
+        }
+    }
+
+CCommsFactoryBase* CAllInterfaceNotificationActivity::IpProtoCprFactory() const
+    {
+    CConnectionFactoryContainer& container = *static_cast<CPlayer&>(iAllInterfaceNotificationWorker->iConnection.Player()).SockManGlobals()->iConnectionFactories;
+    return static_cast<CCommsFactoryBase*>(container.FindFactory(TUid::Uid(AConnectionLegacy::KIPProtoConnectionProviderFactoryUid)));
+    }
+
+// Registration table for receiving InterfaceStateChangeNotification() events.
+const Factories::TAnyFn CAllInterfaceNotificationActivity::iInterfaceVTableF[] =
+    {
+    (Factories::TAnyFn)1, // number of methods. the following entries must be in this order!
+    (Factories::TAnyFn)(Factories::TFactoryNotify<CAllInterfaceNotificationActivity>::Notification)
+    };
+
 // States
 
 DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TAwaitingStart, NetStateMachine::MState, TContext)
@@ -1459,6 +1484,23 @@
 	TCFTierStatusProvider::TTierNotification& msg = message_cast<TCFTierStatusProvider::TTierNotification>(iContext.iMessage);
 
 	__ASSERT_DEBUG(msg.iBundle, User::Panic(KSpecAssert_ESockSSockscnsts, 14));
+	
+    CAllInterfaceNotificationActivity& act = *iContext.Activity();
+    
+    // Register with the IpProtoCpr factory for interface state changes if we haven't already done so.
+    // We can only do this if the IpProtoCpr is active, and the assumption here is that it must be active
+    // if an interface event has been generated.
+    if (!act.iRegisteredForInterfaceStateChanges)
+        {
+        CCommsFactoryBase* ipProtoCprFactory = act.IpProtoCprFactory();
+        if (ipProtoCprFactory)
+            {
+            Factories::IFactoryNotify itf(&act, act.GetVTable());
+            ipProtoCprFactory->RegisterNotifierL(itf);
+            act.iRegisteredForInterfaceStateChanges = ETrue;
+            }
+        }
+
 	if(msg.iBundle->PtrL()->CountParamSetContainers() > 0)
 		{
 		TInt i = 0;