--- a/commsfwsupport/commselements/meshmachine/src/mm_node.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/commsfwsupport/commselements/meshmachine/src/mm_node.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -401,11 +401,12 @@
TBool awoke = ETrue;
TInt c = iActivities.Count();
TNodeNullContext context(*this);
+
//Clean up..
- while (awoke && c > 0)
+ while (awoke)
{
awoke = EFalse;
- for (TInt i = c - 1 ; i>=0 ; --i)
+ for (TInt i = iActivities.Count() - 1 ; i>=0 ; --i)
{
//Signal to waiting activities if:
//1) an event was received (& the state has potentialy changed as a result)
@@ -414,25 +415,18 @@
//If any signalled activity reacted, the state could change and all other activities need to be signalled again.
context.iNodeActivity = iActivities[i];
awoke |= context.iNodeActivity->Signal(context);
- if(context.iNodeActivity->IsIdle())
- {
- iActivities.Remove(i);
- context.iNodeActivity->Destroy();
- context.iNodeActivity = NULL;
- // NOTE: if "aContext.iNodeActivity" is the destroy activity, then deleting
- // it will destroy the node (i.e. "this") as well, so don't put anything after this line !
- if (c == 1)
- {
- // c == 1 means that we've just removed the last activity (also means i will be zero)
- // i == 0 means that this round of signalling parked activities has been completed
- // This is effectively safeguarding the access to iActivities which may or may not be
- // there (based on the note above). The destroy activity will always be placed at the
- // head of the list, and will therefore be the last to get processed.
- return;
- }
- }
}
- c = iActivities.Count();
+ }
+
+ for (TInt i = iActivities.Count() - 1 ; i>=0 ; --i)
+ {
+ context.iNodeActivity = iActivities[i];
+ if(context.iNodeActivity->IsIdle())
+ {
+ iActivities.Remove(i);
+ context.iNodeActivity->Destroy();
+ context.iNodeActivity = NULL;
+ }
}
}
--- a/commsfwsupport/commselements/serverden/src/sd_workersession.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/commsfwsupport/commselements/serverden/src/sd_workersession.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -694,7 +694,8 @@
EXPORT_C CWorkerSubSession::~CWorkerSubSession()
{
- COMMONLOG((Session()->WorkerId(),KECommonServerTag, _L8("CWorkerSubSession(%08x):\t~CWorkerSubSession() Session(%08x)"), this, iSession));
+ // Session may be disappeared by now, so DO NOT USE IT
+ COMMONLOG((CommsFW::KInvalidWorkerId, KECommonServerTag, _L8("CWorkerSubSession(%08x):\t~CWorkerSubSession() Session(%08x)"), this, iSession));
//All interfaces must be closed by now (by the derived subsession's destructor the latest)
__ASSERT_DEBUG(iApiExtRegister.InterfaceCount() == 0, User::Panic(KSpecAssert_ElemSvrDenWrkrSC, 15));
--- a/commsfwtools/commstools/svg/parselog.pl Thu Dec 17 09:22:25 2009 +0200
+++ b/commsfwtools/commstools/svg/parselog.pl Thu Jan 07 13:34:53 2010 +0200
@@ -428,17 +428,12 @@
ClearActivity($actAddr);
}
elsif ($action eq "Abort") {
- print "t ", objectName($activityNode{$actAddr}), " (Abort ", $activityName{$actAddr}, ")\n";
+ print "t ", objectName($activityNode{$actAddr}), " ($activityName{$actAddr}) Abort()\n";
}
- elsif ($action eq "Next->cancel") {
- my $tuple = "";
- if (m/\[Triple=([^]]+)\]/) {
- $tuple = $1;
- print "t ", objectName($activityNode{$actAddr}), " (Cancel $activityName{$actAddr}, $tuple)\n";
- }
- else {
- print "t ", objectName($activityNode{$actAddr}), " (Cancel ", $activityName{$actAddr}, ")\n";
- }
+ elsif ($action =~ m/Cancel\(\)/) {
+ m/iPostedToId ([0-9a-f]{8})/;
+ my $postedToId = $1;
+ print "t ", objectName($activityNode{$actAddr}), " ($activityName{$actAddr}) Cancel(). Posted to ", objectName($postedToId), "\n";
}
}
elsif (($opt_X & 4) == 0 && /UnparkState->unparked\s+\[MNode=0x([0-9a-fA-F]{8})\].*\[Activity=(\w+)\].*\[Triple=(.*?)\]/)
--- a/commsfwtools/preparedefaultcommsdatabase/Tools/ced/inc/dbdef.h Thu Dec 17 09:22:25 2009 +0200
+++ b/commsfwtools/preparedefaultcommsdatabase/Tools/ced/inc/dbdef.h Thu Jan 07 13:34:53 2010 +0200
@@ -1335,7 +1335,7 @@
#endif // __COMMDB_ROHID_SUPPORT__
COMMDB_ID,
COMMDB_NAME,
- VPN_SERVICE_POLICY,VPN_SERVICE_IAP,VPN_SERVICE_NETWORKID,
+ VPN_SERVICE_POLICY,VPN_SERVICE_IAP,KCDTypeNameVPNSNAPRecord,VPN_SERVICE_NETWORKID,
VPN_SERVICE_ENABLE_LLMNR,
NO_MORE_RECORDS
};
@@ -3022,6 +3022,12 @@
NO_MORE_RECORDS
};
#endif //SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+
+const TText* const LINK_REC_VPNSERVICEcolumnArray [] =
+ {
+ KCDTypeNameVPNSNAPRecord,
+ NO_MORE_RECORDS
+ };
/**
This enum is used as index for LinkRecords Arrays
@@ -3041,6 +3047,7 @@
ELRAPPrioritySel,
ELRTier,
#endif //SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ ELRVPNService,
ELRWAPIPBearer
};
@@ -3062,6 +3069,7 @@
AP_PRIORITY_SELECTION_POLICY_TABLE,
TIER_TABLE,
#endif //SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ VPN_SERVICE,
WAP_IP_BEARER,
NO_MORE_RECORDS
};
@@ -3083,6 +3091,7 @@
(const TText** const)LINK_REC_APPRIORITYSELECTIONPOLICYcolumnArray,
(const TText** const)LINK_REC_TIERcolumnArray,
#endif //SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ (const TText** const)LINK_REC_VPNSERVICEcolumnArray,
(const TText** const)LINK_REC_WAPIPBEARER_Array
};
@@ -3100,10 +3109,11 @@
_S("AccessPointTable"),
_S("WLANServiceExtensionTable"),
_S("EAPSecuritySettingsTable"),
- _S("TunnelledEAPSettingsTable")
+ _S("TunnelledEAPSettingsTable"),
+ KCDTypeNameVPNSNAPRecord
};
-const TInt LinkedRecordTableNum = 7;
+const TInt LinkedRecordTableNum = 8;
const TText* const LegacyLinkFields[] =
--- a/commsfwtools/preparedefaultcommsdatabase/Tools/ced/src/database.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/commsfwtools/preparedefaultcommsdatabase/Tools/ced/src/database.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -1010,6 +1010,9 @@
err = SetLinkedRecord(ELRTier, aPtrField,aColumn,aSetting,aAttribute);
break;
#endif //SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ case KCDTIdVPNServiceRecord:
+ err = SetLinkedRecord(ELRVPNService, aPtrField,aColumn,aSetting,aAttribute);
+ break;
default: ;
}
--- a/commsfwtools/preparedefaultcommsdatabase/inc/CommsDatTypeInfoV1_1.h Thu Dec 17 09:22:25 2009 +0200
+++ b/commsfwtools/preparedefaultcommsdatabase/inc/CommsDatTypeInfoV1_1.h Thu Jan 07 13:34:53 2010 +0200
@@ -636,13 +636,15 @@
// FieldTIds
- const TMDBElementId KCDTIdVPNPolicyName = 0x05830000; //< Commsdat field id for field: Policy. Policy name. Field is declared in the VPNService table.
- const TMDBElementId KCDTIdVPNIAPRecord = 0x05840000; //< Commsdat field id for field: HomeIAP. Link to a IAP record. Field is declared in the VPNService table.
- const TMDBElementId KCDTIdVPNNetwork = 0x05850000; //< Commsdat field id for field: HomeNetwork. Link to a Network record. Field is declared in the VPNService table.
+ const TMDBElementId KCDTIdVPNPolicyName = 0x05830000; ///< Commsdat field id for field: Policy. Policy name. Field is declared in the VPNService table.
+ const TMDBElementId KCDTIdVPNIAPRecord = 0x05840000; ///< Commsdat field id for field: HomeIAP. Link to a IAP record. Field is declared in the VPNService table.
+ const TMDBElementId KCDTIdVPNSNAPRecord = 0x05860000; ///< Commsdat field id for field: SNAPIAP. Link to a snap iap record. Field is declared in the VPNService table.
+ const TMDBElementId KCDTIdVPNNetwork = 0x05850000; ///< Commsdat field id for field: HomeNetwork. Link to a Network record. Field is declared in the VPNService table.
#define KCDTypeNameVPNPolicyName _S("Policy")
#define KCDTypeNameVPNIAPRecord _S("HomeIAP")
+ #define KCDTypeNameVPNSNAPRecord _S("HomeSNAP")
#define KCDTypeNameVPNNetwork _S("HomeNetwork")
--- a/commsfwtools/preparedefaultcommsdatabase/inc/CommsDatTypesV1_1.h Thu Dec 17 09:22:25 2009 +0200
+++ b/commsfwtools/preparedefaultcommsdatabase/inc/CommsDatTypesV1_1.h Thu Jan 07 13:34:53 2010 +0200
@@ -833,9 +833,10 @@
public:
// Member Data
- CMDBField<TDesC> iServicePolicy; //< Policy id of the policy file- this is a reference to the policy file.
- CMDBRecordLink<CCDIAPRecord> iServiceIAP; //< Record id of the real IAP used by the IPSEC software to communicate with the VPN gateway.
- CMDBRecordLink<CCDNetworkRecord> iServiceNetwork;//< Record id of the real Network to be connected to by the virtual tunnel.
+ CMDBField<TDesC> iServicePolicy; ///< Policy id of the policy file- this is a reference to the policy file.
+ CMDBRecordLink<CCDIAPRecord> iServiceIAP; ///< Record id of the real IAP used by the IPSEC software to communicate with the VPN gateway.
+ CMDBRecordLink<CCDAccessPointRecord> iServiceSNAP; ///< Record id of the SNAP id used by the IPSEC software to communicate with the VPN gateway.
+ CMDBRecordLink<CCDNetworkRecord> iServiceNetwork;///< Record id of the real Network to be connected to by the virtual tunnel.
private:
--- a/commsfwtools/preparedefaultcommsdatabase/src/CommsDatSchema.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/commsfwtools/preparedefaultcommsdatabase/src/CommsDatSchema.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -451,6 +451,7 @@
// This class
{ KCDTIdVPNPolicyName, EText, ENotNull, KCDTypeNameVPNPolicyName },
{ KCDTIdVPNIAPRecord, ELinkIAPRecord, ENoAttrs, KCDTypeNameVPNIAPRecord },
+ { KCDTIdVPNSNAPRecord, ELinkAPRecord, ENoAttrs, KCDTypeNameVPNSNAPRecord },
{ KCDTIdVPNNetwork, ELinkNetworkRecord, ENoAttrs, KCDTypeNameVPNNetwork },
/**** add new fields above this comment ****/
// service base class
--- a/commsfwtools/preparedefaultcommsdatabase/src/CommsDatTypesV1_1.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/commsfwtools/preparedefaultcommsdatabase/src/CommsDatTypesV1_1.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -811,10 +811,14 @@
X_REGISTER_ATTRIBUTE( CCDVPNServiceRecord, iServicePolicy, TMDBText )
#ifdef SYMBIAN_COMMSDAT_USE_INT_RECORD_LINKS
X_REGISTER_ATTRIBUTE( CCDVPNServiceRecord, iServiceIAP, TMDBNum )
+ X_REGISTER_ATTRIBUTE( CCDVPNServiceRecord, iServiceSNAP, TMDBNum )
X_REGISTER_ATTRIBUTE( CCDVPNServiceRecord, iServiceNetwork, TMDBNum )
#else
X_REGISTER_ATTRIBUTE( CCDVPNServiceRecord, iServiceIAP, TMDBLinkNum )
- X_REGISTER_ATTRIBUTE( CCDVPNServiceRecord, iServiceNetwork, TMDBLinkNum )
+#endif
+ X_REGISTER_ATTRIBUTE( CCDVPNServiceRecord, iServiceSNAP, TMDBLinkNum )
+#ifndef SYMBIAN_COMMSDAT_USE_INT_RECORD_LINKS
+ X_REGISTER_ATTRIBUTE( CCDVPNServiceRecord, iServiceNetwork, TMDBLinkNum )
#endif // SYMBIAN_COMMSDAT_USE_INT_RECORD_LINKS
END_ATTRIBUTE_TABLE_BASE( CCDServiceRecordBase, KCDTIdServiceRecordBase)
--- a/datacommsserver/esockserver/CoreProviders/src/corecprstates.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/CoreProviders/src/corecprstates.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -21,6 +21,7 @@
@file
@internalComponent
*/
+
#define SYMBIAN_NETWORKING_UPS
#include <comms-infras/ss_log.h>
@@ -328,13 +329,15 @@
const TCFDataClient::TBindTo& bindToMsg(message_cast<const TCFDataClient::TBindTo>(iContext.iMessage));
__ASSERT_DEBUG(!bindToMsg.iNodeId.IsNull(), User::Panic(KCoreCprPanic, KPanicNoServiceProvider));
- activity.iNewServiceProvider = iContext.Node().AddClientL(bindToMsg.iNodeId,
- TClientType(TCFClientType::EServProvider, TCFClientType::EActivating));
- //Join the new service provider
- iContext.iNodeActivity->PostRequestTo(*activity.iNewServiceProvider,
- TCFControlClient::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::ECtrl), iContext.Node().Priority()).CRef());
+
+ RNodeInterface* newServiceProvider = iContext.Node().AddClientL(bindToMsg.iNodeId,
+ TClientType(TCFClientType::EServProvider, TCFClientType::EActivating));
+ __ASSERT_DEBUG(newServiceProvider, User::Panic(KCoreCprPanic, KPanicNoServiceProvider));
+ activity.iNewServiceProvider = bindToMsg.iNodeId;
+ //Join the new service provider
+ activity.PostRequestTo(*newServiceProvider,
+ TCFControlClient::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::ECtrl), iContext.Node().Priority()).CRef());
}
-
}
EXPORT_DEFINE_SMELEMENT(THandleDataClientIdle, NetStateMachine::MStateTransition, CprStates::TContext)
--- a/datacommsserver/esockserver/CoreProviders/src/coremcpractivities.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/CoreProviders/src/coremcpractivities.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -144,7 +144,7 @@
DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityNoBearer, MCprNoBearer, TCFControlProvider::TNoBearer, PRActivities::CNoBearer::NewL)
FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingNoBearer, CNoBearer::TNoTagOrBearerPresentBlockedByNoBearer)
NODEACTIVITY_ENTRY(KNoTag, MCprStates::TSelectNextLayer, MCprStates::TAwaitingSelectNextLayerCompleted, CoreNetStates::TNoTagOrBearerPresent)
-
+
//Special for the Meta Plane (don't just copy & paste)
NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreNetStates::TStartServiceProvider, CoreNetStates::TAwaitingStarted, TTag<CoreNetStates::KBearerPresent>)
NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreNetStates::TRequestCommsBinderRetry, CoreNetStates::TAwaitingBinderResponse, TTag<CoreNetStates::KBearerPresent>)
@@ -443,7 +443,7 @@
const TLayerSelectionInfo* selectInfo = static_cast<const TLayerSelectionInfo*>(iContext.Node().AccessPointConfig().FindExtension(
STypeId::CreateSTypeId(TLayerSelectionInfo::EUid, TLayerSelectionInfo::ETypeId)));
__ASSERT_ALWAYS(selectInfo, CoreMCprPanic(KPanicUnexpectedExecutionPath));
-
+
TUint selectionPolicyId = selectInfo->CustomSelectionPolicy();
//Running this transition, we can't be at the bottom of the stack!
@@ -486,7 +486,7 @@
const TLayerSelectionInfo* selectInfo = static_cast<const TLayerSelectionInfo*>(iContext.Node().AccessPointConfig().FindExtension(
STypeId::CreateSTypeId(TLayerSelectionInfo::EUid, TLayerSelectionInfo::ETypeId)));
__ASSERT_ALWAYS(selectInfo, CoreMCprPanic(KPanicUnexpectedExecutionPath));
-
+
TUint selectionPolicyId = selectInfo->SelectionPolicy();
//Running this transition, we can't be at the bottom of the stack!
@@ -580,7 +580,7 @@
const TLayerSelectionInfo* selectInfo = static_cast<const TLayerSelectionInfo*>(iContext.Node().AccessPointConfig().FindExtension(
STypeId::CreateSTypeId(TLayerSelectionInfo::EUid, TLayerSelectionInfo::ETypeId)));
__ASSERT_ALWAYS(selectInfo, CoreMCprPanic(KPanicUnexpectedExecutionPath));
-
+
TUint selectionPolicyId = selectInfo->CustomSelectionPolicy();
//Running this transition, we can't be at the bottom of the stack!
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/CoreProviders/src/coremcpractivities.cpp.orig Thu Jan 07 13:34:53 2010 +0200
@@ -0,0 +1,975 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "coremcpractivities.h"
+
+
+#include <comms-infras/ss_log.h>
+#include <comms-infras/ss_coreprstates.h>
+#include <comms-infras/coremcprstates.h>
+#include <comms-infras/esock_params.h>
+#include <comms-infras/ss_nodemessages_selector.h>
+#include <comms-infras/ss_nodemessages_dataclient.h>
+#include <comms-infras/ss_nodemessages_serviceprovider.h>
+#include <comms-infras/ss_nodemessages_availability.h>
+#include <comms-infras/ss_nodemessages_factory.h>
+#include <comms-infras/ss_nodemessages_tiermanagerfactory.h>
+#include <comms-infras/ss_nodemessages_mcpr.h>
+
+#include <elements/nm_messages_peer.h>
+#include <elements/nm_messages_errorrecovery.h>
+#include <elements/nm_messages_child.h>
+#include <comms-infras/ss_tiermanagerutils.h>
+#include <ss_glob.h>
+#include "ss_internal_activities.h"
+#include <commsdattypesv1_1.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)
+_LIT(KSpecAssert_ESockCoreProvcprac, "ESockCrPrvcprac");
+#endif
+
+#ifdef __CFLOG_ACTIVE
+ #define KCoreMCprStatesTag KESockMetaConnectionTag
+ _LIT8(KCoreMCprStatesSubTag, "coremcprstate");
+#endif
+
+using namespace ESock;
+using namespace MCprActivities;
+using namespace NetStateMachine;
+using namespace PRActivities;
+using namespace CorePanics;
+using namespace Messages;
+using namespace MeshMachine;
+
+
+//
+//Panics
+void CoreMCprPanic(TInt aCode)
+ {
+ _LIT(KCoreMCprPanic, "CoreMCprPanic");
+ User::Panic(KCoreMCprPanic, aCode);
+ }
+
+
+namespace MCprControlClientJoinActivity
+{ //This activity needs the activity object (& it can fail on AddClientL, so no point converting)
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityClientJoin, MCprControlClientJoin, Messages::TNodeSignal::TNullMessageId) //May be waiting for both messages
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingControlClientJoin, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MCprStates::TDecrementBlockingDestroyAndAddControlClientAndSendJoinCompleteIfRequest)
+NODEACTIVITY_END()
+}
+
+namespace MCprDataClientJoinActivity
+{ //This activity needs the activity object (& it can fail on AddClientL, so no point converting)
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityDataClientJoin, MCprDataClientJoin, TCFControlProvider::TJoinRequest)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientJoinRequest, MCprStates::TNoTagOrRejoinTag)
+ LAST_NODEACTIVITY_ENTRY(MCprStates::KRejoinTag, MCprStates::TProcessDataClientRejoin)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MCprStates::TDecrementBlockingDestroyAndAddDataClientAndRespond)
+NODEACTIVITY_END()
+}
+
+namespace MCprDestroyActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityDestroy, MCprDestroy, Messages::TNodeSignal::TNullMessageId, CoreActivities::CDestroyActivity::New) //May be waiting for both messages
+ FIRST_NODEACTIVITY_ENTRY(MCprStates::TAwaitingClientLeaveAndNoClients, MeshMachine::TNoTag)
+ //MCprStates::TProcessClientLeave removes the client and marks the node for deletion.
+ //If there are no servce providers it also terminates the activity.
+ //If there are service providers it continues to following triples.
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, MCprStates::TProcessClientLeave, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, MeshMachine::TAwaitingLeaveComplete, CoreActivities::CDestroyActivity::TNoTagOrNoTagBackwards)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingAndRemoveControlProvider)
+NODEACTIVITY_END()
+}
+
+namespace MCprSimpleSelectActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivitySelect, MCprSimpleSelect, TCFSelector::TSimpleSelect, CSelectNextLayerActivity::NewL)
+ //Reply from TAwaitingSelectNextLayer if no choices, otherwise accept
+ FIRST_NODEACTIVITY_ENTRY(MCprStates::TAwaitingSelectNextLayer, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, CSelectNextLayerActivity::TProcessSimpleSelectionPolicy, MCprStates::TSelectedProvider)
+ //Start the selection main loop
+ NODEACTIVITY_ENTRY(MCprStates::KSelectedProvider, CSelectNextLayerActivity::TFindOrCreateTierManager, MCprStates::TAwaitingTierManagerCreated, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CSelectNextLayerActivity::TJoinTierManager, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag)
+ //Select next provider and enter the selection internal loop if provider received. Break if SelectComplete(NULL).
+ NODEACTIVITY_ENTRY(KNoTag, CSelectNextLayerActivity::TSelectNextLayer, MCprStates::TAwaitingSelectComplete, CSelectNextLayerActivity::TNoTagOrSelectedProviderIsNull)
+ NODEACTIVITY_ENTRY(KNoTag, CSelectNextLayerActivity::TAddProviderInfo, MCprStates::TAwaitingSelectComplete, CSelectNextLayerActivity::TNoTagBackwardsOrJoinServiceProvider)
+ //Break the selection internal loop if SelectComplete(NULL), otherwise stay in this tripple
+ NODEACTIVITY_ENTRY(MCprStates::KJoinServiceProvider, CSelectNextLayerActivity::TJoinServiceProvider, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, CSelectNextLayerActivity::TSendSelectComplete, CSelectNextLayerActivity::TSelectedProviderIsNullOrJoinServiceProviderBackward)
+ //Break the selection main loop if no more choices, otherwise go back again
+ THROUGH_NODEACTIVITY_ENTRY(MCprStates::KSelectedProviderIsNull, CSelectNextLayerActivity::TLeaveTierManager, CSelectNextLayerActivity::TNoTagOrSelectedProviderBackward)
+ //Finish the activity
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MCprStates::TSendFinalSelectComplete)
+NODEACTIVITY_END()
+}
+
+namespace MCprSimpleSelectActivitySuper
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivitySelect, MCprSimpleSelect, TCFSelector::TSelect, CSelectNextLayerActivity::NewL)
+ //Reply from TAwaitingSelectNextLayer if no choices, otherwise accept
+ FIRST_NODEACTIVITY_ENTRY(MCprStates::TAwaitingSelectNextLayerSuper, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, CSelectNextLayerActivity::TProcessPrioritisedSelectionPolicySuper, MCprStates::TSelectedProvider)
+ //Start the selection main loop
+ NODEACTIVITY_ENTRY(MCprStates::KSelectedProvider, CSelectNextLayerActivity::TFindOrCreateTierManagerSuper, MCprStates::TAwaitingTierManagerCreated, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CSelectNextLayerActivity::TJoinTierManager, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag)
+ //Select next provider and enter the selection internal loop if provider received. Break if SelectComplete(NULL).
+ NODEACTIVITY_ENTRY(KNoTag, CSelectNextLayerActivity::TSelectNextLayerSuper, MCprStates::TAwaitingSelectComplete, CSelectNextLayerActivity::TNoTagOrSelectedProviderIsNull)
+ NODEACTIVITY_ENTRY(KNoTag, CSelectNextLayerActivity::TAddProviderInfo, MCprStates::TAwaitingSelectComplete, CSelectNextLayerActivity::TNoTagBackwardsOrJoinServiceProvider)
+ //Break the selection internal loop if SelectComplete(NULL), otherwise stay in this tripple
+ NODEACTIVITY_ENTRY(MCprStates::KJoinServiceProvider, CSelectNextLayerActivity::TJoinServiceProvider, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, CSelectNextLayerActivity::TSendSelectComplete, CSelectNextLayerActivity::TSelectedProviderIsNullOrJoinServiceProviderBackward)
+ //Break the selection main loop if no more choices, otherwise go back again
+ THROUGH_NODEACTIVITY_ENTRY(MCprStates::KSelectedProviderIsNull, CSelectNextLayerActivity::TLeaveTierManager, CSelectNextLayerActivity::TNoTagOrSelectedProviderBackwardSuper)
+ //Finish the activity
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MCprStates::TSendFinalSelectComplete)
+NODEACTIVITY_END()
+}
+
+namespace MCprNoBearerActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityNoBearer, MCprNoBearer, TCFControlProvider::TNoBearer, PRActivities::CNoBearer::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingNoBearer, CNoBearer::TNoTagOrBearerPresentBlockedByNoBearer)
+ NODEACTIVITY_ENTRY(KNoTag, MCprStates::TSelectNextLayer, MCprStates::TAwaitingSelectNextLayerCompleted, CoreNetStates::TNoTagOrBearerPresent)
+
+ //Special for the Meta Plane (don't just copy & paste)
+// NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreNetStates::TStartServiceProvider, CoreNetStates::TAwaitingStarted, TTag<CoreNetStates::KBearerPresent>)
+ NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreNetStates::TRequestCommsBinderRetry, CoreNetStates::TAwaitingBinderResponse, TTag<CoreNetStates::KBearerPresent>)
+ NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreNetStates::TSendBindTo, CoreNetStates::TAwaitingBindToComplete, TTag<CoreNetStates::KBearerPresent>)
+ THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreActivities::ABindingActivity::TSendBindToComplete, MeshMachine::TNoTag)
+
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendBearer)
+NODEACTIVITY_END()
+}
+
+namespace MCprReConnectActivity
+{
+//MCprConnectionStartRecovery activity belongs to a group of Error Recovery Activities.
+//Error Recovery Activities need to handle their own errors (generated as well as returned).
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityReConnect, MCprReConnect, TCFMcpr::TReConnect, CReConnectActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(MCprStates::TAwaitingReConnectRequest, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, CReConnectActivity::TProcessReConnectRequest, MeshMachine::TNoTag)
+
+ //Build lower layer
+ NODEACTIVITY_ENTRY(KNoTag, CReConnectActivity::TBuildLowerLayer, CoreNetStates::TAwaitingBindToComplete, MeshMachine::TNoTag)
+
+ //Respond
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CReConnectActivity::TSendReConnectResponse)
+NODEACTIVITY_END()
+}
+
+namespace MCprErrorRecoveryDefaultActivity
+{
+//This is a default error recovery activity.
+//It always replies with TErrorRecoveryResponse(EPropagate).
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityErrorRecovery, DefaultErrorRecovery, TEErrorRecovery::TErrorRecoveryRequest)
+ NODEACTIVITY_ENTRY(KNoTag, MCprStates::TSendPropagateRecoveryResponse, MCprStates::TAwaitingErrorRecoveryRequest, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace MCprBinderRequestActivity
+{
+// MCPRs can only have one data client, hence the use of CoreNetStates::TNoTagOrDataClientPresent.
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityBinderRequest, MCprBinderRequest, TCFServiceProvider::TCommsBinderRequest, CCommsBinderActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingBinderRequest, CCommsBinderActivity::TNoTagOrUseExistingBlockedByBinderRequest)
+ NODEACTIVITY_ENTRY(KNoTag, PRStates::TCreateDataClient, CoreNetStates::TAwaitingDataClientJoin, MeshMachine::TNoTag)
+
+ // Below this point we need to modify the error handling approach. If we're getting a TError on TBinderResponse,
+ // this means the client requesting the binder couldn't bind to it. As far as the client is concerned, this
+ // activity is finished (it has flagged an error). The standard error handling will result in erroring
+ // the originator. In this case we shouoldn't error the originator, instead, wrap up quietly.
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, CCommsBinderActivity::TProcessDataClientCreation, TTag<CoreStates::KUseExisting>)
+
+ NODEACTIVITY_ENTRY(CoreStates::KUseExisting, CCommsBinderActivity::TSendBinderResponse, CCommsBinderActivity::TAwaitingBindToComplete, MeshMachine::TNoTagOrErrorTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TClearError)
+NODEACTIVITY_END()
+}
+
+namespace MCprReportProviderStatusActivity
+{
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityReportProviderStatus, MCprReportProviderStatus, TCFMcpr::TProviderStatusChangeRegistration)
+ // for other requests "joining in"
+ NODEACTIVITY_ENTRY(KNoTag, MCprStates::TProcessProviderStatusChangeRegistration, MeshMachine::TAwaitingAny, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, CoreNetStates::TAwaitingProviderStatusChangeOrDataClientStatusChange, MCprStates::TDataClientStatusChangeOrNoTag)
+ // Process the provider status change notification sent from provider on left
+ THROUGH_NODEACTIVITY_ENTRY(MCprStates::KDataClientStatusChange, PRStates::THandleDataClientStatusChangeAndDestroyOrphans, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, MCprStates::TPostStatusChangeToOriginators, CoreNetStates::TAwaitingProviderStatusChangeOrDataClientStatusChange, MCprStates::TDataClientStatusChangeBackwardsOrNoTagBackwards)
+ // Never get past this point
+NODEACTIVITY_END()
+}
+
+namespace MCprAvailabilityNotificationActivity
+{
+// Reference availability notification activity.
+// Forwards availability registrations down to lower MCPRs
+// Then combines their responses into a single TAvailability object and sends the notification upwards if anything has changed
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityAvailabilityNotification, MCprAvailability, TCFAvailabilityProvider::TAvailabilityNotificationRegistration, CAvailabilityActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(MeshMachine::TAwaitingMessageState<TCFAvailabilityProvider::TAvailabilityNotificationRegistration>, MeshMachine::TNoTag)
+
+ //Select Service Providers (availability sources - if any)
+ NODEACTIVITY_ENTRY(KNoTag, MCprStates::TSelectNextLayer, MCprStates::TAwaitingSelectNextLayerCompleted, MeshMachine::TNoTagOrErrorTag)
+
+ //Register for notifications with all Service Providers (if any)
+ NODEACTIVITY_ENTRY(KNoTag, CAvailabilityActivity::TRegisterForNotifications, MCprStates::TAwaitingAvailabilityNotificationOrError, TErrorTagOr<TTag<MCprStates::KProcessAvailability> >)
+
+ //Process the availability notification and loop (if success, or finish on failure)
+ NODEACTIVITY_ENTRY(MCprStates::KProcessAvailability, CAvailabilityActivity::TProcessNotification, MCprStates::TAwaitingAvailabilityNotificationOrError, TErrorTagOr<TTag<MCprStates::KProcessAvailability|EBackward> >)
+
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TRaiseAndClearActivityError)
+NODEACTIVITY_END()
+}
+
+// Also if this Message is not expected to be received from the MCpr, we
+// manage it.
+namespace MCprDataClientGoneDownActivity
+{
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityDataClientGoneDown, MCprDataClientGoneDown, TCFControlProvider::TDataClientGoneDown)
+ // The only thing we do is to clear(unset) the "Flags" of
+ // the relative DataClient from "EStart": this is done
+ // in "TAwaitingDataClientGoneDown".
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientGoneDown, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
+NODEACTIVITY_END()
+}
+
+namespace MCprStartActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStart, MCprStart, TCFServiceProvider::TStart, PRActivities::CStartActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingStart, CoreNetStates::TNoTagOrBearerPresentBlockedByStop)
+ NODEACTIVITY_ENTRY(KNoTag, MCprStates::TSelectNextLayer, MCprStates::TAwaitingSelectNextLayerCompleted, CoreNetStates::TNoTagOrBearerPresent)
+ NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreNetStates::TBindSelfToPresentBearer, CoreNetStates::TAwaitingBindToComplete, TTag<CoreNetStates::KBearerPresent>)
+
+ //Start the service provider, use the default cancellation.
+ //Forward TCancel to the service provider, wait for TStarted or TError (via the Error Activity)
+ //When TStarted arrives after TCancel the activity will move to the nearest KErrorTag
+ NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreNetStates::TStartServiceProviderRetry, CoreNetStates::TAwaitingStarted, MeshMachine::TNoTagOrErrorTag)
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing)
+ //Start data clients, use the default cancellation.
+ //Forward TCancel to the self, wait for TCFDataClient::TStarted or TError (via the Error Activity)
+ //When TCFDataClient::TStarted arrives after TCancel the activity will move to the nearest KErrorTag
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStartSelf, CoreNetStates::TAwaitingDataClientStarted, MeshMachine::TNoTagOrErrorTag)
+ NODEACTIVITY_ENTRY(KErrorTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TErrorTag)
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendStarted)
+NODEACTIVITY_END()
+}
+
+namespace MCprStopActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStop, MCprStop, TCFServiceProvider::TStop, MeshMachine::CNodeRetryActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingStop, CoreNetStates::TActiveOrNoTagBlockedByBindTo)
+ THROUGH_NODEACTIVITY_ENTRY(KActiveTag, CoreNetStates::TCancelDataClientStart, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, CoreNetStates::TNoTagOrNoBearer)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendStop, CoreNetStates::TAwaitingStopped, TTag<CoreNetStates::KNoBearer>)
+ LAST_NODEACTIVITY_ENTRY(CoreNetStates::KNoBearer, PRStates::TSendStoppedAndGoneDown)
+NODEACTIVITY_END()
+}
+
+namespace MCprActivities
+{
+//This activity map should be used if the MCPR only supports the
+//selection message TSelectNextLayerConnPrefList. Nodes using this activity
+//map will not support legacy selection
+DEFINE_EXPORT_ACTIVITY_MAP(coreMCprActivitiesSuper)
+ ACTIVITY_MAP_ENTRY(MCprDestroyActivity, MCprDestroy)
+ ACTIVITY_MAP_ENTRY(MCprSimpleSelectActivitySuper, MCprSimpleSelect)
+ ACTIVITY_MAP_ENTRY(MCprNoBearerActivity, MCprNoBearer)
+ ACTIVITY_MAP_ENTRY(MCprReConnectActivity, MCprReConnect)
+ ACTIVITY_MAP_ENTRY(MCprAvailabilityNotificationActivity, MCprAvailability)
+ ACTIVITY_MAP_ENTRY(MCprBinderRequestActivity, MCprBinderRequest)
+ ACTIVITY_MAP_ENTRY(MCprReportProviderStatusActivity, MCprReportProviderStatus)
+ ACTIVITY_MAP_ENTRY(MCprDataClientJoinActivity, MCprDataClientJoin)
+ ACTIVITY_MAP_ENTRY(MCprControlClientJoinActivity, MCprControlClientJoin)
+ ACTIVITY_MAP_ENTRY(MCprErrorRecoveryDefaultActivity, DefaultErrorRecovery)
+ ACTIVITY_MAP_ENTRY(MCprDataClientGoneDownActivity, MCprDataClientGoneDown)
+ ACTIVITY_MAP_ENTRY(MCprStopActivity, MCprStop)
+ ACTIVITY_MAP_ENTRY(MCprStartActivity, MCprStart)
+ACTIVITY_MAP_END_BASE(PRActivities, coreActivitiesMCpr)
+
+//This activiy map supports legacy selection and the additional activity
+//is that support. It should be used where tier managers need to support
+//selection message TSelectNextLayer
+DEFINE_EXPORT_ACTIVITY_MAP(coreMCprActivities)
+ ACTIVITY_MAP_ENTRY(MCprSimpleSelectActivity, MCprSimpleSelect)
+ACTIVITY_MAP_END_BASE(MCprActivities, coreMCprActivitiesSuper)
+}
+
+//
+//CSelectNextLayerActivity
+EXPORT_C MeshMachine::CNodeActivityBase* CSelectNextLayerActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ CSelectNextLayerActivity* self = new (ELeave) CSelectNextLayerActivity(aActivitySig, aNode);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+EXPORT_C void CSelectNextLayerActivity::ConstructL()
+ {
+ iDbs = CommsDat::CMDBSession::NewL(KCDVersion1_2);
+
+ }
+
+EXPORT_C CSelectNextLayerActivity::~CSelectNextLayerActivity()
+ {
+ if (!iTierManager.IsNull())
+ {
+ // Only leave if the iTierManager is still a client - only happens in some
+ // error cases for example if the Join fails the generic TError handling
+ // does not call iTierManager.SetNull(), also if AddClientL() leaves.
+ // TierManager is always a special case because the relationship with
+ // MCPR is always temporary.
+ RNodeInterface* client = iNode.FindClient(iTierManager);
+ if (client)
+ {
+ RClientInterface::OpenPostMessageClose(iNode.Id(), iTierManager, TEChild::TLeft().CRef());
+ iNode.RemoveClient(iTierManager);
+ }
+ iTierManager.SetNull();
+ }
+ delete iDbs;
+ iSelectCompleteMessages.Close();
+ }
+
+EXPORT_C TConnIdList& CSelectNextLayerActivity::SelectionChoices()
+ {
+ return iSelectionChoices;
+ }
+
+EXPORT_C ESock::RConnPrefList& CSelectNextLayerActivity::SelectionConnPrefList()
+ {
+ return iSelectionConnPrefList;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TNoTagOrSelectedProviderIsNull, NetStateMachine::MStateFork, CSelectNextLayerActivity::TContext)
+TInt CSelectNextLayerActivity::TNoTagOrSelectedProviderIsNull::TransitionTag()
+ {
+ //We proceede forward through a transision that will process our concrete message received (NULL or not NULL).
+ TInt tag = MeshMachine::KNoTag | NetStateMachine::EForward;
+ if (message_cast<TCFSelector::TSelectComplete>(iContext.iMessage).iNodeId.IsNull())
+ {
+ tag = MCprStates::KSelectedProviderIsNull | NetStateMachine::EForward;
+ }
+ return tag;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TNoTagBackwardsOrJoinServiceProvider, NetStateMachine::MStateFork, CSelectNextLayerActivity::TContext)
+TInt CSelectNextLayerActivity::TNoTagBackwardsOrJoinServiceProvider::TransitionTag()
+ {
+ TInt tag = MeshMachine::KNoTag | NetStateMachine::EBackward;
+ if (message_cast<TCFSelector::TSelectComplete>(iContext.iMessage).iNodeId.IsNull())
+ {
+ //This is the final select complete that we have received from the selector.
+ tag = MCprStates::KJoinServiceProvider | NetStateMachine::EForward;
+ }
+ return tag;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TSelectedProviderIsNullOrJoinServiceProviderBackward, NetStateMachine::MStateFork, CSelectNextLayerActivity::TContext)
+TInt CSelectNextLayerActivity::TSelectedProviderIsNullOrJoinServiceProviderBackward::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+ if (ac.iSelectCompleteMessages.Count() > 0)
+ {
+ return MCprStates::KJoinServiceProvider | NetStateMachine::EBackward;
+ }
+
+ return MCprStates::KSelectedProviderIsNull | NetStateMachine::EForward;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TNoTagOrSelectedProviderBackward, NetStateMachine::MStateFork, CSelectNextLayerActivity::TContext)
+TInt CSelectNextLayerActivity::TNoTagOrSelectedProviderBackward::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+ if (ac.SelectionChoices().Count() > (ac.iCurrentIndex + 1))
+ {
+ return MCprStates::KSelectedProvider | NetStateMachine::EBackward;
+ }
+
+ return MeshMachine::KNoTag | NetStateMachine::EForward;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TProcessSimpleSelectionPolicy, NetStateMachine::MStateTransition, CSelectNextLayerActivity::TContext)
+void CSelectNextLayerActivity::TProcessSimpleSelectionPolicy::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+ __ASSERT_DEBUG(ac.SelectionChoices().Count() == 0, User::Panic(KSpecAssert_ESockCoreProvcprac, 1)); //It should be empty
+
+ //We are going to process our own selection policy to determine choices
+ //for selection of the next layer.
+
+ //This simple transition interprets the selection policy id
+ //directly as a next layer access point id.
+
+ //This transition is an entry point to the main selection loop which
+ //will process all the inforamtion gathered in this transition.
+ //We initialise the current index to start from the beginning of the list
+ //(next step preincrements).
+ ac.iCurrentIndex = -1;
+
+ if (iContext.Node().AccessPointConfig().FindExtension(TOverridenSelectionPrefsExt::TypeId()))
+ {
+ //Our selection has been overriden by special preferences (so called pass-through
+ //preference) given to us by our control client.
+ __CFLOG_VAR((KCoreMCprStatesTag, KCoreMCprStatesSubTag, _L8("TProcessSimpleSelectionPolicy::DoL() - Selection policy overriden!.")));
+ return;
+ }
+
+ //Now we can interpret the selection policy and store the results for further
+ //processing
+ const TLayerSelectionInfo* selectInfo = static_cast<const TLayerSelectionInfo*>(iContext.Node().AccessPointConfig().FindExtension(
+ STypeId::CreateSTypeId(TLayerSelectionInfo::EUid, TLayerSelectionInfo::ETypeId)));
+ __ASSERT_ALWAYS(selectInfo, CoreMCprPanic(KPanicUnexpectedExecutionPath));
+
+ TUint selectionPolicyId = selectInfo->CustomSelectionPolicy();
+
+ //Running this transition, we can't be at the bottom of the stack!
+ __ASSERT_DEBUG(selectionPolicyId, User::Panic(KSpecAssert_ESockCoreProvcprac, 2));
+
+ //And, of course, for nodes using this transition, it is only one single
+ //access point below.
+ ac.SelectionChoices().Append(selectionPolicyId);
+ }
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TProcessPrioritisedSelectionPolicy, NetStateMachine::MStateTransition, CSelectNextLayerActivity::TContext)
+void CSelectNextLayerActivity::TProcessPrioritisedSelectionPolicy::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+ __ASSERT_DEBUG(ac.SelectionChoices().Count() == 0, User::Panic(KSpecAssert_ESockCoreProvcprac, 3)); //It should be empty
+
+ //We are going to process our own selection policy to determine choices
+ //for selection of the next layer.
+
+ //This simple transition interprets the selection policy id
+ //directly as a next layer access point id.
+
+ //This transition is an entry point to the main selection loop which
+ //will process all the inforamtion gathered in this transition.
+ //We initialise the current index to start from the beginning of the list
+ //(next step preincrements).
+ ac.iCurrentIndex = -1;
+
+ if (iContext.Node().AccessPointConfig().FindExtension(TOverridenSelectionPrefsExt::TypeId()))
+ {
+ //Our selection has been overriden by special preferences (so called pass-through
+ //preference) given to us by our control client.
+ __CFLOG_VAR((KCoreMCprStatesTag, KCoreMCprStatesSubTag, _L8("TProcessPrioritisedSelectionPolicy::DoL() - Selection policy overriden!.")));
+ return;
+ }
+
+ //Now we can interpret the selection policy and store the results for further
+ //processing
+ const TLayerSelectionInfo* selectInfo = static_cast<const TLayerSelectionInfo*>(iContext.Node().AccessPointConfig().FindExtension(
+ STypeId::CreateSTypeId(TLayerSelectionInfo::EUid, TLayerSelectionInfo::ETypeId)));
+ __ASSERT_ALWAYS(selectInfo, CoreMCprPanic(KPanicUnexpectedExecutionPath));
+
+ TUint selectionPolicyId = selectInfo->SelectionPolicy();
+
+ //Running this transition, we can't be at the bottom of the stack!
+ __ASSERT_DEBUG(selectionPolicyId, User::Panic(KSpecAssert_ESockCoreProvcprac, 4));
+
+ //And, of course, for nodes using this transition, all of the choices come
+ //from the simple prioritised selection policy
+ TierManagerUtils::FillListL(ac.SelectionChoices(),selectionPolicyId,ac.Dbs());
+ }
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TFindOrCreateTierManager, NetStateMachine::MStateTransition, CSelectNextLayerActivity::TContext)
+void CSelectNextLayerActivity::TFindOrCreateTierManager::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+
+ //Preincrement the current index
+ ++ac.iCurrentIndex;
+
+ //If we do not have our choices now, this may only mean that our selection
+ //policy has been overriden by our control client.
+ TUid tierId;
+ if (ac.SelectionChoices().Count())
+ {
+ __ASSERT_DEBUG(ac.SelectionChoices().Count() > ac.iCurrentIndex, User::Panic(KSpecAssert_ESockCoreProvcprac, 5)); //Specified choice must be present
+ __ASSERT_DEBUG(iContext.Node().AccessPointConfig().FindExtension(TOverridenSelectionPrefsExt::TypeId()) == NULL, User::Panic(KSpecAssert_ESockCoreProvcprac, 6));
+ tierId = TierManagerUtils::ReadTierIdL(ac.SelectionChoices().Get(ac.iCurrentIndex), ac.Dbs()) ;
+ }
+ else
+ {
+ //Our policy has been overriden
+ const TOverridenSelectionPrefsExt& override = static_cast<const TOverridenSelectionPrefsExt&>(iContext.Node().AccessPointConfig().FindExtensionL(TOverridenSelectionPrefsExt::TypeId()));
+ tierId = override.iTierId;
+ }
+
+ //The tier id must be set now!
+ __ASSERT_DEBUG(tierId.iUid!=0, User::Panic(KSpecAssert_ESockCoreProvcprac, 7));
+ User::LeaveIfError(tierId.iUid!=0? KErrNone : KErrCorrupt); //Check your configuration!
+ TAlwaysFindFactoryQuery query;
+ iContext.iNodeActivity->PostRequestTo(SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::ETierMgrPlane)), TCFFactory::TFindOrCreatePeer(TCFPlayerRole::ETierMgrPlane, tierId, &query).CRef(), EFalse);
+ }
+
+//This is a default implementation of the TSelectNextLayer transition,
+//Other mcprs, especially those with custom selection policies may want
+//to use their own logic to populate the selection preferences for the next layer.
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TSelectNextLayer, NetStateMachine::MStateTransition, CSelectNextLayerActivity::TContext)
+void CSelectNextLayerActivity::TSelectNextLayer::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+
+ if (ac.SelectionChoices().Count())
+ {
+ //We use choices derived from our own selection policy
+ __ASSERT_DEBUG(ac.SelectionChoices().Count() > ac.iCurrentIndex, User::Panic(KSpecAssert_ESockCoreProvcprac, 8)); //Specified choice must be present
+ __ASSERT_DEBUG(iContext.Node().AccessPointConfig().FindExtension(TOverridenSelectionPrefsExt::TypeId())==NULL, User::Panic(KSpecAssert_ESockCoreProvcprac, 9));
+
+ TConnIdList list;
+ list.Append(ac.SelectionChoices().Get(ac.iCurrentIndex));
+
+ TSelectionPrefs newPrefs;
+ newPrefs.SetPrefs(list);
+
+ iContext.iNodeActivity->PostRequestTo(ac.iTierManager, TCFSelector::TSimpleSelect(newPrefs).CRef());
+ }
+ else
+ {
+ //We have been given preferences for the next layer and we use them here
+ const TOverridenSelectionPrefsExt& override = static_cast<const TOverridenSelectionPrefsExt&>(iContext.Node().AccessPointConfig().FindExtensionL(TOverridenSelectionPrefsExt::TypeId()));
+
+ iContext.iNodeActivity->PostRequestTo(ac.iTierManager, TCFSelector::TSimpleSelect(override.iPrefs).CRef());
+ }
+ }
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TProcessSimpleSelectionPolicySuper, NetStateMachine::MStateTransition, CSelectNextLayerActivity::TContext)
+void CSelectNextLayerActivity::TProcessSimpleSelectionPolicySuper::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+
+ //We are going to process our own selection policy to determine choices
+ //for selection of the next layer.
+
+ //This simple transition interprets the selection policy id
+ //directly as a next layer access point id.
+
+ //This transition is an entry point to the main selection loop which
+ //will process all the inforamtion gathered in this transition.
+
+ //Now we can interpret the selection policy and store the results for further
+ //processing
+ const TLayerSelectionInfo* selectInfo = static_cast<const TLayerSelectionInfo*>(iContext.Node().AccessPointConfig().FindExtension(
+ STypeId::CreateSTypeId(TLayerSelectionInfo::EUid, TLayerSelectionInfo::ETypeId)));
+ __ASSERT_ALWAYS(selectInfo, CoreMCprPanic(KPanicUnexpectedExecutionPath));
+
+ TUint selectionPolicyId = selectInfo->CustomSelectionPolicy();
+
+ //Running this transition, we can't be at the bottom of the stack!
+ __ASSERT_DEBUG(selectionPolicyId, User::Panic(KSpecAssert_ESockCoreProvcprac, 10));
+
+ //And, of course, for nodes using this transition, it is only one single
+ //access point below.
+
+ //This constructs a TConnAPPref to represent the access point to be created
+ ac.SelectionConnPrefList() = message_cast<TCFSelector::TSelect>(iContext.iMessage).iConnPrefList;
+
+ if (selectionPolicyId != (TUint)CommsDat::CCDAccessPointRecord::KNoPolicy)
+ {
+ TConnAPPref* nextAP = TConnAPPref::NewL(selectionPolicyId);
+ CleanupStack::PushL(nextAP);
+ ac.SelectionConnPrefList().AppendL(nextAP);
+ CleanupStack::Pop();
+ }
+
+ //The current index is set to the length of the list, this is decremented
+ //in the next step so the correct tier manager is created (the one
+ //relating to this access point
+ }
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TProcessPrioritisedSelectionPolicySuper, NetStateMachine::MStateTransition, CSelectNextLayerActivity::TContext)
+void CSelectNextLayerActivity::TProcessPrioritisedSelectionPolicySuper::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+
+ ac.SelectionConnPrefList() = message_cast<TCFSelector::TSelect>(iContext.iMessage).iConnPrefList;
+
+ //We are going to process our own selection policy to determine choices
+ //for selection of the next layer.
+
+ //This simple transition interprets the selection policy id
+ //directly as a next layer access point id.
+
+ //Now we can interpret the selection policy and store the results for further
+ //processing
+ const TLayerSelectionInfo* selectInfo = static_cast<const TLayerSelectionInfo*>(iContext.Node().AccessPointConfig().FindExtension(
+ STypeId::CreateSTypeId(TLayerSelectionInfo::EUid, TLayerSelectionInfo::ETypeId)));
+ __ASSERT_ALWAYS(selectInfo, CoreMCprPanic(KPanicUnexpectedExecutionPath));
+ TUint selectionPolicyId = selectInfo->SelectionPolicy();
+
+ //Running this transition, we can't be at the bottom of the stack!
+ __ASSERT_DEBUG(selectionPolicyId, User::Panic(KSpecAssert_ESockCoreProvcprac, 11));
+
+ //And, of course, for nodes using this transition, all of the choices come
+ //from the simple prioritised selection policy
+
+ TierManagerUtils::FillListL(ac.SelectionConnPrefList(),selectionPolicyId,ac.Dbs());
+ }
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TFindOrCreateTierManagerSuper, NetStateMachine::MStateTransition, CSelectNextLayerActivity::TContext)
+void CSelectNextLayerActivity::TFindOrCreateTierManagerSuper::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+
+ //This takes the first TConnAPPref from the list and creates the tier manager it
+ //is associated with.
+ ESock::RConnPrefList::TIter<TConnAPPref> iterAP = ac.SelectionConnPrefList().getIter<TConnAPPref>();
+
+ __ASSERT_DEBUG(!iterAP.IsEnd(), User::Panic(KSpecAssert_ESockCoreProvcprac, 12));
+
+ TUid tierId = TierManagerUtils::ReadTierIdL(iterAP->GetAP(), ac.Dbs()) ;
+
+ //The tier id must be set now!
+ __ASSERT_DEBUG(tierId.iUid!=0, User::Panic(KSpecAssert_ESockCoreProvcprac, 13));
+ User::LeaveIfError(tierId.iUid!=0? KErrNone : KErrCorrupt); //Check your configuration!
+ TAlwaysFindFactoryQuery query;
+ iContext.iNodeActivity->PostRequestTo(SockManGlobals::Get()->GetPlaneFC(
+ TCFPlayerRole(TCFPlayerRole::ETierMgrPlane)),
+ TCFFactory::TFindOrCreatePeer(TCFPlayerRole::ETierMgrPlane, tierId, &query).CRef(), EFalse);
+ }
+
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TSelectNextLayerSuper, NetStateMachine::MStateTransition, CSelectNextLayerActivity::TContext)
+void CSelectNextLayerActivity::TSelectNextLayerSuper::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+
+ // We should not have got here if the list is empty
+ __ASSERT_DEBUG(ac.SelectionConnPrefList().Count() != 0, User::Panic(KSpecAssert_ESockCoreProvcprac, 14));
+
+ // The handle to the complete list is passed to the tier manager
+ iContext.iNodeActivity->PostRequestTo(ac.iTierManager, TCFSelector::TSelect(ac.SelectionConnPrefList()).CRef());
+ }
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TNoTagOrSelectedProviderBackwardSuper, NetStateMachine::MStateFork, CSelectNextLayerActivity::TContext)
+EXPORT_C TInt CSelectNextLayerActivity::TNoTagOrSelectedProviderBackwardSuper::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+ ESock::RConnPrefList::TIter<TConnAPPref> iterAP = ac.SelectionConnPrefList().getIter<TConnAPPref>();
+
+ if (!iterAP.IsEnd())
+ {
+ return MCprStates::KSelectedProvider | NetStateMachine::EBackward;
+ }
+
+ return MeshMachine::KNoTag | NetStateMachine::EForward;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TAddProviderInfo, NetStateMachine::MStateTransition, CSelectNextLayerActivity::TContext)
+void CSelectNextLayerActivity::TAddProviderInfo::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+
+ TCFSelector::TSelectComplete& msg = message_cast<TCFSelector::TSelectComplete>(iContext.iMessage);
+ ac.iSelectCompleteMessages.Append(msg);
+ }
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TJoinTierManager, NetStateMachine::MStateTransition, CSelectNextLayerActivity::TContext)
+void CSelectNextLayerActivity::TJoinTierManager::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+
+ ac.iTierManager = message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage).iNodeId;
+ __ASSERT_DEBUG(!ac.iTierManager.IsNull(), User::Panic(KSpecAssert_ESockCoreProvcprac, 15)); //Must always be valid.
+
+ //Ensure that the MCPR remains active by adding the lower TierManager as an
+ //auxiliary client. This is only a temporary association with the TierManager
+ //in the layer below and is only active for the duration of the select.
+ //Note that this might leave resulting in ac.iTierManager non-Null in destructor
+ iContext.Node().AddClientL(ac.iTierManager, TClientType(TCFClientType::EAux));
+ ac.PostRequestTo(ac.iTierManager, TCFPeer::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::ECtrl)).CRef());
+ }
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TJoinServiceProvider, NetStateMachine::MStateTransition, MCprStates::TContext)
+void CSelectNextLayerActivity::TJoinServiceProvider::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+
+ __ASSERT_DEBUG(ac.iSelectCompleteMessages.Count() > 0, User::Panic(KSpecAssert_ESockCoreProvcprac, 16));
+ ESock::TSigSelectComplete& msg = ac.iSelectCompleteMessages[0];
+
+ //This transition assumes that the first service provider supplied will be the chosen one (EActive denotes 'the' service provider).
+ TInt flags = 0;
+ if (iContext.Node().ServiceProvider() == NULL)
+ {
+ flags = TCFClientType::EActive;
+ }
+
+ RNodeInterface* client = iContext.Node().AddClientL(msg.iNodeId, TClientType(TCFClientType::EServProvider, flags), &msg.iProviderInfo);
+
+ iContext.iNodeActivity->PostRequestTo(*client, TCFServiceProvider::TJoinRequest(iContext.NodeId(), TCFClientType::ECtrl).CRef());
+ }
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TSendSelectComplete, NetStateMachine::MStateTransition, MCprStates::TContext)
+void CSelectNextLayerActivity::TSendSelectComplete::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+
+ __ASSERT_DEBUG(ac.iSelectCompleteMessages.Count() > 0, User::Panic(KSpecAssert_ESockCoreProvcprac, 17));
+ ESock::TSigSelectComplete& selectcompletemsg = ac.iSelectCompleteMessages[0];
+ iContext.iNodeActivity->PostToOriginators(TCFSelector::TSelectComplete(iContext.iPeer->RecipientId(), selectcompletemsg.iProviderInfo).CRef());
+ ac.iSelectCompleteMessages.Remove(0);
+ }
+
+EXPORT_DEFINE_SMELEMENT(CSelectNextLayerActivity::TLeaveTierManager, NetStateMachine::MStateTransition, CSelectNextLayerActivity::TContext)
+void CSelectNextLayerActivity::TLeaveTierManager::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CSelectNextLayerActivity& ac = static_cast<CSelectNextLayerActivity&>(*iContext.iNodeActivity);
+ __ASSERT_DEBUG(!ac.iTierManager.IsNull(), User::Panic(KSpecAssert_ESockCoreProvcprac, 18)); //Must always be valid.
+ ac.PostRequestTo(ac.iTierManager, TEChild::TLeft().CRef());
+ iContext.Node().RemoveClient(ac.iTierManager);
+ ac.iTierManager.SetNull();
+
+ }
+//
+//CReConnectActivity
+CReConnectActivity::CReConnectActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+: MeshMachine::CNodeActivityBase(aActivitySig, aNode)
+ {
+ }
+
+MeshMachine::CNodeActivityBase* CReConnectActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ return new(ELeave)CReConnectActivity(aActivitySig, aNode);
+ }
+
+void CReConnectActivity::StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& aOriginator, const TStateTriple& aFirst)
+ {
+ //This activity provides service for only one single requestor at a time.
+ __ASSERT_DEBUG(iOriginators.Count()==0, User::Panic(KSpecAssert_ESockCoreProvcprac, 19)); //Diagnostic panic
+ User::LeaveIfError(iOriginators.Count()? KErrInUse : KErrNone);
+ iOriginators.AppendL(aOriginator);
+ MESH_LOG_CONTEXT_EXT(KESockMeshMachine, aContext, (_L8("CReConnectActivity %08x:\tStartL->starting activity"), this));
+ __ASSERT_DEBUG(IsIdle(), User::Panic(KSpecAssert_ESockCoreProvcprac, 20));
+ NetStateMachine::ACore::Start(&aContext, aFirst);
+ MESH_LOG((KESockMeshMachine, _L8("CReConnectActivity %08x:\tStartL->activity started"), this));
+ }
+
+DEFINE_SMELEMENT(CReConnectActivity::TProcessReConnectRequest, NetStateMachine::MStateTransition, CReConnectActivity::TContext)
+void CReConnectActivity::TProcessReConnectRequest::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CReConnectActivity& activity = static_cast<CReConnectActivity&>(*iContext.iNodeActivity);
+ TCFMcpr::TReConnect& msg = message_cast<TCFMcpr::TReConnect>(iContext.iMessage);
+
+ activity.iStoppingSP = iContext.Node().FindClientL(msg.iNodeId1);
+ __ASSERT_DEBUG(activity.iStoppingSP->Type()&TCFClientType::EServProvider, User::Panic(KSpecAssert_ESockCoreProvcprac, 21));
+
+ activity.iStartingSP = iContext.Node().FindClientL(msg.iNodeId2);
+ __ASSERT_DEBUG(activity.iStartingSP->Type()&TCFClientType::EServProvider, User::Panic(KSpecAssert_ESockCoreProvcprac, 22));
+ }
+
+DEFINE_SMELEMENT(CReConnectActivity::TBuildLowerLayer, NetStateMachine::MStateTransition, CReConnectActivity::TContext)
+void CReConnectActivity::TBuildLowerLayer::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CReConnectActivity& activity = static_cast<CReConnectActivity&>(*iContext.iNodeActivity);
+
+ //Post a TBuildLowerLayer to self, initiating building of the new layer below
+ //Use the new service provider to prime the new layer
+ __ASSERT_DEBUG(activity.iStartingSP, User::Panic(KSpecAssert_ESockCoreProvcprac, 25));
+ iContext.iNodeActivity->PostRequestTo(iContext.NodeId(), TCFDataClient::TBindTo(activity.iStartingSP->RecipientId()).CRef());
+ }
+
+
+DEFINE_SMELEMENT(CReConnectActivity::TSendReConnectResponse, NetStateMachine::MStateTransition, CReConnectActivity::TContext)
+void CReConnectActivity::TSendReConnectResponse::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ iContext.iNodeActivity->PostToOriginators(TCFMcpr::TReConnectComplete().CRef());
+ }
+
+
+//
+//CAvailabilityActivity
+MeshMachine::CNodeActivityBase* CAvailabilityActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ return new (ELeave) CAvailabilityActivity(aActivitySig, aNode);
+ }
+
+CAvailabilityActivity::~CAvailabilityActivity()
+ {
+ static_cast<CCoreMetaConnectionProvider&>(iNode).CancelAvailabilityMonitoring();
+
+ //Unmark all remaining availability providers
+ TClientIter<TFlagsOnlyClientMatchPolicy> iter = iNode.GetClientIter<TFlagsOnlyClientMatchPolicy>(TClientType(0, TCFClientType::EAvailabilityProvider));
+ RNodeInterface* provider = iter++;
+ while (provider)
+ {
+ provider->ClearFlags(TCFClientType::EAvailabilityProvider);
+ provider = static_cast<RNodeAvailabilityProviderInterface*>(iter++);
+ }
+ }
+
+void CAvailabilityActivity::StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& aOriginator, const TStateTriple& aFirst)
+ {
+ TCFAvailabilityProvider::TAvailabilityNotificationRegistration& msg =
+ message_cast<TCFAvailabilityProvider::TAvailabilityNotificationRegistration>(aContext.iMessage);
+
+ CSubscriberInfo* info = new (ELeave) CSubscriberInfo;
+ const_cast<Messages::XNodePeerId&>(aOriginator).iInfo = info;
+ info->SetSubscriptionOptions(msg.iAvailabilitySubscriptionOptions);
+ CleanupStack::PushL(info);
+ MeshMachine::CNodeActivityBase::StartL(aContext, aOriginator, aFirst);
+ CleanupStack::Pop(info);
+
+ if (IsAvailabilityKnown())
+ {
+ info->SetReportedStatus(iCurrentAvailabilityStatus);
+ aContext.PostToSender(TCFAvailabilityControlClient::TAvailabilityNotification(iCurrentAvailabilityStatus).CRef());
+ }
+ }
+
+void CAvailabilityActivity::Cancel(TNodeContextBase& aContext)
+ {
+ //Post TCancel to all availability providers
+ iNode.PostToClients<TFlagsOnlyClientMatchPolicy>(TNodeCtxId(ActivityId(), iNode.Id()), TEBase::TCancel().CRef(),
+ TClientType(0, TCFClientType::EAvailabilityProvider));
+ MeshMachine::CNodeActivityBase::Cancel(aContext);
+ }
+
+void CAvailabilityActivity::CalculateCurrentAvailabilityStatus()
+ {
+ iCurrentAvailabilityStatus.SetUnknown();
+ TClientIter<TFlagsOnlyClientMatchPolicy> iter = iNode.GetClientIter<TFlagsOnlyClientMatchPolicy>(TClientType(0, TCFClientType::EAvailabilityProvider));
+ RNodeAvailabilityProviderInterface* provider = static_cast<RNodeAvailabilityProviderInterface*>(iter++);
+ __ASSERT_DEBUG(provider, User::Panic(KSpecAssert_ESockCoreProvcprac, 26)); //There must be at least availability provider registered at this stage (or there are no originators == this activity should not run)
+ while (provider)
+ {
+ __ASSERT_DEBUG(provider->Type()&(TCFClientType::EServProvider|TClientType::ERegistrar), User::Panic(KSpecAssert_ESockCoreProvcprac, 27));
+ const TAvailabilityStatus& availabilityStatus = provider->AvailabilityStatus();
+ if (!availabilityStatus.IsKnown())
+ {
+ //If the immediate response from any of the remaining providers is still in transport,
+ //set the whole as unknown.
+ iCurrentAvailabilityStatus.SetUnknown();
+ return;
+ }
+ else if (availabilityStatus.Score() > iCurrentAvailabilityStatus.Score())
+ {
+ iCurrentAvailabilityStatus.SetScore(availabilityStatus.Score());
+ }
+ provider = static_cast<RNodeAvailabilityProviderInterface*>(iter++);
+ }
+ }
+
+TBool CAvailabilityActivity::IsAvailabilityKnown() const
+ {
+ return iCurrentAvailabilityStatus.IsKnown();
+ }
+
+void CAvailabilityActivity::NotifyInterestedSubscribers()
+ {
+ __ASSERT_DEBUG(IsAvailabilityKnown(), User::Panic(KSpecAssert_ESockCoreProvcprac, 28)); //Use only with known availability!
+ TCFAvailabilityControlClient::TAvailabilityNotification msg(iCurrentAvailabilityStatus); //KActivityNull will be overriden
+
+ for (TInt i = iOriginators.Count() - 1; i >= 0; --i)
+ {
+ XNodePeerId& originator = iOriginators[i];
+ CSubscriberInfo* info = static_cast<CSubscriberInfo*>(originator.iInfo);
+ __ASSERT_DEBUG(info, User::Panic(KSpecAssert_ESockCoreProvcprac, 29));
+
+ if (!info->ReportedStatus().IsKnown()
+ || info->SubscriptionOptions().IsChangeSignificant(info->ReportedStatus(), iCurrentAvailabilityStatus))
+ {
+ info->SetReportedStatus(iCurrentAvailabilityStatus);
+ originator.PostMessage(TNodeCtxId(ActivityId(), iNode.Id()), msg);
+ }
+ }
+ }
+
+void CAvailabilityActivity::RegisterForNotifications(TClientIterBase& aClientIter) const
+ {
+ RNodeAvailabilityProviderInterface* provider = static_cast<RNodeAvailabilityProviderInterface*>(aClientIter++);
+
+ //We can ignore the fact that tere is no service providers we can register with, provided
+ //the node has ensured there are some other availability providers!
+ //If there are no service nor other availability providers the condition is serious.
+ //__ASSERT_ALWAYS is required as the verified conditions are of a run time nature
+ __ASSERT_ALWAYS(provider!=NULL || iNode.CountClients<TFlagsOnlyClientMatchPolicy>(TClientType(0, TCFClientType::EAvailabilityProvider))>0,
+ CoreMCprPanic(KPanicNoAvailabilityProvider));
+
+ TAvailabilitySubscriptionOptions subscriptionOptions; //By default register for all notifications - may need to be modified in the future
+ TCFAvailabilityProvider::TAvailabilityNotificationRegistration msg(subscriptionOptions);
+
+ //Iterate through service providers if any, setting EAvailabilityProvider flags
+ while (provider)
+ {
+ provider->SetFlags(TCFClientType::EAvailabilityProvider);
+ provider->PostMessage(TNodeCtxId(ActivityId(), iNode.Id()), msg);
+ provider = static_cast<RNodeAvailabilityProviderInterface*>(aClientIter++);
+ }
+ }
+
+DEFINE_SMELEMENT(CAvailabilityActivity::TRegisterForNotifications, NetStateMachine::MStateTransition, CAvailabilityActivity::TContext)
+void CAvailabilityActivity::TRegisterForNotifications::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CAvailabilityActivity& activity = static_cast<CAvailabilityActivity&>(*iContext.iNodeActivity);
+
+ //Start monitoring on the node if necessary
+ iContext.Node().StartAvailabilityMonitoringL(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()));
+
+ TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider));
+ activity.RegisterForNotifications(iter);
+ }
+
+DEFINE_SMELEMENT(CAvailabilityActivity::TProcessNotification, NetStateMachine::MStateTransition, CAvailabilityActivity::TContext)
+void CAvailabilityActivity::TProcessNotification::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, CoreMCprPanic(KPanicNoActivity));
+ CAvailabilityActivity& activity = static_cast<CAvailabilityActivity&>(*iContext.iNodeActivity);
+
+ //Register with any new service providers (if any) == not with EAvailabilityProvider(s)
+ TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider), TClientType(0, TCFClientType::EAvailabilityProvider));
+ activity.RegisterForNotifications(iter);
+
+ //Now the iPeer must be set (and we need to have the RNodeAvailabilityProviderInterface behind it)
+ __ASSERT_DEBUG(iContext.iPeer, User::Panic(KSpecAssert_ESockCoreProvcprac, 30));
+ TCFAvailabilityControlClient::TAvailabilityNotification& msg = message_cast<TCFAvailabilityControlClient::TAvailabilityNotification>(iContext.iMessage);
+
+ //RNodeAvailabilityProviderInterface stores information (on this node) about the availability provider
+ RNodeAvailabilityProviderInterface* provider = static_cast<RNodeAvailabilityProviderInterface*>(iContext.iPeer);
+ __ASSERT_DEBUG(provider->Flags()&TCFClientType::EAvailabilityProvider, User::Panic(KSpecAssert_ESockCoreProvcprac, 31));
+ provider->SetAvailabilityStatus(msg.iAvailabilityStatus);
+
+ //Compute the overal availability and report if known already
+ activity.CalculateCurrentAvailabilityStatus();
+ if (activity.IsAvailabilityKnown())
+ {
+ activity.NotifyInterestedSubscribers();
+ }
+ }
+
--- a/datacommsserver/esockserver/CoreProviders/src/coretiernotificationstates.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/CoreProviders/src/coretiernotificationstates.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -110,7 +110,7 @@
EXPORT_DEFINE_SMELEMENT(TAwaitingCancelOrErrorOrDestroy, NetStateMachine::MState, TierNotification::TContext)
EXPORT_C TBool TAwaitingCancelOrErrorOrDestroy::Accept()
{
- return( iContext.iMessage.IsMessage<TEBase::TCancel>() ||
+ return( ( iContext.iMessage.IsMessage<TEBase::TCancel>() && iContext.Activity()->FindOriginator(iContext.iSender) != KErrNotFound ) ||
iContext.iMessage.IsMessage<TEBase::TError>() ||
iContext.iMessage.IsMessage<TEChild::TDestroy>() );
}
--- a/datacommsserver/esockserver/MobilityCoreProviders/inc/mobilitymcpractivities.h Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/MobilityCoreProviders/inc/mobilitymcpractivities.h Thu Jan 07 13:34:53 2010 +0200
@@ -1,9 +1,9 @@
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
-// under the terms of the License "Symbian Foundation License v1.0"
+// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
-// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
@@ -12,7 +12,7 @@
//
// Description:
// Mobility Meta Connection Provider Activities
-//
+//
//
/**
@@ -38,7 +38,7 @@
DECLARE_EXPORT_ACTIVITY_MAP(mobilityMCprActivities)
-///////////////////////////////////////////////////////////////////////////////
+//
//CMobilityActivity
class CMobilityActivity : public MeshMachine::CNodeRetryActivity
{
@@ -49,7 +49,7 @@
CMobilityActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode);
virtual ~CMobilityActivity();
typedef MeshMachine::TNodeContext<CMobilityMetaConnectionProvider, MCprStates::TContext> TContext;
-
+
private:
TBool EvaluatePreference(TContext& aContext);
void SetHandshakingFlag();
@@ -57,33 +57,28 @@
private:
ESock::RMetaServiceProviderInterface* iCurrent;
- ESock::RMetaServiceProviderInterface* iAvailable;
- ESock::RMetaServiceProviderInterface* iCandidate;
+ ESock::RMetaServiceProviderInterface* iPreferred;
const TUint iAvailabilityScoreTreshold;
public:
-
+
DECLARE_SMELEMENT_HEADER(TAwaitingCurrentCarrierRejectedOrAvailabilityChange, MeshMachine::TState<TContext>, NetStateMachine::MState, TContext)
virtual TBool Accept();
DECLARE_SMELEMENT_FOOTER(TAwaitingCurrentCarrierRejectedOrAvailabilityChange)
-
+
DECLARE_SMELEMENT_HEADER(TNoTagOrAwaitMobility, MeshMachine::TStateFork<TContext>, NetStateMachine::MStateFork, CMobilityActivity::TContext)
virtual TInt TransitionTag();
- DECLARE_SMELEMENT_FOOTER(TNoTagOrAwaitMobility)
-
- DECLARE_SMELEMENT_HEADER(TNoTagOrReConnectOrStartMobilityHandshakeBackwards, MeshMachine::TStateFork<TContext>, NetStateMachine::MStateFork, CMobilityActivity::TContext)
- virtual TInt TransitionTag();
- DECLARE_SMELEMENT_FOOTER(TNoTagOrReConnectOrStartMobilityHandshakeBackwards)
+ DECLARE_SMELEMENT_FOOTER(TNoTagOrAwaitMobility)
DECLARE_SMELEMENT_HEADER(TNoTagOrStartMobilityHandshakeBackwards, MeshMachine::TStateFork<TContext>, NetStateMachine::MStateFork, CMobilityActivity::TContext)
virtual TInt TransitionTag();
DECLARE_SMELEMENT_FOOTER(TNoTagOrStartMobilityHandshakeBackwards)
-
+
DECLARE_SMELEMENT_HEADER(TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger, MeshMachine::TStateFork<TContext>, NetStateMachine::MStateFork, CMobilityActivity::TContext)
virtual TInt TransitionTag();
DECLARE_SMELEMENT_FOOTER(TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger)
-
+
DECLARE_SMELEMENT_HEADER(TClearHandshakingFlag, MeshMachine::TStateTransition<TContext>, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
virtual void DoL();
DECLARE_SMELEMENT_FOOTER(TClearHandshakingFlag)
@@ -121,7 +116,7 @@
)
};
-///////////////////////////////////////////////////////////////////////////////
+//
//CConnectionRecoveryActivity
class CConnectionRecoveryActivity : public MeshMachine::CNodeRetryActivity
{
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/MobilityCoreProviders/inc/mobilitymcpractivities.h.orig Thu Jan 07 13:34:53 2010 +0200
@@ -0,0 +1,180 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Mobility Meta Connection Provider Activities
+//
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+
+#ifndef MOBILITYMCPRACTIVITIES_H
+#define MOBILITYMCPRACTIVITIES_H
+
+#include <comms-infras/coremcpractivities.h>
+#include <comms-infras/mobilitymcprstates.h>
+#include <elements/nm_messages_errorrecovery.h>
+
+enum TMobilityMCprActivities
+ {
+ ECFActivityMCprMobility = ESock::ECFActivityCustom + 1,
+ };
+
+namespace MobilityMCprActivities
+{
+DECLARE_EXPORT_ACTIVITY_MAP(mobilityMCprActivities)
+
+
+//
+//CMobilityActivity
+class CMobilityActivity : public MeshMachine::CNodeRetryActivity
+ {
+public:
+ static MeshMachine::CNodeActivityBase* NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode);
+
+protected:
+ CMobilityActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode);
+ virtual ~CMobilityActivity();
+ typedef MeshMachine::TNodeContext<CMobilityMetaConnectionProvider, MCprStates::TContext> TContext;
+
+private:
+ TBool EvaluatePreference(TContext& aContext);
+ void SetHandshakingFlag();
+ void ClearHandshakingFlag();
+
+private:
+ ESock::RMetaServiceProviderInterface* iCurrent;
+ ESock::RMetaServiceProviderInterface* iPreferred;
+ const TUint iAvailabilityScoreTreshold;
+
+
+public:
+
+ DECLARE_SMELEMENT_HEADER(TAwaitingCurrentCarrierRejectedOrAvailabilityChange, MeshMachine::TState<TContext>, NetStateMachine::MState, TContext)
+ virtual TBool Accept();
+ DECLARE_SMELEMENT_FOOTER(TAwaitingCurrentCarrierRejectedOrAvailabilityChange)
+
+ DECLARE_SMELEMENT_HEADER(TNoTagOrAwaitMobility, MeshMachine::TStateFork<TContext>, NetStateMachine::MStateFork, CMobilityActivity::TContext)
+ virtual TInt TransitionTag();
+ DECLARE_SMELEMENT_FOOTER(TNoTagOrAwaitMobility)
+
+ DECLARE_SMELEMENT_HEADER(TNoTagOrStartMobilityHandshakeBackwards, MeshMachine::TStateFork<TContext>, NetStateMachine::MStateFork, CMobilityActivity::TContext)
+ virtual TInt TransitionTag();
+ DECLARE_SMELEMENT_FOOTER(TNoTagOrStartMobilityHandshakeBackwards)
+
+ DECLARE_SMELEMENT_HEADER(TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger, MeshMachine::TStateFork<TContext>, NetStateMachine::MStateFork, CMobilityActivity::TContext)
+ virtual TInt TransitionTag();
+ DECLARE_SMELEMENT_FOOTER(TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger)
+
+ DECLARE_SMELEMENT_HEADER(TClearHandshakingFlag, MeshMachine::TStateTransition<TContext>, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TClearHandshakingFlag)
+
+ DECLARE_SMELEMENT_HEADER(TSendAvailabilityRequest, MeshMachine::TStateTransition<TContext>, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TSendAvailabilityRequest)
+
+ DECLARE_SMELEMENT_HEADER(TInformMigrationAvailableAndSetHandshakingFlag, MeshMachine::TStateTransition<TContext>, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TInformMigrationAvailableAndSetHandshakingFlag)
+
+ // For the moment it is sufficient to use the re-connect activity, in the future we may want to
+ // customise the behavior, for example start the new layer before rebinding it, etc.
+ DECLARE_SMELEMENT_HEADER(TRequestReConnect, MeshMachine::TStateTransition<TContext>, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TRequestReConnect)
+
+ DECLARE_SMELEMENT_HEADER(TInformMigrationCompleted, MeshMachine::TStateTransition<TContext>, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TInformMigrationCompleted)
+
+ typedef MeshMachine::TActivitiesIdMutex<ESock::ECFActivityConnectionStartRecovery,
+ ESock::ECFActivityConnectionGoneDownRecovery> TActivityErrorRecoveryMutex;
+ DECLARE_SERIALIZABLE_STATE(
+ TNoTagOrAwaitMobilityBackwardsOnMobilityTriggerBlockedByErrorRecovery,
+ TActivityErrorRecoveryMutex,
+ TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger
+ )
+
+ DECLARE_SERIALIZABLE_STATE(
+ TNoTagOrAwaitMobilityBlockedByErrorRecovery,
+ TActivityErrorRecoveryMutex,
+ TNoTagOrAwaitMobility
+ )
+ };
+
+//
+//CConnectionRecoveryActivity
+class CConnectionRecoveryActivity : public MeshMachine::CNodeRetryActivity
+ {
+public:
+ static MeshMachine::CNodeActivityBase* NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode);
+ void ReplyToOriginators(Messages::TEErrorRecovery::TErrorRecoveryResponse& aCFMessageSig);
+
+protected:
+ CConnectionRecoveryActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode);
+
+public:
+ Messages::TErrContext iOriginalErrContext; //Error context on which this activity started
+
+protected:
+ typedef MeshMachine::TNodeContext<CMobilityMetaConnectionProvider, MCprStates::TContext> TContext;
+
+public:
+ DECLARE_SMELEMENT_HEADER(TAwaitingReConnectComplete, MeshMachine::TState<TContext>, NetStateMachine::MState, TContext)
+ virtual TBool Accept();
+ DECLARE_SMELEMENT_FOOTER(TAwaitingReConnectComplete)
+
+ class TTransitionBase : public MeshMachine::TStateTransition<TContext>
+ {
+ public:
+ TTransitionBase(TContext& aContext)
+ : MeshMachine::TStateTransition<TContext>(aContext)
+ {
+ }
+
+ virtual void Error(TInt aError);
+ };
+
+ DECLARE_SMELEMENT_HEADER(TStoreErrorContext, CConnectionRecoveryActivity::TTransitionBase, NetStateMachine::MStateTransition, TContext)
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TStoreErrorContext)
+
+ DECLARE_SMELEMENT_HEADER(TProcessConnectionStartRecoveryRequest, CConnectionRecoveryActivity::TTransitionBase, NetStateMachine::MStateTransition, TContext)
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TProcessConnectionStartRecoveryRequest)
+
+ DECLARE_SMELEMENT_HEADER(TProcessConnectionGoneDownRecoveryRequest, CConnectionRecoveryActivity::TTransitionBase, NetStateMachine::MStateTransition, TContext)
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TProcessConnectionGoneDownRecoveryRequest)
+
+ DECLARE_SMELEMENT_HEADER(TSendRetryRecoveryResponse, CConnectionRecoveryActivity::TTransitionBase, NetStateMachine::MStateTransition, TContext)
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TSendRetryRecoveryResponse)
+
+ DECLARE_SMELEMENT_HEADER(TSendPropagateRecoveryResponse, CConnectionRecoveryActivity::TTransitionBase, NetStateMachine::MStateTransition, TContext)
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TSendPropagateRecoveryResponse)
+
+ DECLARE_SMELEMENT_HEADER(TSendIgnoreRecoveryResponse, CConnectionRecoveryActivity::TTransitionBase, NetStateMachine::MStateTransition, TContext)
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TSendIgnoreRecoveryResponse)
+ };
+
+} // namespace MobilityMCprActivities
+
+#endif // MOBILITYMCPRACTIVITIES_H
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/MobilityCoreProviders/inc/mobilitymcpractivities.h.rej Thu Jan 07 13:34:53 2010 +0200
@@ -0,0 +1,176 @@
+***************
+*** 9,21 ****
+ // Nokia Corporation - initial contribution.
+ //
+ // Contributors:
+ //
+ // Description:
+ // Mobility Meta Connection Provider Activities
+- //
+ //
+
+ /**
+ @file
+ @internalComponent
+ */
+--- 9,21 ----
+ // Nokia Corporation - initial contribution.
+ //
+ // Contributors:
+ //
+ // Description:
+ // Mobility Meta Connection Provider Activities
++ //
+ //
+
+ /**
+ @file
+ @internalComponent
+ */
+***************
+*** 46,92 ****
+ static MeshMachine::CNodeActivityBase* NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode);
+
+ protected:
+ CMobilityActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode);
+ virtual ~CMobilityActivity();
+ typedef MeshMachine::TNodeContext<CMobilityMetaConnectionProvider, MCprStates::TContext> TContext;
+-
+ private:
+ TBool EvaluatePreference(TContext& aContext);
+ void SetHandshakingFlag();
+ void ClearHandshakingFlag();
+
+ private:
+ ESock::RMetaServiceProviderInterface* iCurrent;
+- ESock::RMetaServiceProviderInterface* iAvailable;
+- ESock::RMetaServiceProviderInterface* iCandidate;
+ const TUint iAvailabilityScoreTreshold;
+
+
+ public:
+-
+ DECLARE_SMELEMENT_HEADER(TAwaitingCurrentCarrierRejectedOrAvailabilityChange, MeshMachine::TState<TContext>, NetStateMachine::MState, TContext)
+ virtual TBool Accept();
+ DECLARE_SMELEMENT_FOOTER(TAwaitingCurrentCarrierRejectedOrAvailabilityChange)
+-
+ DECLARE_SMELEMENT_HEADER(TNoTagOrAwaitMobility, MeshMachine::TStateFork<TContext>, NetStateMachine::MStateFork, CMobilityActivity::TContext)
+ virtual TInt TransitionTag();
+- DECLARE_SMELEMENT_FOOTER(TNoTagOrAwaitMobility)
+
+- DECLARE_SMELEMENT_HEADER(TNoTagOrReConnectOrStartMobilityHandshakeBackwards, MeshMachine::TStateFork<TContext>, NetStateMachine::MStateFork, CMobilityActivity::TContext)
+- virtual TInt TransitionTag();
+- DECLARE_SMELEMENT_FOOTER(TNoTagOrReConnectOrStartMobilityHandshakeBackwards)
+-
+ DECLARE_SMELEMENT_HEADER(TNoTagOrStartMobilityHandshakeBackwards, MeshMachine::TStateFork<TContext>, NetStateMachine::MStateFork, CMobilityActivity::TContext)
+ virtual TInt TransitionTag();
+ DECLARE_SMELEMENT_FOOTER(TNoTagOrStartMobilityHandshakeBackwards)
+-
+ DECLARE_SMELEMENT_HEADER(TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger, MeshMachine::TStateFork<TContext>, NetStateMachine::MStateFork, CMobilityActivity::TContext)
+ virtual TInt TransitionTag();
+ DECLARE_SMELEMENT_FOOTER(TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger)
+-
+ DECLARE_SMELEMENT_HEADER(TClearHandshakingFlag, MeshMachine::TStateTransition<TContext>, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TClearHandshakingFlag)
+
+ DECLARE_SMELEMENT_HEADER(TSendAvailabilityRequest, MeshMachine::TStateTransition<TContext>, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+ virtual void DoL();
+--- 46,87 ----
+ static MeshMachine::CNodeActivityBase* NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode);
+
+ protected:
+ CMobilityActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode);
+ virtual ~CMobilityActivity();
+ typedef MeshMachine::TNodeContext<CMobilityMetaConnectionProvider, MCprStates::TContext> TContext;
++
+ private:
+ TBool EvaluatePreference(TContext& aContext);
+ void SetHandshakingFlag();
+ void ClearHandshakingFlag();
+
+ private:
+ ESock::RMetaServiceProviderInterface* iCurrent;
++ ESock::RMetaServiceProviderInterface* iPreferred;
+ const TUint iAvailabilityScoreTreshold;
+
+
+ public:
++
+ DECLARE_SMELEMENT_HEADER(TAwaitingCurrentCarrierRejectedOrAvailabilityChange, MeshMachine::TState<TContext>, NetStateMachine::MState, TContext)
+ virtual TBool Accept();
+ DECLARE_SMELEMENT_FOOTER(TAwaitingCurrentCarrierRejectedOrAvailabilityChange)
++
+ DECLARE_SMELEMENT_HEADER(TNoTagOrAwaitMobility, MeshMachine::TStateFork<TContext>, NetStateMachine::MStateFork, CMobilityActivity::TContext)
+ virtual TInt TransitionTag();
++ DECLARE_SMELEMENT_FOOTER(TNoTagOrAwaitMobility)
+
+ DECLARE_SMELEMENT_HEADER(TNoTagOrStartMobilityHandshakeBackwards, MeshMachine::TStateFork<TContext>, NetStateMachine::MStateFork, CMobilityActivity::TContext)
+ virtual TInt TransitionTag();
+ DECLARE_SMELEMENT_FOOTER(TNoTagOrStartMobilityHandshakeBackwards)
++
+ DECLARE_SMELEMENT_HEADER(TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger, MeshMachine::TStateFork<TContext>, NetStateMachine::MStateFork, CMobilityActivity::TContext)
+ virtual TInt TransitionTag();
+ DECLARE_SMELEMENT_FOOTER(TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger)
++
+ DECLARE_SMELEMENT_HEADER(TClearHandshakingFlag, MeshMachine::TStateTransition<TContext>, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TClearHandshakingFlag)
+
+ DECLARE_SMELEMENT_HEADER(TSendAvailabilityRequest, MeshMachine::TStateTransition<TContext>, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+ virtual void DoL();
+***************
+*** 102,127 ****
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TRequestReConnect)
+
+ DECLARE_SMELEMENT_HEADER(TInformMigrationCompleted, MeshMachine::TStateTransition<TContext>, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TInformMigrationCompleted)
+-
+- typedef MeshMachine::TActivitiesIdMutex<ESock::ECFActivityConnectionStartRecovery,
+ ESock::ECFActivityConnectionGoneDownRecovery> TActivityErrorRecoveryMutex;
+ DECLARE_SERIALIZABLE_STATE(
+ TNoTagOrAwaitMobilityBackwardsOnMobilityTriggerBlockedByErrorRecovery,
+ TActivityErrorRecoveryMutex,
+ TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger
+- )
+-
+ DECLARE_SERIALIZABLE_STATE(
+ TNoTagOrAwaitMobilityBlockedByErrorRecovery,
+ TActivityErrorRecoveryMutex,
+ TNoTagOrAwaitMobility
+- )
+ };
+
+ ///////////////////////////////////////////////////////////////////////////////
+ //CConnectionRecoveryActivity
+ class CConnectionRecoveryActivity : public MeshMachine::CNodeRetryActivity
+ {
+--- 97,122 ----
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TRequestReConnect)
+
+ DECLARE_SMELEMENT_HEADER(TInformMigrationCompleted, MeshMachine::TStateTransition<TContext>, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+ virtual void DoL();
+ DECLARE_SMELEMENT_FOOTER(TInformMigrationCompleted)
++
++ typedef MeshMachine::TActivitiesIdMutex<ESock::ECFActivityConnectionStartRecovery,
+ ESock::ECFActivityConnectionGoneDownRecovery> TActivityErrorRecoveryMutex;
+ DECLARE_SERIALIZABLE_STATE(
+ TNoTagOrAwaitMobilityBackwardsOnMobilityTriggerBlockedByErrorRecovery,
+ TActivityErrorRecoveryMutex,
+ TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger
++ )
++
+ DECLARE_SERIALIZABLE_STATE(
+ TNoTagOrAwaitMobilityBlockedByErrorRecovery,
+ TActivityErrorRecoveryMutex,
+ TNoTagOrAwaitMobility
++ )
+ };
+
+ ///////////////////////////////////////////////////////////////////////////////
+ //CConnectionRecoveryActivity
+ class CConnectionRecoveryActivity : public MeshMachine::CNodeRetryActivity
+ {
--- a/datacommsserver/esockserver/MobilityCoreProviders/inc/mobilitymcprstates.h Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/MobilityCoreProviders/inc/mobilitymcprstates.h Thu Jan 07 13:34:53 2010 +0200
@@ -1,9 +1,9 @@
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
-// under the terms of the License "Symbian Foundation License v1.0"
+// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
-// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
@@ -12,7 +12,7 @@
//
// Description:
// Mobility Meta Connection Provider States
-//
+//
//
/**
@@ -39,9 +39,9 @@
//
//-=========================================================
-const TInt KStartMobilityHandshake = 10000;
+const TInt KStartMobilityHandshake = 10000;
const TInt KAwaitMobility = 10001;
-const TInt KReConnect = 10002;
+
//-=========================================================
//
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/MobilityCoreProviders/inc/mobilitymcprstates.h.orig Thu Jan 07 13:34:53 2010 +0200
@@ -0,0 +1,117 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Mobility Meta Connection Provider States
+//
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+
+#ifndef MOBILITYMCPRSTATES_H
+#define MOBILITYMCPRSTATES_H
+
+#include <elements/mm_states.h>
+#include <comms-infras/mobilitymcpr.h>
+#include <comms-infras/coremcprstates.h>
+
+namespace MobilityMCprStates
+{
+
+typedef MeshMachine::TNodeContext<CMobilityMetaConnectionProvider, MCprStates::TContext> TContext;
+
+//-=========================================================
+//
+//Core Mobile Meta Connection Provider Transition Ids 10000..11000
+//
+//-=========================================================
+
+const TInt KStartMobilityHandshake = 10000;
+const TInt KAwaitMobility = 10001;
+const TInt KReConnect = 10002;
+
+//-=========================================================
+//
+//Mutexes
+//
+//-=========================================================
+
+//This mutex blocks when the mobility is handshaking on the node
+class THandshakingMobilityMutex
+ {
+public:
+ static TBool IsBlocked(MeshMachine::TNodeContextBase& aContext);
+ };
+
+//-=========================================================
+//
+//States
+//
+//-=========================================================
+
+DECLARE_SMELEMENT_HEADER(TAwaitingStartMobility, MeshMachine::TState<TContext>, NetStateMachine::MState, TContext)
+ virtual TBool Accept();
+DECLARE_SMELEMENT_FOOTER(TAwaitingStartMobility)
+
+/**
+ Mobility base state implementing generic cancellation behaviour.
+*/
+class TStateBase : public MeshMachine::TState<TContext>
+ {
+public:
+ explicit TStateBase(TContext& aContext) : MeshMachine::TState<TContext>(aContext)
+ {
+ }
+ virtual void Cancel();
+ };
+
+DECLARE_SMELEMENT_HEADER(TAwaitingMigrationRequestedOrRejected, MobilityMCprStates::TStateBase, NetStateMachine::MState, TContext)
+ virtual TBool Accept();
+DECLARE_SMELEMENT_FOOTER(TAwaitingMigrationRequestedOrRejected)
+
+DECLARE_SMELEMENT_HEADER(TAwaitingMigrationAcceptedOrRejected, MobilityMCprStates::TStateBase, NetStateMachine::MState, TContext)
+ virtual TBool Accept();
+DECLARE_SMELEMENT_FOOTER(TAwaitingMigrationAcceptedOrRejected)
+
+//-=========================================================
+//
+//State Forks
+//
+//-=========================================================
+DECLARE_SMELEMENT_HEADER(TNoTagOrErrorTagIfMobilityRunning, MeshMachine::TStateFork<TContext>, NetStateMachine::MStateFork, TContext)
+ virtual TInt TransitionTag();
+DECLARE_SMELEMENT_FOOTER(TNoTagOrErrorTagIfMobilityRunning)
+
+DECLARE_SERIALIZABLE_STATE(
+ TNoTagBlockedByMobilityHandshaking,
+ THandshakingMobilityMutex,
+ MeshMachine::TNoTag
+ )
+
+//-=========================================================
+//
+//Transitions
+//
+//-=========================================================
+
+DECLARE_SMELEMENT_HEADER(TReplyMobilityStarted, MeshMachine::TStateTransition<TContext>, NetStateMachine::MStateTransition, TContext)
+ virtual void DoL();
+DECLARE_SMELEMENT_FOOTER(TReplyMobilityStarted)
+
+} //namespace MobilityMCprStates
+
+#endif // MOBILITYMCPRSTATES_H
+
--- a/datacommsserver/esockserver/MobilityCoreProviders/src/mobilitymcpractivities.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/MobilityCoreProviders/src/mobilitymcpractivities.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -1,9 +1,9 @@
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
-// under the terms of the License "Symbian Foundation License v1.0"
+// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
-// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
@@ -16,10 +16,10 @@
#include <elements/nm_messages_errorrecovery.h>
#include <comms-infras/ss_coreprstates.h>
#include "mobilitymcpractivities.h"
-#include "mobilitymcprstates.h"
-#include "ss_nodemessages_selector.h"
-#include "ss_nodemessages_mobility.h"
-#include "ss_nodemessages_availability.h"
+#include <comms-infras/mobilitymcprstates.h>
+#include <comms-infras/ss_nodemessages_selector.h>
+#include <comms-infras/ss_nodemessages_mobility.h>
+#include <comms-infras/ss_nodemessages_availability.h>
#include <comms-infras/ss_logext.h>
@@ -43,7 +43,7 @@
using namespace Messages;
using namespace MeshMachine;
-///////////////////////////////////////////////////////////////////////////////
+//
//Panics
#ifdef _DEBUG
_LIT (KCoreMobileMCprPanic,"CoreMobileMCprPanic");
@@ -87,7 +87,7 @@
//if it sees that the availability notification has influcenced what the currently preffered bearer should be.
THROUGH_NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TSendAvailabilityRequest, MeshMachine::TTag<MobilityMCprStates::KStartMobilityHandshake>)
- //<BEGIN> MAIN LOOP ****************
+ //<BEGIN> MAIN LOOP ****************
//The main mobility handshake loop. The loop is executed when performing migration from one service provider to another.
//The entry condition for the loop is that:
//- upgrade: a better then current access point is now available (a better access point reported available)
@@ -97,21 +97,21 @@
// NOTE: if the current bearer ceases to be available completely (goes down), then this will be assisted by an error recovery request;
// NOTE: This tuple doesn't actually do (b), i.e.: assumes the threshold of '1' (in 0..100 availability score range)
//Before awaitng for availability change or rejection by the client (TAwaitingCurrentCarrierRejectedOrAvailabilityChange), the activity
- //first checks (TNoTagOrAwaitMobilityBlockedByErrorRecovery) if the availability has changed since it last checked
- //(availability could have been reported amidst the previous handshake loop)
+ //first checks (TNoTagOrAwaitMobilityBlockedByErrorRecovery) if the availability has changed since it last checked
+ //(availability could have been reported amidst the previous handshake loop)
THROUGH_NODEACTIVITY_ENTRY(MobilityMCprStates::KStartMobilityHandshake, CMobilityActivity::TClearHandshakingFlag, CMobilityActivity::TNoTagOrAwaitMobilityBlockedByErrorRecovery)
NODEACTIVITY_ENTRY(MobilityMCprStates::KAwaitMobility, MeshMachine::TDoNothing, CMobilityActivity::TAwaitingCurrentCarrierRejectedOrAvailabilityChange, CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTriggerBlockedByErrorRecovery)
- //Mobility has been triggered ((a) or (b)). Start mobility handshake (set handshaking flag and inform the client about the preferred bearer)
- NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TInformMigrationAvailableAndSetHandshakingFlag, MobilityMCprStates::TAwaitingMigrationRequestedOrRejected, CMobilityActivity::TNoTagOrReConnectOrStartMobilityHandshakeBackwards)
- //The client accepts the new access point.
+ //Mobility has been triggered ((a) or (b)). Start mobility handshake (set handshaking flag and inform the client about the preferred bearer)
+ NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TInformMigrationAvailableAndSetHandshakingFlag, MobilityMCprStates::TAwaitingMigrationRequestedOrRejected, CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards)
+ //The client accepts the new access point.
//For the moment it is sufficient to use the re-connect activity, in the future we may want to
//customise the behavior, for example start the new layer before rebinding it, etc.
//Should rebinding fail, the mobility activity will be set to an error mode. The error mode will be cleared if
//there are other bearers this activity can offer. If there aren't the data client will be errored.
- NODEACTIVITY_ENTRY(MobilityMCprStates::KReConnect, CMobilityActivity::TRequestReConnect, MCprStates::TAwaitingReConnectCompleteOrError, CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards)
+ NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TRequestReConnect, MCprStates::TAwaitingReConnectCompleteOrError, CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards)
//Rebinding has been successful. As far as MCPR is concerned, the mobility is finished, but the MCPR must await
- //for the handshake (accept|reject) before it can offer another bearer.
+ //for the handshake (accept|reject) before it can offer another bearer.
NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TInformMigrationCompleted, MobilityMCprStates::TAwaitingMigrationAcceptedOrRejected, MeshMachine::TTag<MobilityMCprStates::KStartMobilityHandshake|EBackward>)
NODEACTIVITY_END()
}
@@ -164,7 +164,7 @@
ACTIVITY_MAP_END_BASE(MCprActivities, coreMCprActivities)
}
-///////////////////////////////////////////////////////////////////////////////
+//
// CMobilityActivity
MeshMachine::CNodeActivityBase* MobilityMCprActivities::CMobilityActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
{
@@ -210,12 +210,11 @@
// - current bearer rejected;
// - proposed bearer rejected;
// - failure to migrate to the proposed bearer;
- lastRejected = iAvailable ? iAvailable :
- static_cast<RMetaServiceProviderInterface*>(aContext.Node().ServiceProvider());
+ lastRejected = iPreferred ? iPreferred :
+ static_cast<RMetaServiceProviderInterface*>(aContext.Node().ServiceProvider());
}
-
- iCandidate = iAvailable;
- iAvailable = NULL; //Do not remember rejected candidate any longer
+
+ iPreferred = NULL; //Do not remember rejected candidate any longer
while ((candidate = static_cast<RMetaServiceProviderInterface*>(iter++)) != NULL)
{
const TAvailabilityStatus& status = candidate->AvailabilityStatus();
@@ -230,8 +229,7 @@
if (status.Score() > iAvailabilityScoreTreshold
&& candidate!=lastRejected)
{
- if (candidate==aContext.Node().ServiceProvider()
- && Error() == KErrNone )
+ if (candidate->Flags() & TCFClientType::EStarted)
{
//The preferred one is the current one, is still available and was not just rejected.
//No need to do anything more.
@@ -239,7 +237,7 @@
}
//A new match found
- iAvailable = candidate;
+ iPreferred = candidate;
return ETrue;
}
}
@@ -258,22 +256,6 @@
static_cast<CMobilityMetaConnectionProvider&>(iNode).iIsHandshakingNow = EFalse;
}
-DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrReConnectOrStartMobilityHandshakeBackwards, NetStateMachine::MStateFork, CMobilityActivity::TContext)
-TInt CMobilityActivity::TNoTagOrReConnectOrStartMobilityHandshakeBackwards::TransitionTag()
- {
- if (iContext.Activity()->Error() == KErrNone &&
- (message_cast<TCFMobilityProvider::TMigrationRequested>(&iContext.iMessage) ||
- message_cast<TCFMcpr::TReConnectComplete>(&iContext.iMessage)))
- {
- CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity);
- if( activity.iCurrent!=activity.iAvailable )
- return MobilityMCprStates::KReConnect | NetStateMachine::EForward;
- else
- return MeshMachine::KNoTag | NetStateMachine::EForward;
- }
- return MobilityMCprStates::KStartMobilityHandshake | NetStateMachine::EBackward;
- }
-
DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards, NetStateMachine::MStateFork, CMobilityActivity::TContext)
TInt CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards::TransitionTag()
{
@@ -281,7 +263,7 @@
(message_cast<TCFMobilityProvider::TMigrationRequested>(&iContext.iMessage) ||
message_cast<TCFMcpr::TReConnectComplete>(&iContext.iMessage)))
{
- return MeshMachine::KNoTag | NetStateMachine::EForward;
+ return MeshMachine::KNoTag | NetStateMachine::EForward;
}
return MobilityMCprStates::KStartMobilityHandshake | NetStateMachine::EBackward;
}
@@ -290,13 +272,13 @@
TInt CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger::TransitionTag()
{
//This is where the judgement is made on whether to trigger mobility (offer the client another bearer)
- //or ignore and come back waiting.
+ //or ignore and come back waiting.
__ASSERT_DEBUG(iContext.iMessage.IsMessage<TCFMobilityProvider::TMigrationRejected>() ||
- iContext.iMessage.IsMessage<TCFAvailabilityControlClient::TAvailabilityNotification>(),
+ iContext.iMessage.IsMessage<TCFAvailabilityControlClient::TAvailabilityNotification>(),
User::Panic(KCoreMobileMCprPanic, KPanicIncorrectMessage));
- __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity);
-
+
if (activity.EvaluatePreference(iContext))
{
activity.SetError(KErrNone);
@@ -313,9 +295,9 @@
DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrAwaitMobility, NetStateMachine::MStateFork, CMobilityActivity::TContext)
TInt CMobilityActivity::TNoTagOrAwaitMobility::TransitionTag()
{
- __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity);
-
+
if (activity.EvaluatePreference(iContext))
{
activity.SetError(KErrNone);
@@ -350,41 +332,26 @@
//Inform the CPR that a potential migration is available. We only support a single data client
//in this implementation.
- __ASSERT_DEBUG(activity.iAvailable, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
+ __ASSERT_DEBUG(activity.iPreferred, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
//Compute all this here to keep EvaluatePreference() as fast as possible
- activity.iCurrent = static_cast<RMetaServiceProviderInterface*>(iContext.Node().ServiceProvider());
+ activity.iCurrent = static_cast<RMetaServiceProviderInterface*>(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EStarted)));
__ASSERT_DEBUG(activity.iCurrent, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
//Perform a simple check if this is an upgrade or not
TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider));
RNodeInterface* sp = iter++;
- while (sp && sp!=activity.iCurrent && sp!=activity.iAvailable)
+ while (sp && sp!=activity.iCurrent && sp!=activity.iPreferred)
{
sp = iter++;
}
TBool isUpgrade = (sp != activity.iCurrent); //If current was found first -> this is not an upgrade
- if( activity.iCurrent == activity.iAvailable && activity.iCandidate )
- {
- // The available client is the same as the current and a candidate exists, this indicates that
- // an error has occured when trying to start the candidate bearer and the control as reverted to
- // the current bearer. In this situation the notification needs to look as if the bearer has
- // migrated from the failed candidate to the current bearer.
- TCFMobilityControlClient::TMigrationNotification msg(activity.iCandidate->ProviderInfo().APId(),
- activity.iAvailable->ProviderInfo().APId(),
- isUpgrade, EFalse);
- activity.PostToOriginators(msg);
- }
- else
- {
- // Standard case where migration is going from current to available.
- TCFMobilityControlClient::TMigrationNotification msg(activity.iCurrent->ProviderInfo().APId(),
- activity.iAvailable->ProviderInfo().APId(),
- isUpgrade, EFalse);
- activity.PostToOriginators(msg);
- }
+ TCFMobilityControlClient::TMigrationNotification msg(activity.iCurrent->ProviderInfo().APId(),
+ activity.iPreferred->ProviderInfo().APId(),
+ isUpgrade, EFalse);
+ activity.PostToOriginators(msg);
activity.ClearPostedTo();
activity.SetHandshakingFlag();
}
@@ -408,13 +375,13 @@
__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity);
- __ASSERT_DEBUG(activity.iAvailable, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
+ __ASSERT_DEBUG(activity.iPreferred, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
__ASSERT_DEBUG(activity.iCurrent, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
- __ASSERT_DEBUG(activity.iCurrent!=activity.iAvailable, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 1));
+ __ASSERT_DEBUG(activity.iCurrent!=activity.iPreferred, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 1));
// For the moment it is sufficient to use the re-connect activity, in the future we may want to
// customise the behavior, for example start the new layer before rebinding it, etc.
- TCFMcpr::TReConnect msg(activity.iCurrent->RecipientId(), activity.iAvailable->RecipientId());
+ TCFMcpr::TReConnect msg(activity.iCurrent->RecipientId(), activity.iPreferred->RecipientId());
activity.PostRequestTo(iContext.NodeId(), msg);
}
@@ -435,7 +402,7 @@
}
-///////////////////////////////////////////////////////////////////////////////
+//
//CConnectionRecoveryActivity
MeshMachine::CNodeActivityBase* CConnectionRecoveryActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
{
@@ -501,26 +468,27 @@
void CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest::DoL()
{
__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
- RNodeInterface* newSP = NULL;
- RNodeInterface* curSP = iContext.Node().ServiceProvider(); //Our current started Service Provider.
+ RNodeInterface* startingSP = NULL;
+ RNodeInterface* stoppingSP = NULL;
//Choose Service Providers to work on
TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider));
RNodeInterface* itf = NULL;
- for (itf = iter++; itf!=NULL && newSP==NULL; itf = iter++)
+ for (itf = iter++; itf!=NULL && stoppingSP==NULL; itf = iter++)
{
- if (itf==curSP)
+ if (itf->Flags() & TCFClientType::EStarted)
{
- newSP = iter++; //And the new one to try next
+ stoppingSP = itf; //Our current started Service Provider.
+ startingSP = iter++; //And the new one to try next
}
}
//Sanity check.
//The new provider must not be started, there can be only one started at a time.
- __ASSERT_DEBUG(newSP==NULL || (newSP->Flags() & TCFClientType::EStarted)==0, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 3));
+ __ASSERT_DEBUG(startingSP==NULL || (startingSP->Flags() & TCFClientType::EStarted)==0, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 3));
//If there is no other Service Provider to try, return KErrNotFound
- if (newSP==NULL || curSP == NULL)
+ if (startingSP==NULL || stoppingSP == NULL)
{
#ifdef __CFLOG_ACTIVE
__CFLOG_VAR((KCoreMCprStatesTag, KCoreMCprStatesSubTag, _L8("WARNING: CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest::DoL() - no more choices, abandoning recovery.")));
@@ -531,7 +499,7 @@
//Diagnostinc - there must be a data client or we cannot be here
__ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData)), User::Panic(KCoreMobileMCprPanic, KPanicNoDataClient));
iContext.iNodeActivity->PostRequestTo(iContext.NodeId(),
- TCFMcpr::TReConnect(curSP->RecipientId(), newSP->RecipientId()).CRef());
+ TCFMcpr::TReConnect(stoppingSP->RecipientId(), startingSP->RecipientId()).CRef());
}
DEFINE_SMELEMENT(CConnectionRecoveryActivity::TProcessConnectionGoneDownRecoveryRequest, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext)
@@ -540,7 +508,7 @@
__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
CConnectionRecoveryActivity& activity = static_cast<CConnectionRecoveryActivity&>(*iContext.iNodeActivity);
- RNodeInterface* started = iContext.Node().ServiceProvider();
+ RNodeInterface* started = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EStarted));
TUint apId = (TUint)activity.iOriginalErrContext.iInfo;
RNodeInterface* gonedownsp = iContext.Node().FindServiceProvider(apId);
if (started && started != gonedownsp)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/MobilityCoreProviders/src/mobilitymcpractivities.cpp.orig Thu Jan 07 13:34:53 2010 +0200
@@ -0,0 +1,586 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <elements/nm_messages_errorrecovery.h>
+#include <comms-infras/ss_coreprstates.h>
+#include "mobilitymcpractivities.h"
+#include <comms-infras/mobilitymcprstates.h>
+#include <comms-infras/ss_nodemessages_selector.h>
+#include <comms-infras/ss_nodemessages_mobility.h>
+#include <comms-infras/ss_nodemessages_availability.h>
+#include <comms-infras/ss_logext.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)
+_LIT(KSpecAssert_ESockMbCrMCPRAct, "ESockMbCrMCPRAct");
+#endif
+
+#ifdef __CFLOG_ACTIVE
+ #define KCoreMCprStatesTag KESockMetaConnectionTag
+ _LIT8(KCoreMCprStatesSubTag, "coremcprstate");
+#endif
+
+using namespace ESock;
+using namespace CorePanics;
+using namespace MCprStates;
+using namespace NetStateMachine;
+using namespace MCprActivities;
+using namespace MobilityMCprActivities;
+using namespace Messages;
+using namespace MeshMachine;
+
+//
+//Panics
+#ifdef _DEBUG
+_LIT (KCoreMobileMCprPanic,"CoreMobileMCprPanic");
+#endif
+
+namespace MobilityMCprPrioritisedSelectActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivitySelect, MCprPrioritisedSelect, TCFSelector::TSimpleSelect, CSelectNextLayerActivity::NewL)
+ //Reply from TAwaitingSelectNextLayer if no choices, otherwise accept
+ FIRST_NODEACTIVITY_ENTRY(MCprStates::TAwaitingSelectNextLayer, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, CSelectNextLayerActivity::TProcessPrioritisedSelectionPolicy, MCprStates::TSelectedProvider)
+ //Start the selection main loop
+ NODEACTIVITY_ENTRY(MCprStates::KSelectedProvider, CSelectNextLayerActivity::TFindOrCreateTierManager, MCprStates::TAwaitingTierManagerCreated, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CSelectNextLayerActivity::TJoinTierManager, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag)
+ //Select next provider and enter the selection internal loop if provider received. Break if SelectComplete(NULL).
+ NODEACTIVITY_ENTRY(KNoTag, CSelectNextLayerActivity::TSelectNextLayer, MCprStates::TAwaitingSelectComplete, CSelectNextLayerActivity::TNoTagOrSelectedProviderIsNull)
+ NODEACTIVITY_ENTRY(KNoTag, CSelectNextLayerActivity::TAddProviderInfo, MCprStates::TAwaitingSelectComplete, CSelectNextLayerActivity::TNoTagBackwardsOrJoinServiceProvider)
+ //Break the selection internal loop if SelectComplete(NULL), otherwise stay in this tripple
+ NODEACTIVITY_ENTRY(MCprStates::KJoinServiceProvider, CSelectNextLayerActivity::TJoinServiceProvider, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, CSelectNextLayerActivity::TSendSelectComplete, CSelectNextLayerActivity::TSelectedProviderIsNullOrJoinServiceProviderBackward)
+ //Break the selection main loop if no more choices, otherwise go back again
+ THROUGH_NODEACTIVITY_ENTRY(MCprStates::KSelectedProviderIsNull, CSelectNextLayerActivity::TLeaveTierManager, CSelectNextLayerActivity::TNoTagOrSelectedProviderBackward)
+ //Finish the activity
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MCprStates::TSendFinalSelectComplete)
+NODEACTIVITY_END()
+}
+
+namespace MobilityMCprMobilityActivity
+{
+//This activity monitors availability status on this node
+//NOTE: This activity assumes there is only one data client (Cpr) of this MCpr!
+//NOTE: This activity can only be executed in the context of CMobilityMetaConnectionProvider (or derived)
+//NOTE: TError may come from the availability activity only. It is handled by the ECFActivityError.
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityMCprMobility, MCprMobility, TCFMobilityProvider::TStartMobility, MobilityMCprActivities::CMobilityActivity::NewL)
+ //The activity only makes sense after the startup sequence completed on this layer
+ FIRST_NODEACTIVITY_ENTRY(MobilityMCprStates::TAwaitingStartMobility, MeshMachine::TNoTag/*BlockedByNoServiceProviderStarted*/)
+ //Report to the client that we have successfully started
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, MobilityMCprStates::TReplyMobilityStarted, MeshMachine::TNoTag)
+ //Register with self for availability notifications. Self will report _any_ availabilty change (even available->available) back to
+ //this activity. This activity can trigger mobility (see CMobilityActivity::TNoTagOrErrorTagOrStartMobilityHandshakeBackwardsOnMobilityTriggerBlockedByErrorRecovery)
+ //if it sees that the availability notification has influcenced what the currently preffered bearer should be.
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TSendAvailabilityRequest, MeshMachine::TTag<MobilityMCprStates::KStartMobilityHandshake>)
+
+ //<BEGIN> MAIN LOOP ****************
+ //The main mobility handshake loop. The loop is executed when performing migration from one service provider to another.
+ //The entry condition for the loop is that:
+ //- upgrade: a better then current access point is now available (a better access point reported available)
+ //- downgrade:
+ // (a) the current access point is being rejected by the client (e.g.: the current access point doesn't seem to route traffic where required)
+ // (b) the current access point ceases to be available (reports availability below reasonable threshold).
+ // NOTE: if the current bearer ceases to be available completely (goes down), then this will be assisted by an error recovery request;
+ // NOTE: This tuple doesn't actually do (b), i.e.: assumes the threshold of '1' (in 0..100 availability score range)
+ //Before awaitng for availability change or rejection by the client (TAwaitingCurrentCarrierRejectedOrAvailabilityChange), the activity
+ //first checks (TNoTagOrAwaitMobilityBlockedByErrorRecovery) if the availability has changed since it last checked
+ //(availability could have been reported amidst the previous handshake loop)
+ THROUGH_NODEACTIVITY_ENTRY(MobilityMCprStates::KStartMobilityHandshake, CMobilityActivity::TClearHandshakingFlag, CMobilityActivity::TNoTagOrAwaitMobilityBlockedByErrorRecovery)
+ NODEACTIVITY_ENTRY(MobilityMCprStates::KAwaitMobility, MeshMachine::TDoNothing, CMobilityActivity::TAwaitingCurrentCarrierRejectedOrAvailabilityChange, CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTriggerBlockedByErrorRecovery)
+
+ //Mobility has been triggered ((a) or (b)). Start mobility handshake (set handshaking flag and inform the client about the preferred bearer)
+ NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TInformMigrationAvailableAndSetHandshakingFlag, MobilityMCprStates::TAwaitingMigrationRequestedOrRejected, CMobilityActivity::TNoTagOrReConnectOrStartMobilityHandshakeBackwards)
+ //The client accepts the new access point.
+ //For the moment it is sufficient to use the re-connect activity, in the future we may want to
+ //customise the behavior, for example start the new layer before rebinding it, etc.
+ //Should rebinding fail, the mobility activity will be set to an error mode. The error mode will be cleared if
+ //there are other bearers this activity can offer. If there aren't the data client will be errored.
+ NODEACTIVITY_ENTRY(MobilityMCprStates::KReConnect, CMobilityActivity::TRequestReConnect, MCprStates::TAwaitingReConnectCompleteOrError, CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards)
+ //Rebinding has been successful. As far as MCPR is concerned, the mobility is finished, but the MCPR must await
+ //for the handshake (accept|reject) before it can offer another bearer.
+ NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TInformMigrationCompleted, MobilityMCprStates::TAwaitingMigrationAcceptedOrRejected, MeshMachine::TTag<MobilityMCprStates::KStartMobilityHandshake|EBackward>)
+NODEACTIVITY_END()
+}
+
+namespace MCprConnectionStartRecoveryActivity
+{
+//MCprConnectionStartRecovery activity belongs to a group of Error Recovery Activities.
+//Error Recovery Activities need to handle their own errors (generated as well as returned).
+
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityConnectionStartRecovery, MCprConnectionStartRecovery, TEErrorRecovery::TErrorRecoveryRequest, CConnectionRecoveryActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(MCprStates::TAwaitingConnectionStartRecoveryRequest, MobilityMCprStates::TNoTagOrErrorTagIfMobilityRunning)
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, CConnectionRecoveryActivity::TSendIgnoreRecoveryResponse)
+
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, CConnectionRecoveryActivity::TStoreErrorContext, MeshMachine::TNoTag)
+ //Decide if it it possible/sensible to reconnect and retry
+ //This transition will leave if not possible to recover (==TSendPropagateRecoveryResponse from Transition::Error())
+ NODEACTIVITY_ENTRY(KNoTag, CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest, MCprStates::TAwaitingReConnectCompleteOrError, MeshMachine::TNoTagOrErrorTag) //Own error handling
+ //Respond with retry
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CConnectionRecoveryActivity::TSendRetryRecoveryResponse)
+ //Respond with propagate - the reconnect failed (we could think of re-trying reconnect again though..)
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, CConnectionRecoveryActivity::TSendPropagateRecoveryResponse)
+NODEACTIVITY_END()
+}
+
+namespace MCprConnectionGoneDownRecoveryActivity
+{
+//MCprConnectionGoneDownRecovery activity belongs to a group of Error Recovery Activities.
+//Error Recovery Activities need to handle their own errors (generated as well as returned).
+
+//NOTE: This activity is only a reference one. All it does it waits for the mobility handshake to finish before
+//continuing with the stack cleanup originated by TGoneDown.
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityConnectionGoneDownRecovery, MCprConnectionGoneDownRecovery, TEErrorRecovery::TErrorRecoveryRequest, CConnectionRecoveryActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(MCprStates::TAwaitingConnectionGoneDownRecoveryRequest, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, CConnectionRecoveryActivity::TStoreErrorContext, CoreStates::TNoTagOrNoPeer)
+ LAST_NODEACTIVITY_ENTRY(CoreStates::KNoPeer, MCprStates::TSendPropagateRecoveryResponse) //Take error codes directly from the request
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, MobilityMCprStates::TNoTagBlockedByMobilityHandshaking)
+ //Decide if it it possible/sensible to retry
+ //This transition will leave if not possible to recover (==TSendPropagateRecoveryResponse from Transition::Error())
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CConnectionRecoveryActivity::TProcessConnectionGoneDownRecoveryRequest) //Take error codes from the request directly
+NODEACTIVITY_END()
+}
+
+namespace MobilityMCprActivities
+{
+DEFINE_EXPORT_ACTIVITY_MAP(mobilityMCprActivities)
+ ACTIVITY_MAP_ENTRY(MobilityMCprPrioritisedSelectActivity, MCprPrioritisedSelect)
+ ACTIVITY_MAP_ENTRY(MobilityMCprMobilityActivity, MCprMobility)
+ ACTIVITY_MAP_ENTRY(MCprConnectionStartRecoveryActivity,MCprConnectionStartRecovery)
+ ACTIVITY_MAP_ENTRY(MCprConnectionGoneDownRecoveryActivity,MCprConnectionGoneDownRecovery)
+ACTIVITY_MAP_END_BASE(MCprActivities, coreMCprActivities)
+}
+
+//
+// CMobilityActivity
+MeshMachine::CNodeActivityBase* MobilityMCprActivities::CMobilityActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ return new (ELeave) CMobilityActivity(aActivitySig, aNode);
+ }
+
+CMobilityActivity::CMobilityActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+: MeshMachine::CNodeRetryActivity(aActivitySig, aNode),
+ //NOTE: This reference implementation will currently only react to availability oscilating around
+ //the middle point on the availability scale
+ iAvailabilityScoreTreshold((TAvailabilityStatus::EMinAvailabilityScore + TAvailabilityStatus::EMaxAvailabilityScore) / 2)
+ {
+ }
+
+CMobilityActivity::~CMobilityActivity()
+ {
+ //cancel availablilty subscription.
+ RClientInterface::OpenPostMessageClose(TNodeCtxId(ActivityId(), iNode.Id()), iNode.Id(), TEBase::TCancel().CRef());
+ ClearHandshakingFlag();
+ }
+
+TBool CMobilityActivity::EvaluatePreference(CMobilityActivity::TContext& aContext)
+ {
+ //Find the most preferred Service Provider
+ TClientIter<TDefaultClientMatchPolicy> iter = iNode.GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider));
+ __ASSERT_DEBUG(iter[0], User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); //A Service Provider must exist!
+
+ //If we are evaluating the preferences as a result of carrier rejection, we will
+ //not propose the most recently rejected one.
+ //NOTE: This implementation does not provide a blacklisting mechanism.
+ //It does not store any blacklisting information.
+ //lastRejected is only the recently rejected carrier that may not be proposed again for the client
+ //to be able to renegotiate the old bearer and continue using the connection.
+ //NOTE: This reference implementation will work only when at least one of the two most preferred carriers
+ //can be used (accepted) by the mobility client at any given time.
+ RMetaServiceProviderInterface* candidate = NULL;
+ RMetaServiceProviderInterface* lastRejected = NULL;
+ if ( Error() != KErrNone )
+ {
+ //The activity is running in an error mode attempting to recover from it.
+ //There's a couple of reasons why the activity may be in an error mode:
+ //- rejection
+ // - current bearer rejected;
+ // - proposed bearer rejected;
+ // - failure to migrate to the proposed bearer;
+ lastRejected = iAvailable ? iAvailable :
+ static_cast<RMetaServiceProviderInterface*>(aContext.Node().ServiceProvider());
+ }
+
+ iCandidate = iAvailable;
+ iAvailable = NULL; //Do not remember rejected candidate any longer
+ while ((candidate = static_cast<RMetaServiceProviderInterface*>(iter++)) != NULL)
+ {
+ const TAvailabilityStatus& status = candidate->AvailabilityStatus();
+ if (!status.IsKnown())
+ {
+ //We are still waiting for the availability check results for this AP
+ //Ignore the whole evaluation now as we may soon receive a better candidate
+ //to propose to the mobility client.
+ return EFalse;
+ }
+
+ if (status.Score() > iAvailabilityScoreTreshold
+ && candidate!=lastRejected)
+ {
+ if (candidate==aContext.Node().ServiceProvider()
+ && Error() == KErrNone )
+ {
+ //The preferred one is the current one, is still available and was not just rejected.
+ //No need to do anything more.
+ return EFalse;
+ }
+
+ //A new match found
+ iAvailable = candidate;
+ return ETrue;
+ }
+ }
+
+ //There is no choice for migration
+ return EFalse; //No match found
+ }
+
+void CMobilityActivity::SetHandshakingFlag()
+ {
+ static_cast<CMobilityMetaConnectionProvider&>(iNode).iIsHandshakingNow = ETrue;
+ }
+
+void CMobilityActivity::ClearHandshakingFlag()
+ {
+ static_cast<CMobilityMetaConnectionProvider&>(iNode).iIsHandshakingNow = EFalse;
+ }
+
+DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrReConnectOrStartMobilityHandshakeBackwards, NetStateMachine::MStateFork, CMobilityActivity::TContext)
+TInt CMobilityActivity::TNoTagOrReConnectOrStartMobilityHandshakeBackwards::TransitionTag()
+ {
+ if (iContext.Activity()->Error() == KErrNone &&
+ (message_cast<TCFMobilityProvider::TMigrationRequested>(&iContext.iMessage) ||
+ message_cast<TCFMcpr::TReConnectComplete>(&iContext.iMessage)))
+ {
+ CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity);
+ if( activity.iCurrent!=activity.iAvailable )
+ return MobilityMCprStates::KReConnect | NetStateMachine::EForward;
+ else
+ return MeshMachine::KNoTag | NetStateMachine::EForward;
+ }
+ return MobilityMCprStates::KStartMobilityHandshake | NetStateMachine::EBackward;
+ }
+
+DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards, NetStateMachine::MStateFork, CMobilityActivity::TContext)
+TInt CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards::TransitionTag()
+ {
+ if (iContext.Activity()->Error() == KErrNone &&
+ (message_cast<TCFMobilityProvider::TMigrationRequested>(&iContext.iMessage) ||
+ message_cast<TCFMcpr::TReConnectComplete>(&iContext.iMessage)))
+ {
+ return MeshMachine::KNoTag | NetStateMachine::EForward;
+ }
+ return MobilityMCprStates::KStartMobilityHandshake | NetStateMachine::EBackward;
+ }
+
+DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger, NetStateMachine::MStateFork, CMobilityActivity::TContext)
+TInt CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger::TransitionTag()
+ {
+ //This is where the judgement is made on whether to trigger mobility (offer the client another bearer)
+ //or ignore and come back waiting.
+ __ASSERT_DEBUG(iContext.iMessage.IsMessage<TCFMobilityProvider::TMigrationRejected>() ||
+ iContext.iMessage.IsMessage<TCFAvailabilityControlClient::TAvailabilityNotification>(),
+ User::Panic(KCoreMobileMCprPanic, KPanicIncorrectMessage));
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity);
+
+ if (activity.EvaluatePreference(iContext))
+ {
+ activity.SetError(KErrNone);
+ return KNoTag;
+ }
+ else if (activity.Error() != KErrNone )
+ {
+ activity.PostToOriginators(TEBase::TError(activity.Error()).CRef());
+ activity.SetError(KErrNone);
+ }
+ return MobilityMCprStates::KAwaitMobility | NetStateMachine::EBackward;
+ }
+
+DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrAwaitMobility, NetStateMachine::MStateFork, CMobilityActivity::TContext)
+TInt CMobilityActivity::TNoTagOrAwaitMobility::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity);
+
+ if (activity.EvaluatePreference(iContext))
+ {
+ activity.SetError(KErrNone);
+ return KNoTag;
+ }
+ else if (activity.Error() != KErrNone )
+ {
+ activity.PostToOriginators(TEBase::TError(activity.Error()).CRef());
+ activity.SetError(KErrNone);
+ }
+ return MobilityMCprStates::KAwaitMobility;
+ }
+
+DEFINE_SMELEMENT(CMobilityActivity::TSendAvailabilityRequest, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+void CMobilityActivity::TSendAvailabilityRequest::DoL()
+ {
+ //Issue availability notification registration to start the availability activity on this node.
+ //NOTE: since we've requested availability from self, we are interested in any change (even available->available)
+ //since we could be switching from AP1 available to AP2 available. Either way we must recalculate.
+ //We're hence interested in TAvailabilitySubscriptionOptions::EAnyNestedChange.
+ TAvailabilitySubscriptionOptions availabilityOptions(TAvailabilitySubscriptionOptions::EAnyNestedChange);
+ TCFAvailabilityProvider::TAvailabilityNotificationRegistration msg(availabilityOptions);
+ RClientInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.NodeId(), msg);
+ //Do not set iPostedTo. We are not waiting for the responses.
+ }
+
+DEFINE_SMELEMENT(CMobilityActivity::TInformMigrationAvailableAndSetHandshakingFlag, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+void CMobilityActivity::TInformMigrationAvailableAndSetHandshakingFlag::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity);
+
+ //Inform the CPR that a potential migration is available. We only support a single data client
+ //in this implementation.
+ __ASSERT_DEBUG(activity.iAvailable, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
+
+ //Compute all this here to keep EvaluatePreference() as fast as possible
+ activity.iCurrent = static_cast<RMetaServiceProviderInterface*>(iContext.Node().ServiceProvider());
+ __ASSERT_DEBUG(activity.iCurrent, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
+
+ //Perform a simple check if this is an upgrade or not
+ TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider));
+ RNodeInterface* sp = iter++;
+ while (sp && sp!=activity.iCurrent && sp!=activity.iAvailable)
+ {
+ sp = iter++;
+ }
+
+ TBool isUpgrade = (sp != activity.iCurrent); //If current was found first -> this is not an upgrade
+ if( activity.iCurrent == activity.iAvailable && activity.iCandidate )
+ {
+ // The available client is the same as the current and a candidate exists, this indicates that
+ // an error has occured when trying to start the candidate bearer and the control as reverted to
+ // the current bearer. In this situation the notification needs to look as if the bearer has
+ // migrated from the failed candidate to the current bearer.
+ TCFMobilityControlClient::TMigrationNotification msg(activity.iCandidate->ProviderInfo().APId(),
+ activity.iAvailable->ProviderInfo().APId(),
+ isUpgrade, EFalse);
+ activity.PostToOriginators(msg);
+ }
+ else
+ {
+ // Standard case where migration is going from current to available.
+ TCFMobilityControlClient::TMigrationNotification msg(activity.iCurrent->ProviderInfo().APId(),
+ activity.iAvailable->ProviderInfo().APId(),
+ isUpgrade, EFalse);
+ activity.PostToOriginators(msg);
+ }
+
+ activity.ClearPostedTo();
+ activity.SetHandshakingFlag();
+ }
+
+
+DEFINE_SMELEMENT(CMobilityActivity::TAwaitingCurrentCarrierRejectedOrAvailabilityChange, NetStateMachine::MState, CMobilityActivity::TContext)
+TBool CMobilityActivity::TAwaitingCurrentCarrierRejectedOrAvailabilityChange::Accept()
+ {
+ if (iContext.iMessage.IsMessage<TCFMobilityProvider::TMigrationRejected>())
+ {
+ iContext.Activity()->SetError(KErrNotFound);
+ return ETrue;
+ }
+ return iContext.iMessage.IsMessage<TCFAvailabilityControlClient::TAvailabilityNotification>();
+ }
+
+
+DEFINE_SMELEMENT(CMobilityActivity::TRequestReConnect, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+void CMobilityActivity::TRequestReConnect::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity);
+
+ __ASSERT_DEBUG(activity.iAvailable, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
+ __ASSERT_DEBUG(activity.iCurrent, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
+ __ASSERT_DEBUG(activity.iCurrent!=activity.iAvailable, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 1));
+
+ // For the moment it is sufficient to use the re-connect activity, in the future we may want to
+ // customise the behavior, for example start the new layer before rebinding it, etc.
+ TCFMcpr::TReConnect msg(activity.iCurrent->RecipientId(), activity.iAvailable->RecipientId());
+ activity.PostRequestTo(iContext.NodeId(), msg);
+ }
+
+DEFINE_SMELEMENT(CMobilityActivity::TInformMigrationCompleted, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+void CMobilityActivity::TInformMigrationCompleted::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ iContext.iNodeActivity->PostToOriginators(TCFMobilityProvider::TMigrationComplete().CRef());
+ iContext.iNodeActivity->ClearPostedTo();
+ }
+
+DEFINE_SMELEMENT(CMobilityActivity::TClearHandshakingFlag, NetStateMachine::MStateTransition, CMobilityActivity::TContext)
+void CMobilityActivity::TClearHandshakingFlag::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity);
+ activity.ClearHandshakingFlag();
+ }
+
+
+//
+//CConnectionRecoveryActivity
+MeshMachine::CNodeActivityBase* CConnectionRecoveryActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ return new (ELeave) CConnectionRecoveryActivity(aActivitySig, aNode);
+ }
+
+CConnectionRecoveryActivity::CConnectionRecoveryActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+: MeshMachine::CNodeRetryActivity(aActivitySig, aNode)
+ {
+ }
+
+void CConnectionRecoveryActivity::ReplyToOriginators(TEErrorRecovery::TErrorRecoveryResponse& aCFMessageSig)
+ {
+ NM_LOG_START_BLOCK(KESockMeshMachine, _L8("CConnectionRecoveryActivity::ReplyToOriginators"));
+ NM_LOG((KESockMeshMachine, _L8("[this=0x%08x] "), this));
+ NM_LOG_MESSAGE(KESockMeshMachine, aCFMessageSig);
+ NM_LOG_END_BLOCK(KESockMeshMachine, _L8("CConnectionRecoveryActivity::ReplyToOriginators"));
+ for (TInt n = iOriginators.Count() - 1;n>=0; n--)
+ {
+ Messages::TNodePeerId& peerId = iOriginators[n];
+ TCFSafeMessage::TResponseCarrierWest<TEErrorRecovery::TErrorRecoveryResponse> resp(aCFMessageSig, peerId.RecipientId());
+ peerId.PostMessage(iNode.Id(), resp);
+ }
+ }
+
+DEFINE_SMELEMENT(CConnectionRecoveryActivity::TAwaitingReConnectComplete, NetStateMachine::MState, CConnectionRecoveryActivity::TContext)
+TBool CConnectionRecoveryActivity::TAwaitingReConnectComplete::Accept()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ TEBase::TError* msg = message_cast<TEBase::TError>(&iContext.iMessage);
+ if(msg)
+ {
+ CConnectionRecoveryActivity& ac = static_cast<CConnectionRecoveryActivity&>(*iContext.iNodeActivity);
+ TErrResponse propagateResp(TErrResponse::EPropagate,ac.iOriginalErrContext.iStateChange.iError,ac.iOriginalErrContext.iMessageId);
+ TEErrorRecovery::TErrorRecoveryResponse errResp(propagateResp);
+ ac.ReplyToOriginators(errResp);
+ ac.SetIdle();
+ iContext.iMessage.ClearMessageId();
+ return EFalse;
+ }
+ return (iContext.iMessage.IsMessage<TCFMcpr::TReConnectComplete>())? ETrue : EFalse;
+ }
+
+void CConnectionRecoveryActivity::TTransitionBase::Error(TInt /*aError*/)
+ {
+ //Reply to the Error Activity and terminate
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ CConnectionRecoveryActivity& ac = static_cast<CConnectionRecoveryActivity&>(*iContext.iNodeActivity);
+ TEErrorRecovery::TErrorRecoveryResponse errResp(TErrResponse(TErrResponse::EPropagate,ac.iOriginalErrContext.iStateChange.iError,ac.iOriginalErrContext.iMessageId));
+ ac.ReplyToOriginators(errResp);
+ iContext.iNodeActivity->SetIdle();
+ }
+
+DEFINE_SMELEMENT(CConnectionRecoveryActivity::TStoreErrorContext, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext)
+void CConnectionRecoveryActivity::TStoreErrorContext::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ CConnectionRecoveryActivity& activity = static_cast<CConnectionRecoveryActivity&>(*iContext.iNodeActivity);
+ activity.iOriginalErrContext = message_cast<TEErrorRecovery::TErrorRecoveryRequest>(iContext.iMessage).iErrContext;
+ }
+
+DEFINE_SMELEMENT(CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext)
+void CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ RNodeInterface* newSP = NULL;
+ RNodeInterface* curSP = iContext.Node().ServiceProvider(); //Our current started Service Provider.
+
+ //Choose Service Providers to work on
+ TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider));
+ RNodeInterface* itf = NULL;
+ for (itf = iter++; itf!=NULL && newSP==NULL; itf = iter++)
+ {
+ if (itf==curSP)
+ {
+ newSP = iter++; //And the new one to try next
+ }
+ }
+
+ //Sanity check.
+ //The new provider must not be started, there can be only one started at a time.
+ __ASSERT_DEBUG(newSP==NULL || (newSP->Flags() & TCFClientType::EStarted)==0, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 3));
+
+ //If there is no other Service Provider to try, return KErrNotFound
+ if (newSP==NULL || curSP == NULL)
+ {
+#ifdef __CFLOG_ACTIVE
+ __CFLOG_VAR((KCoreMCprStatesTag, KCoreMCprStatesSubTag, _L8("WARNING: CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest::DoL() - no more choices, abandoning recovery.")));
+#endif
+ User::Leave(KErrNotFound);
+ }
+
+ //Diagnostinc - there must be a data client or we cannot be here
+ __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData)), User::Panic(KCoreMobileMCprPanic, KPanicNoDataClient));
+ iContext.iNodeActivity->PostRequestTo(iContext.NodeId(),
+ TCFMcpr::TReConnect(curSP->RecipientId(), newSP->RecipientId()).CRef());
+ }
+
+DEFINE_SMELEMENT(CConnectionRecoveryActivity::TProcessConnectionGoneDownRecoveryRequest, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext)
+void CConnectionRecoveryActivity::TProcessConnectionGoneDownRecoveryRequest::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ CConnectionRecoveryActivity& activity = static_cast<CConnectionRecoveryActivity&>(*iContext.iNodeActivity);
+
+ RNodeInterface* started = iContext.Node().ServiceProvider();
+ TUint apId = (TUint)activity.iOriginalErrContext.iInfo;
+ RNodeInterface* gonedownsp = iContext.Node().FindServiceProvider(apId);
+ if (started && started != gonedownsp)
+ {
+ CConnectionRecoveryActivity::TSendRetryRecoveryResponse tr(iContext);
+ tr.DoL();
+ }
+ else
+ {
+ CConnectionRecoveryActivity::TSendPropagateRecoveryResponse tr(iContext);
+ tr.DoL();
+ }
+ }
+
+DEFINE_SMELEMENT(CConnectionRecoveryActivity::TSendRetryRecoveryResponse, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext)
+void CConnectionRecoveryActivity::TSendRetryRecoveryResponse::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ CConnectionRecoveryActivity& activity = static_cast<CConnectionRecoveryActivity&>(*iContext.iNodeActivity);
+ TEErrorRecovery::TErrorRecoveryResponse err(TErrResponse(TErrResponse::ERetry,KErrNone,activity.iOriginalErrContext.iMessageId));
+ activity.ReplyToOriginators(err);
+ }
+
+DEFINE_SMELEMENT(CConnectionRecoveryActivity::TSendPropagateRecoveryResponse, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext)
+void CConnectionRecoveryActivity::TSendPropagateRecoveryResponse::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ CConnectionRecoveryActivity& activity = static_cast<CConnectionRecoveryActivity&>(*iContext.iNodeActivity);
+ TEErrorRecovery::TErrorRecoveryResponse err(TErrResponse(TErrResponse::EPropagate,
+ activity.iOriginalErrContext.iStateChange.iError,activity.iOriginalErrContext.iMessageId));
+ activity.ReplyToOriginators(err);
+ }
+
+DEFINE_SMELEMENT(CConnectionRecoveryActivity::TSendIgnoreRecoveryResponse, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext)
+void CConnectionRecoveryActivity::TSendIgnoreRecoveryResponse::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+ CConnectionRecoveryActivity& activity = static_cast<CConnectionRecoveryActivity&>(*iContext.iNodeActivity);
+ TEErrorRecovery::TErrorRecoveryResponse err(TErrResponse(TErrResponse::EIgnore,KErrNone,activity.iOriginalErrContext.iMessageId));
+ activity.ReplyToOriginators(err);
+ }
+
+
--- a/datacommsserver/esockserver/core_states/ss_corepractivities.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/core_states/ss_corepractivities.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -1,9 +1,9 @@
// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
-// under the terms of the License "Symbian Foundation License v1.0"
+// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
-// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
@@ -24,12 +24,14 @@
#define SYMBIAN_NETWORKING_UPS
+#include "ss_corepractivities.h"
+
+
#include <comms-infras/ss_log.h>
#include "ss_internal_activities.h"
-#include "ss_coreprstates.h"
-#include "ss_corepractivities.h"
+#include <comms-infras/ss_coreprstates.h>
#include <comms-infras/ss_subconnprov.h>
-#include "ss_mcprnodemessages.h"
+#include <comms-infras/ss_mcprnodemessages.h>
#include <comms-infras/ss_protocolparameterset.h>
#include <ss_glob.h>
@@ -40,10 +42,10 @@
#include <elements/nm_messages_errorrecovery.h>
#include "ss_nodemessages_dataclient.h"
#include "ss_nodemessages_serviceprovider.h"
-#include "ss_nodemessages_rejoiningprovider.h"
-#include "ss_nodemessages_flow.h"
+#include <comms-infras/ss_nodemessages_rejoiningprovider.h>
+#include <comms-infras/ss_nodemessages_flow.h>
#include "ss_nodemessages_factory.h"
-#include "ss_nodemessages_internal_esock.h"
+#include <comms-infras/ss_nodemessages_internal_esock.h>
#ifdef _DEBUG
@@ -70,6 +72,7 @@
using namespace MeshMachine;
using namespace Factories;
+
#ifdef _DEBUG
_LIT (KCorePrPanic,"CorePrPanic");
#endif
@@ -651,6 +654,16 @@
static_cast<ESock::CMMCommsProviderBase&>(iNode).DeleteMeNow();
}
+TBool CDestroyActivity::Next(TNodeContextBase& aContext)
+ {
+ if (aContext.iMessage.IsMessage<TEBase::TCancel>())
+ {
+ return ETrue;
+ }
+ else
+ return CNodeActivityBase::Next(aContext);
+ }
+
EXPORT_DEFINE_SMELEMENT(CDestroyActivity::TNoTagOrNoTagBackwards, NetStateMachine::MStateFork, PRStates::TContext)
EXPORT_C TInt CDestroyActivity::TNoTagOrNoTagBackwards::TransitionTag()
{
@@ -840,8 +853,6 @@
ACTIVITY_MAP_ENTRY(PRClientLeaveActivity, PRClientLeave)
ACTIVITY_MAP_ENTRY(PRForwardStateChangeActivity, PRForwardStateChange)
ACTIVITY_MAP_ENTRY(PRBindToActivity, PRBindTo)
- ACTIVITY_MAP_ENTRY(PRDataClientStartActivity, PRDataClientStart)
- ACTIVITY_MAP_ENTRY(PRDataClientStopActivity, PRDataClientStop)
ACTIVITY_MAP_END_BASE(CoreActivities,coreActivitiesAll)
//Activity Map provided by CorePr to be used by SCprs.
@@ -850,6 +861,8 @@
ACTIVITY_MAP_ENTRY(PRProvisionActivity, PrProvision)
ACTIVITY_MAP_ENTRY(PRStartActivity, PRStart)
ACTIVITY_MAP_ENTRY(PRStopActivity, PRStop)
+ ACTIVITY_MAP_ENTRY(PRDataClientStartActivity, PRDataClientStart)
+ ACTIVITY_MAP_ENTRY(PRDataClientStopActivity, PRDataClientStop)
ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle)
ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive)
ACTIVITY_MAP_ENTRY(PRDestroyActivity, PRDestroy)
@@ -868,6 +881,8 @@
ACTIVITY_MAP_ENTRY(PRProvisionActivity, PrProvision)
ACTIVITY_MAP_ENTRY(PRStartActivity, PRStart)
ACTIVITY_MAP_ENTRY(PRStopActivity, PRStop)
+ ACTIVITY_MAP_ENTRY(PRDataClientStartActivity, PRDataClientStart)
+ ACTIVITY_MAP_ENTRY(PRDataClientStopActivity, PRDataClientStop)
ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle)
ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive)
ACTIVITY_MAP_ENTRY(PRDestroyActivity, PRDestroy)
@@ -982,11 +997,13 @@
const TCFDataClient::TBindTo& bindToMsg(message_cast<const TCFDataClient::TBindTo>(iContext.iMessage));
__ASSERT_DEBUG(!bindToMsg.iNodeId.IsNull(), User::Panic(KCorePrPanic, KPanicNoServiceProvider));
- activity.iNewServiceProvider = iContext.Node().AddClientL(bindToMsg.iNodeId,
- TClientType(TCFClientType::EServProvider, TCFClientType::EActivating));
- //Join the new service provider
- iContext.iNodeActivity->PostRequestTo(*activity.iNewServiceProvider,
- TCFControlClient::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::ECtrl)).CRef());
+ RNodeInterface* newServiceProvider = iContext.Node().AddClientL(bindToMsg.iNodeId,
+ TClientType(TCFClientType::EServProvider, TCFClientType::EActivating));
+ __ASSERT_DEBUG(newServiceProvider, User::Panic(KCorePrPanic, KPanicNoServiceProvider));
+ activity.iNewServiceProvider = bindToMsg.iNodeId;
+ //Join the new service provider
+ iContext.Activity()->PostRequestTo(*newServiceProvider,
+ TCFControlClient::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::ECtrl)).CRef());
}
EXPORT_DEFINE_SMELEMENT(CBindToActivity::TAwaitingBindToCompleteOrError, NetStateMachine::MState, CRejoinDataClientActivity::TContext)
@@ -1037,8 +1054,9 @@
CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
//The service provider has been joined already and must be found here
- __ASSERT_DEBUG(activity.iNewServiceProvider , User::Panic(KCorePrPanic, KPanicNoServiceProvider));
-
+ __ASSERT_DEBUG(!activity.iNewServiceProvider.IsNull(), User::Panic(KCorePrPanic, KPanicNoServiceProvider));
+ RNodeInterface* newServiceProvider = iContext.Node().FindClient(activity.iNewServiceProvider);
+ __ASSERT_DEBUG(newServiceProvider, User::Panic(KCorePrPanic, KPanicNoServiceProvider));
//We must not be in this transition if dc was not found
__ASSERT_DEBUG(activity.CurrentDataClient(), User::Panic(KCorePrPanic, KPanicDataClient));
@@ -1071,7 +1089,7 @@
// Send "TCommsBinderRequest" to the Current ServiceProvider
activity.PostRequestTo(
- *activity.iNewServiceProvider,
+ *newServiceProvider,
TCFServiceProvider::TCommsBinderRequest(subConnOpenType).CRef()
);
}
@@ -1152,24 +1170,29 @@
return KBearerReady;
}
- if (iContext.Node().ServiceProvider()
- && bindToReq.iNodeId == iContext.Node().ServiceProvider()->RecipientId())
- {
- //received the same service provider, it's already bound to.
- bindToActivity.iNewServiceProvider = iContext.Node().ServiceProvider();
+ RNodeInterface* sp = iContext.Node().ServiceProvider();
+ if (sp && bindToReq.iNodeId == sp->RecipientId())
+ {
+ //received the same service provider, it's already bound to.
+ bindToActivity.iNewServiceProvider = sp->RecipientId();
return KBearerReady;
}
- bindToActivity.iNewServiceProvider = iContext.Node().FindClient(bindToReq.iNodeId);
- if (bindToActivity.iNewServiceProvider)
+ RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToReq.iNodeId);
+ if (newServiceProvider)
{
- __ASSERT_DEBUG(bindToActivity.iNewServiceProvider->Type() == TCFClientType::EServProvider, User::Panic(KCorePrPanic, KPanicIncorrectState));
+ __ASSERT_DEBUG(newServiceProvider->Type() == TCFClientType::EServProvider, User::Panic(KCorePrPanic, KPanicIncorrectState));
//Ok, we've received a TBindTo holding a service provider that we already know of and that is not
//our current service provider. We're going to assume this node tolerates multiple service providers (like MCPRs do).
//the current service provider will be swapped, but won't be dropped.
- bindToActivity.iNewServiceProvider->SetFlags(TCFClientType::EActivating);
+ bindToActivity.iNewServiceProvider = bindToReq.iNodeId;
+ newServiceProvider->SetFlags(TCFClientType::EActivating);
bindToActivity.SetDontLeaveServiceProvider();
return KBearerReady;
}
+ else
+ {
+ bindToActivity.iNewServiceProvider = TNodeId::NullId();
+ }
//The node received a new service provider...
return KNoTag;
}
@@ -1187,7 +1210,7 @@
return KBindToComplete;
}
- if (!bindToActivity.iNewServiceProvider)
+ if (bindToActivity.iNewServiceProvider.IsNull())
{
//There is no service provider (new or old) below us.
return KBearerReady;
@@ -1209,7 +1232,8 @@
};
bindToActivity.iSuccessfulDataClients.Reset();
RNodeInterface* sp = iContext.Node().ServiceProvider();
- if (sp && sp != bindToActivity.iNewServiceProvider)
+
+ if (sp && sp->RecipientId() != bindToActivity.iNewServiceProvider)
{
if (bindToActivity.ShouldLeaveServiceProvider())
{
@@ -1229,14 +1253,19 @@
bindToActivity.SetIdle();
}
- if (bindToActivity.iNewServiceProvider && sp != bindToActivity.iNewServiceProvider)
- {
- __ASSERT_DEBUG(bindToActivity.iNewServiceProvider->Flags() & TCFClientType::EActivating, User::Panic(KCorePrPanic, KPanicIncorrectState));
- bindToActivity.iNewServiceProvider->ClearFlags(TCFClientType::EActivating);
- bindToActivity.iNewServiceProvider->SetFlags(TCFClientType::EActive);
- __ASSERT_DEBUG(iContext.Node().ServiceProvider() == bindToActivity.iNewServiceProvider, User::Panic(KCorePrPanic, KPanicIncorrectState));
- }
- bindToActivity.iNewServiceProvider = NULL;
+ if (!bindToActivity.iNewServiceProvider.IsNull() && (sp == NULL || sp->RecipientId() != bindToActivity.iNewServiceProvider))
+ {
+ RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToActivity.iNewServiceProvider);
+ if (newServiceProvider)
+ {
+ __ASSERT_DEBUG(newServiceProvider->Flags() & TCFClientType::EActivating, User::Panic(KCorePrPanic, KPanicIncorrectState));
+ newServiceProvider->ClearFlags(TCFClientType::EActivating);
+ newServiceProvider->SetFlags(TCFClientType::EActive);
+ // Note: iContext.Node().ServiceProvider() must be re-evaluated in the ASSERT below (i.e. don't use any previously cached value).
+ __ASSERT_DEBUG(iContext.Node().ServiceProvider() == newServiceProvider, User::Panic(KCorePrPanic, KPanicIncorrectState));
+ }
+ }
+ bindToActivity.iNewServiceProvider = TNodeId::NullId();
}
EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCancel, NetStateMachine::MStateTransition, CBindToActivity::TContext)
@@ -1251,25 +1280,28 @@
};
bindToActivity.iSuccessfulDataClients.Reset();
- if (bindToActivity.iNewServiceProvider && bindToActivity.iNewServiceProvider != iContext.Node().ServiceProvider())
- {
- __ASSERT_DEBUG(bindToActivity.iNewServiceProvider->Flags() & TCFClientType::EActivating, User::Panic(KCorePrPanic, KPanicIncorrectState));
- bindToActivity.iNewServiceProvider->ClearFlags(TCFClientType::EActivating);
- if (bindToActivity.ShouldLeaveServiceProvider())
- {
- bindToActivity.PostRequestTo(*bindToActivity.iNewServiceProvider, TEPeer::TLeaveRequest().CRef());
- bindToActivity.iNewServiceProvider->SetFlags(TCFClientType::ELeaving);
- }
- else
- {
- bindToActivity.SetIdle();
- }
- }
- else
- {
- bindToActivity.SetIdle();
- }
- bindToActivity.iNewServiceProvider = NULL;
+ TBool setIdle = ETrue;
+ if (!bindToActivity.iNewServiceProvider.IsNull())
+ {
+ RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToActivity.iNewServiceProvider);
+ if (newServiceProvider && newServiceProvider != iContext.Node().ServiceProvider())
+ {
+ __ASSERT_DEBUG(newServiceProvider->Flags() & TCFClientType::EActivating, User::Panic(KCorePrPanic, KPanicIncorrectState));
+ newServiceProvider->ClearFlags(TCFClientType::EActivating);
+ if (bindToActivity.ShouldLeaveServiceProvider())
+ {
+ bindToActivity.PostRequestTo(*newServiceProvider, TEPeer::TLeaveRequest().CRef());
+ newServiceProvider->SetFlags(TCFClientType::ELeaving);
+ setIdle = EFalse;
+ }
+ }
+ }
+
+ if (setIdle)
+ {
+ bindToActivity.SetIdle();
+ }
+ bindToActivity.iNewServiceProvider = TNodeId::NullId();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/core_states/ss_corepractivities.cpp.orig Thu Jan 07 13:34:53 2010 +0200
@@ -0,0 +1,2041 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// COREPRACTIVITIES.CPP
+// Core PR Activities
+// THIS API IS INTERNAL TO NETWORKING AND IS SUBJECT TO CHANGE AND NOT FOR EXTERNAL USE
+//
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#define SYMBIAN_NETWORKING_UPS
+
+#include "ss_corepractivities.h"
+
+
+#include <comms-infras/ss_log.h>
+#include "ss_internal_activities.h"
+#include <comms-infras/ss_coreprstates.h>
+#include <comms-infras/ss_subconnprov.h>
+#include <comms-infras/ss_mcprnodemessages.h>
+
+#include <comms-infras/ss_protocolparameterset.h>
+#include <ss_glob.h>
+
+
+#include <elements/nm_messages_child.h>
+#include <elements/nm_messages_peer.h>
+#include <elements/nm_messages_errorrecovery.h>
+#include "ss_nodemessages_dataclient.h"
+#include "ss_nodemessages_serviceprovider.h"
+#include <comms-infras/ss_nodemessages_rejoiningprovider.h>
+#include <comms-infras/ss_nodemessages_flow.h>
+#include "ss_nodemessages_factory.h"
+#include <comms-infras/ss_nodemessages_internal_esock.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)
+_LIT(KSpecAssert_ESockCrStaCPRAC, "ESockCrStaCPRAC");
+#endif
+
+#if defined __CFLOG_ACTIVE || defined ESOCK_EXTLOG_ACTIVE
+ #define KCoreProviderStatesTag KESockCoreProviderTag
+ _LIT8(KCoreProviderStatesSubTag, "coreprovstate");
+#endif
+
+using namespace NetStateMachine;
+using namespace CoreStates;
+using namespace CoreNetStates;
+using namespace PRStates;
+using namespace PRActivities;
+using namespace CoreActivities;
+using namespace ESock;
+using namespace CorePanics;
+using namespace Elements;
+using namespace Messages;
+using namespace MeshMachine;
+using namespace Factories;
+
+
+#ifdef _DEBUG
+_LIT (KCorePrPanic,"CorePrPanic");
+#endif
+
+namespace CoreErrorActivity
+{ //Special parallel activity, must be started as the last one
+DEFINE_EXPORT_CUSTOM_NODEACTIVITY(ECFActivityError, CoreError, TEBase::TError, CErrorActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CErrorActivity::TCFAwaitingError, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CErrorActivity::TSendErrorRecoveryReq, MeshMachine::TAwaitingMessageState<TEErrorRecovery::TErrorRecoveryResponse>, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CErrorActivity::TDoErrorRecovery)
+NODEACTIVITY_END()
+}
+
+namespace PRProvisionActivity
+{
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityStoreProvision, PrProvision, TCFDataClient::TProvisionConfig)
+ NODEACTIVITY_ENTRY(KNoTag, PRStates::TStoreProvision, CoreNetStates::TAwaitingProvision, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace PRControlClientJoinActivity
+{
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityClientJoin, PRControlClientJoin, TNodeSignal::TNullMessageId) //May be waiting for both messages
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TAddControlClientAndSendJoinCompleteIfRequest, CoreNetStates::TAwaitingControlClientJoin, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace PRDataClientJoinActivity
+{ //This activity needs the activity object (& it can fail on AddClientL, so no point converting)
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityDataClientJoin, PRDataClientJoin, TCFPeer::TJoinRequest)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientJoinRequest, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TAddDataClientAndRespond)
+NODEACTIVITY_END()
+}
+
+namespace PRClientLeaveActivity
+{//This activity will wait for ECFActivityBinderRequest to complete
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityClientLeave, PRClientLeave, TNodeSignal::TNullMessageId) //May be waiting for both messages
+NODEACTIVITY_ENTRY(KNoTag, PRStates::TProcessClientLeave, CoreStates::TAwaitingClientLeave, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace PRDataClientIdleActivity
+{
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityDataClientIdle, PRDataClientIdle, TCFControlProvider::TIdle)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::THandleDataClientIdle, CoreNetStates::TAwaitingDataClientIdle, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace PRDataClientActiveActivity
+{
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityDataClientActive, PRDataClientActive, TCFControlProvider::TActive)
+ NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, CoreNetStates::TAwaitingDataClientActive, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace PRDestroyActivity
+{
+//The generic Destroy activity. Carries out the node's goodbye handshake.
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityDestroy, PRDestroy, TEChild::TDestroy, CoreActivities::CDestroyActivity::New)
+ FIRST_NODEACTIVITY_ENTRY(MeshMachine::TAwaitingDestroy, CoreActivities::CDestroyActivity::TNoTagBlockedByActivitiesOrLeavingDataClient)
+
+ //Stop self first
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, CoreStates::TNoTagOrNoClients)
+
+ //The node mustn't go out of scope with clients present. The node must get rid of them first.
+ NODEACTIVITY_ENTRY(KNoTag, CoreActivities::CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave, CoreStates::TAwaitingClientLeave, CDestroyActivity::TNoTagOrNoTagBackwards)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreActivities::CDestroyActivity::TProcessClientLeave, TTag<KNoClients>)
+
+ THROUGH_NODEACTIVITY_ENTRY(KNoClients, PRStates::TProcessDestroy, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, MeshMachine::TAwaitingLeaveComplete, CoreActivities::CDestroyActivity::TNoTagOrNoTagBackwards)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingAndRemoveControlProvider)
+NODEACTIVITY_END()
+}
+
+namespace PRSetParamsRequest
+{
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRSetParams, TCFScpr::TSetParamsRequest)
+ FIRST_NODEACTIVITY_ENTRY(PRStates::TAwaitingParamRequest, CoreNetStates::TNoTagOrBearerPresent)
+ NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, PRStates::TPassToServiceProvider, CoreNetStates::TAwaitingParamResponse, MeshMachine::TTag<CoreNetStates::KBearerPresent>)
+ LAST_NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, PRStates::TStoreParamsAndPostToOriginators)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TStoreAndRespondWithCurrentParams)
+NODEACTIVITY_END()
+#else
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRSetParams, TNodeSignal::TNullMessageId)
+NODEACTIVITY_END()
+#endif
+}
+
+// no Store in case of GetParamsRequest
+namespace PRGetParamsRequest
+{
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRGetParams, TCFScpr::TGetParamsRequest)
+ FIRST_NODEACTIVITY_ENTRY(PRStates::TAwaitingParamRequest, CoreNetStates::TNoTagOrBearerPresent)
+ NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, PRStates::TPassToServiceProvider, CoreNetStates::TAwaitingParamResponse, MeshMachine::TTag<CoreNetStates::KBearerPresent>)
+ LAST_NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreStates::TPostToOriginators)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TRespondWithRetrievedParams)
+NODEACTIVITY_END()
+#else
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRGetParams, TNodeSignal::TNullMessageId)
+NODEACTIVITY_END()
+#endif
+}
+
+namespace PRBindToActivity
+{
+//PRBindToActivity is responsible for handling TCFDataClient::TBindTo;
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityBindTo, PRBindTo, TCFDataClient::TBindTo, CBindToActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingBindTo, CBindToActivity::TNoTagOrBearerReady)
+ //TBindTo can hold:
+ //[KNoTag] - a valid serviceProvider cookie that this node isn't bound to;
+ //[KBearerReady] - a valid serviceProvider cookie that this node is already bound to;
+ //[KBearerReady] - a NULL serviceProvider (this node is at the stack's bottom);
+
+ //{ JOINING NEW SERVICE PROVIDER
+ //a valid serviceProvider supplied, new to this node, let's join it;
+ NODEACTIVITY_ENTRY(KNoTag, CBindToActivity::TSendControlClientJoinRequest, CoreStates::TAwaitingJoinComplete, TTag<KBearerReady>)
+ //}
+
+ //serviceProvider provisionally joined. Now the activity needs to propagate iteslf (TBindTo) to its dataclients.
+ //The dataclients are either present or not. If not this activity will assume this is the layer construction phase
+ //and will attempt to construct a default dataclient.
+ THROUGH_NODEACTIVITY_ENTRY(KBearerReady, MeshMachine::TDoNothing, CBindToActivity::TNoTagOrDataClientReady)
+
+ //{ DATA CLIENT CREATION
+ //No dataclients present, assume this is the layer creation phase. Attempt to create a dataclient.
+ NODEACTIVITY_ENTRY(KNoTag, CBindToActivity::TCreateDataClient, TAcceptErrorState<CoreNetStates::TAwaitingDataClientJoin>, MeshMachine::TErrorTagOr<CBindToActivity::TNoTagOrBindToComplete>)
+ //BindTo activity is the pre-start layer builder, hence it always requests the dataclient from the factory.
+ //The factory (being aware of the phase) may decide to:
+ //1. create a new dataclient -> process dataclient creation [KNoTag]
+ //2. return a preexisting dataclient -> bind the client [KDataClientReady]
+ //3. not to create a dataclient -> send TBindToComplete to the originator [KBindToComplete]
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, PRStates::TProcessDataClientCreation, TTag<KDataClientReady>)
+ //}
+
+ THROUGH_NODEACTIVITY_ENTRY(KDataClientReady, MeshMachine::TDoNothing, CBindToActivity::TNoTagOrBearerReadyOrBindToComplete)
+ //{ BINDING DATACLIENTS LOOP
+ //Dataclient(s) is/are ready. Depending on whether the node has the lower layer or not,
+ //we will [KNoTag] or will not [KNoBearer] need to request a binder for the dataclient.
+
+ //{SERVICE PROVIDER PRESENT
+ NODEACTIVITY_ENTRY(KNoTag, CBindToActivity::TRequestCommsBinder, TAcceptErrorState<CoreNetStates::TAwaitingBinderResponse>, TErrorTagOr<TTag<KBearerReady> >)
+ //}
+ NODEACTIVITY_ENTRY(KBearerReady, PRActivities::CBindToActivity::TSendBindTo, CBindToActivity::TAwaitingBindToCompleteOrError,
+ TErrorTagOr<TTag<KDataClientReady | NetStateMachine::EBackward> >)
+ //}
+
+ //Binding is finished. If this is not autocommit (see TCFDataClient::TBindTo), the activity will reply TCFDataClient::TBindToComplete
+ //to the sender await for the confirmation (TCFDataClient::TCommitBindTo) or cancelation (TBase::TCancel) from the sender.
+ //If this is autommit, the activity will skip awaiting for TCFDataClient::TCommitBindTo and commit itself.
+ THROUGH_NODEACTIVITY_ENTRY(KBindToComplete, CBindToActivity::TSendBindToComplete, CBindToActivity::TNoTagOrCommit)
+ NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, MeshMachine::TAwaitingMessageState<TCFDataClient::TCommitBindTo>, TErrorTagOr<TTag<KCommit> >)
+
+ //commiting (either implicit or explicit).
+ NODEACTIVITY_ENTRY(KCommit, CBindToActivity::TCommit, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
+
+ //This is not autocommit and the sender has just explicitly cancelled. Alternativelly this is an error path.
+ //Cancelling/processing error entiles sending TCancel to all dataclients awaiting confirmation
+ //as well as it entiles leaving the new service provider.
+ NODEACTIVITY_ENTRY(KErrorTag, CBindToActivity::TCancel, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
+
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
+NODEACTIVITY_END()
+}
+
+namespace PRStartActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStart, PRStart, TCFServiceProvider::TStart, PRActivities::CStartActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingStart, CoreNetStates::TNoTagOrBearerPresentBlockedByStop)
+ NODEACTIVITY_ENTRY(KBearerPresent, CoreNetStates::TBindSelfToPresentBearer, CoreNetStates::TAwaitingBindToComplete, TTag<KBearerPresent>)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendNoBearer, MeshMachine::TAwaitingMessageState<TCFControlProvider::TBearer>, CoreNetStates::TNoTagOrBearerPresentOrErrorTag)
+
+ //Start the service provider, use the default cancellation.
+ //Forward TCancel to the service provider, wait for TStarted or TError (via the Error Activity)
+ //When TStarted arrives after TCancel the activity will move to the nearest KErrorTag
+ NODEACTIVITY_ENTRY(KBearerPresent, CoreNetStates::TStartServiceProviderRetry, CoreNetStates::TAwaitingStarted, MeshMachine::TNoTagOrErrorTag)
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing)
+ //Start data clients, use the default cancellation.
+ //Forward TCancel to the self, wait for TCFDataClient::TStarted or TError (via the Error Activity)
+ //When TCFDataClient::TStarted arrives after TCancel the activity will move to the nearest KErrorTag
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStartSelf, CoreNetStates::TAwaitingDataClientStarted, MeshMachine::TNoTagOrErrorTag)
+ NODEACTIVITY_ENTRY(KErrorTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TErrorTag)
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TRaiseAndClearActivityError)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendStarted)
+NODEACTIVITY_END()
+}
+
+namespace PRStopActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStop, PRStop, TCFServiceProvider::TStop, MeshMachine::CNodeRetryActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingStop, TActiveOrNoTagBlockedByBindTo)
+ THROUGH_NODEACTIVITY_ENTRY(KActiveTag, CoreNetStates::TCancelDataClientStart, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, CoreNetStates::TNoTagOrNoBearer)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendStop, CoreNetStates::TAwaitingStopped, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingRequestToServiceProvider, MeshMachine::TAwaitingLeaveComplete, TTag<CoreNetStates::KNoBearer>)
+ LAST_NODEACTIVITY_ENTRY(CoreNetStates::KNoBearer, PRStates::TSendStoppedAndGoneDown)
+NODEACTIVITY_END()
+}
+
+namespace PRDataClientStartActivity
+{
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityStartDataClient, PRDataClientStart, TCFDataClient::TStart)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientStart, CoreNetStates::TNoTagOrNoDataClients)
+ NODEACTIVITY_ENTRY(KNoTag, PRStates::TStartDataClients, TAcceptErrorState<CoreNetStates::TAwaitingDataClientsStarted>, MeshMachine::TErrorTagOr<MeshMachine::TTag<CoreNetStates::KNoDataClients> >)
+ LAST_NODEACTIVITY_ENTRY(CoreNetStates::KNoDataClients, PRStates::TSendDataClientStarted)
+
+ NODEACTIVITY_ENTRY(KErrorTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientsStopped, MeshMachine::TErrorTag)
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TRaiseAndClearActivityError)
+NODEACTIVITY_END()
+}
+
+namespace PRDataClientStopActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStopDataClient, PRDataClientStop, TCFDataClient::TStop, MeshMachine::CNodeRetryActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientStop, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, PRStates::TProcessDataClientStop, CoreNetStates::TNoTagOrDataClientsToStopBlockedByStarting)
+
+ NODEACTIVITY_ENTRY(CoreNetStates::KDataClientsToStop, CoreNetStates::TStopDataClients, CoreNetStates::TAwaitingDataClientsStopped, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, CoreNetStates::TNoTagOrUnbindOnStop)
+
+ NODEACTIVITY_ENTRY(CoreNetStates::KUnbind, CoreNetStates::TSendClientLeavingRequestToServiceProvider, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, PRStates::TDestroyOrphanedDataClients, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TSendDataClientStopped)
+NODEACTIVITY_END()
+}
+
+
+namespace PRForwardStateChangeActivity
+{
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityForwardStateChange, PRForwardStateChange, TCFMessage::TStateChange)
+ NODEACTIVITY_ENTRY(KNoTag, PRStates::TForwardStateChange, MeshMachine::TAwaitingMessageState<TCFMessage::TStateChange>, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace PRDataClientStatusChangeActivity
+{
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityDataClientStatusChange, PRDataClientStatusChange, TCFControlProvider::TDataClientStatusChange)
+ NODEACTIVITY_ENTRY(KNoTag, PRStates::THandleDataClientStatusChangeAndDestroyOrphans, CoreNetStates::TAwaitingDataClientStatusChange, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace PRGoneDownActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityGoneDown, PRGoneDown, TCFControlClient::TGoneDown, CGoneDownActivity::NewL)
+ // Our Service Provider has gone down unexpectedly (we haven't issued a TStop)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingGoneDown, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TCancelAndCloseZone0ClientExtIfaces, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingRequestToServiceProvider, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CGoneDownActivity::TSendErrorRecoveryReq, MeshMachine::TAwaitingErrorRecoveryResponseOrError, CoreStates::TRetryOrIgnoreOrPropagate)
+ THROUGH_NODEACTIVITY_ENTRY(CoreStates::KRetry, MeshMachine::TDoNothing, CGoneDownActivity::TIgnoreOrPropagate)
+ LAST_NODEACTIVITY_ENTRY(CoreStates::KIgnore, MeshMachine::TDoNothing)
+ NODEACTIVITY_ENTRY(CoreStates::KPropagate, CoreNetStates::TCancelStartAndStopSelf, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TSendGoneDown)
+NODEACTIVITY_END()
+}
+
+
+namespace PRGoneUpActivity
+{
+// This Activity forward the TGoneUp event to the Control Clients nodes that are
+// not in the originator lis
+
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityGoneUp, PRGoneUp, TCFControlClient::TGoneUp)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingGoneUp, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendGoneUp)
+NODEACTIVITY_END()
+}
+
+namespace PRLegacyRMessage2HandlerActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityLegacyRMessage2Handler, PRLegacyRMessage2Handler, TNodeSignal::TNullMessageId, MeshMachine::CNodeParallelMessageStoreActivityBase::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingLegacyRMessage2Ext, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TProcessOrForwardRMessage2Ext, CoreNetStates::TAwaitingRMessage2Processed, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CoreStates::TPostToOriginators)
+NODEACTIVITY_END()
+}
+
+
+namespace CoreActivities
+{
+DECLARE_DEFINE_ACTIVITY_MAP(coreActivitiesAll)
+ ACTIVITY_MAP_ENTRY(CoreErrorActivity, CoreError) //Must be first in the table
+ACTIVITY_MAP_END()
+
+//-=========================================================
+//
+//Error Activity
+//
+//-=========================================================
+MeshMachine::CNodeActivityBase* CErrorActivity::NewL( const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode )
+ {
+ TUint c = GetNextActivityCountL(aActivitySig,aNode);
+ return new(ELeave)CErrorActivity(aActivitySig, aNode, c);
+ }
+
+CErrorActivity::CErrorActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TUint aActivitiesCount)
+ : MeshMachine::CNodeParallelActivityBase(aActivitySig, aNode, aActivitiesCount), iErroredActivityId(MeshMachine::KActivityNull)
+ {
+ }
+
+CErrorActivity::~CErrorActivity()
+ {
+ if (Error() != KErrNone)
+ {
+ CNodeActivityBase* a = iNode.FindActivityById(iErroredActivityId);
+ if (a)
+ {
+ a->SetError(Error());
+ a->SetIdle();
+ }
+ }
+ SetError(KErrNone);
+ }
+
+TBool CErrorActivity::IsIdle() const
+ {
+ return NetStateMachine::ACore::IsIdle();
+ }
+
+void CErrorActivity::StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& /*aOriginator*/, const TStateTriple& aFirst)
+ {
+ __ASSERT_DEBUG(IsIdle(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 1));
+ MESH_LOG_ACTIVITY_EXT(KESockMeshMachine, this, &aContext, (_L8("CErrorActivity %08x:\tStartL->starting activity"), this));
+
+ NetStateMachine::ACore::Start(&aContext, aFirst);
+
+ MESH_LOG_ACTIVITY_EXT(KESockMeshMachine, this, &aContext, (_L8("CErrorActivity %08x:\tStartL->activity started"),this));
+ }
+
+TBool CErrorActivity::Next(TNodeContextBase& aContext)
+ {
+ TBool ret = EFalse;
+
+
+ if (aContext.iMessage.IsMessage<TEBase::TCancel>())
+ {
+ CNodeActivityBase* a = iNode.FindActivityById(iErroredActivityId);
+ //Special handling for TCancel.
+ if (a && a->FindOriginator(aContext.iSender) != KErrNotFound)
+ {
+ ret = ETrue;
+ //iActiviy could have handled it, but chose not to.
+ Cancel(aContext);
+ //consume the message, otherwise the iActivity will get idled and iActivity reference
+ //will become invalid.
+ aContext.iMessage.ClearMessageId();
+ }
+ }
+ else
+ {
+ //If we have sent TErrorRecoveryRequest, we had to have set PostedToId() to the recipient (ControlProvider)
+ //as otherwise there would be no path for propagating the potential TCancel.
+ //The response however (TErrorRecoveryResponse or TError) will not necesserily come from that recipient (CP)
+ //(for example it could be coming from the MCpr and we could be the SCpr).
+ //Normally this would be a problem because any unrelated TError message arriving to the node
+ //and presented to the awaiting state would easily be confused with the response (TError == no recovery on the MCpr == EPropagate).
+ //We avoid the problem by checking all arriving messages if they are adressed to our activity (but we don't
+ //check the sender.
+ const TNodeCtxId* recipient = address_cast<const TNodeCtxId>(&aContext.iRecipient);
+ if (recipient && (ActivityId() == recipient->NodeCtx()))
+ {
+ ret = ACore::Next(&aContext);
+ if(ret)
+ {
+ MESH_LOG_ACTIVITY_EXT(KMeshMachineSubTag, this, &aContext, (_L8("CNodeActivityBase %08x:\tNext->transition"), this));
+ }
+ }
+ }
+ return ret;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CErrorActivity::TAwaitingError, NetStateMachine::MState, CErrorActivity::TContext)
+EXPORT_C TBool CErrorActivity::TAwaitingError::Accept()
+ {
+ if (! iContext.iMessage.IsMessage<TEBase::TError>())
+ {
+ return EFalse;
+ }
+
+ TEBase::TError& errorMessage = message_cast<TEBase::TError>(iContext.iMessage);
+
+ //Diagnostic panic only. TError message should not be travelling around with KErrNone.
+ //If you see this panic, please send a proper error code.
+ __ASSERT_DEBUG(errorMessage.iValue != KErrNone, User::Panic(KSpecAssert_ESockCrStaCPRAC, 2));
+
+ MeshMachine::CNodeActivityBase* aa = iContext.Node().FindAddressedActivity(iContext);
+
+ //TError is always a response. If there is no activity addressed by the TError,
+ //then we assume the activity hasn't bothered waiting for the result.
+ //We hence ignore the error.
+ if (aa)
+ {
+ aa->SetError(errorMessage.iValue);
+ aa->SetIdle();
+ }
+ errorMessage.ClearMessageId();
+ return EFalse;
+ }
+
+DEFINE_SMELEMENT(CErrorActivity::TCFAwaitingError, NetStateMachine::MState, CErrorActivity::TContext)
+EXPORT_C TBool CErrorActivity::TCFAwaitingError::Accept()
+ {
+ if (! iContext.iMessage.IsMessage<TEBase::TError>())
+ {
+ return EFalse;
+ }
+
+ TEBase::TError& errorMessage = message_cast<TEBase::TError>(iContext.iMessage);
+
+ //Diagnostic panic only. TError message should not be travelling around with KErrNone.
+ //If you see this panic, please send a proper error code.
+ __ASSERT_DEBUG(errorMessage.iValue != KErrNone, User::Panic(KSpecAssert_ESockCrStaCPRAC, 3));
+
+ RNodeInterface* client = iContext.Node().FindClient(iContext.iSender);
+ if (client &&
+ client->Type() & TCFClientType::EServProvider &&
+ iContext.Node().ControlProvider() != NULL &&
+ iContext.Node().CountActivities(ECFActivityDestroy) == 0)
+ {
+ //this is the only way out into the activity and into error recovery steps
+ //that error activity is responsible for doing.
+ return ETrue;
+ }
+
+ return CErrorActivity::TAwaitingError::Accept();
+ }
+
+//Simply leaving from this DoL will NOT have the effect of sending TError to originators
+//of the Errored activity! iContext.iNodeActivity is the Error activity.
+//Reassign iContext.iNodeActivity before leaving or handle the error.
+EXPORT_DEFINE_SMELEMENT(CErrorActivity::TSendErrorRecoveryReq, NetStateMachine::MStateTransition, CErrorActivity::TContext)
+EXPORT_C void CErrorActivity::TSendErrorRecoveryReq::DoL()
+ {
+ //Find matching activity, if any
+ MeshMachine::CNodeActivityBase* aa = iContext.Node().FindAddressedActivity(iContext);
+ //we are started based on the fact the the last message iContext.Node()'s received is TError
+ TEBase::TError& errmsg = message_cast<TEBase::TError>(iContext.iMessage);
+
+ //The error comes from someone else than our Data Client (or we wouldn't be here).
+ //It may be our Service Provider or it can be some other node which has originated
+ //an activity on us (in which case the errored activity must be present).
+ if (aa==NULL)
+ {
+ __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ASendErrorRecoveryReq::DoL - TError but no addressed activity - ignoring")));
+#ifdef SYMBIAN_NETWORKING_UPS
+ // Terminate the error activity (not UPS specific).
+ iContext.iNodeActivity->SetIdle();
+#endif //SYMBIAN_NETWORKING_UPS
+ return;
+ }
+
+ AContextStore* intf = NULL;
+ if (aa->SupportsExtInterface(AContextStore::KInterfaceId))
+ {
+ //FetchExtInterfaceL below can never leave because it is being checked few lines above in the "if"
+ intf = reinterpret_cast<AContextStore*>(aa->FetchExtInterfaceL(AContextStore::KInterfaceId));
+ }
+
+ //Check if there is any point in sending Error Recovery Request
+ if (intf==NULL || !intf->IsStored() || !iContext.Node().ControlProvider())
+ {
+ __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ERROR: ASendErrorRecoveryReq::DoL - KErrNotSupported")));
+ iContext.iNodeActivity->SetIdle();
+ aa->SetError(errmsg.iValue);
+ aa->SetIdle();
+ return;
+ }
+
+ //Determine who TErrorRecoveryRequest should be sent to.
+ //If there is no ControlProvider we send a RecoveryRequest to ourselves to recover from the error,
+ //otherwise we sned the RecoveryRequest up to our ControlProvider.
+ //MCPrs typically put all of the error recovery function in a single error recovery activity therefore
+ //it makes sense even for MCPrs to send TErrorRecoveryRequest to their error recovery function. By
+ //posting a TErrorRecoveryRequest sub-classes of the MCPrs get a chance to override the default error
+ //recovery.
+ RNodeInterface* errorRecoverer = iContext.Node().ControlProvider() ? iContext.Node().ControlProvider() : &iContext.Node().SelfInterface();
+
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CoreActivities::CErrorActivity& activity = static_cast<CoreActivities::CErrorActivity&>(*iContext.iNodeActivity);
+ __ASSERT_DEBUG(activity.iErroredActivityId==MeshMachine::KActivityNull, User::Panic(KSpecAssert_ESockCrStaCPRAC, 4));
+ // Save a reference to the activity and a point
+ // Each time we use the activity, query it from the node, because the activity may have gone away (originator left node etc)
+ activity.iErroredActivityId = aa->ActivityId();
+
+ activity.SetError(errmsg.iValue);
+ activity.iMessageId = errmsg.iMsgId;
+
+ TErrContext ctx(iContext.NodeId(), errmsg.iMsgId, aa->ActivitySigId(), TStateChange(0, errmsg.iValue));
+ TEErrorRecovery::TErrorRecoveryRequest msg(ctx);
+
+ activity.PostRequestTo(
+ *errorRecoverer,//ControlProvider() verified above
+ TCFSafeMessage::TRequestCarrierEast<TEErrorRecovery::TErrorRecoveryRequest>(msg).CRef()
+ );
+
+ //The original activiy might have set 'sent to', but that's surely
+ //not meaningful anymore (we've just received a response from that 'sent to').
+ //We could have pretended that the orginal activity knows it's sent
+ //error recovery to the control provider but it's best just to clear
+ //'sent to' (and handle TCancel from here (CErrorActivity::Next()).
+ aa->ClearPostedTo();
+ }
+
+EXPORT_DEFINE_SMELEMENT(CErrorActivity::TDoErrorRecovery, NetStateMachine::MStateTransition, CErrorActivity::TContext)
+EXPORT_C void CErrorActivity::TDoErrorRecovery::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CoreActivities::CErrorActivity* act = static_cast<CoreActivities::CErrorActivity*>(iContext.iNodeActivity);
+ CNodeActivityBase* a = iContext.Node().FindActivityById(act->iErroredActivityId);
+ if (a == NULL)
+ {
+ iContext.iNodeActivity->SetIdle();
+ return;
+ }
+
+ if (iContext.iMessage.IsMessage<TEErrorRecovery::TErrorRecoveryResponse>())
+ {
+ TErrResponse& resp = message_cast<TEErrorRecovery::TErrorRecoveryResponse>(iContext.iMessage).iErrResponse;
+ if (resp.iAction == TErrResponse::ERetry)
+ { //rerun current transition
+ __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ADoErrorRecovery::DoL - instructed to retry")));
+ __ASSERT_DEBUG(a->SupportsExtInterface(AContextStore::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+
+ AContextStore* intf = reinterpret_cast<AContextStore*>(a->FetchExtInterfaceL(AContextStore::KInterfaceId));
+ __ASSERT_DEBUG(intf->IsStored(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 5));
+ intf->Retry(*a,iContext);
+ if (iContext.iReturn == KErrNone)
+ { //retry succeded
+ act->SetError(KErrNone);
+ }
+ //if Retry had failed, then the d'tor of act will raise the error on
+ //and terminate act->iActivity,
+ }
+ else if (resp.iAction == TErrResponse::EPropagate)
+ { //set new error values and fall through
+ __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ADoErrorRecovery::DoL - instructed to propagate the error")));
+ act->iMessageId = resp.iMessageId;
+ a->SetError(resp.iError);
+ }
+ else //if (resp.iAction == TErrResponse::EIgnore)
+ {
+ __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag,
+ _L8("WARNING: ADoErrorRecovery::DoL() - instructed to ignore the error!")));
+ }
+ }
+ }
+
+
+//-=========================================================
+//
+//Destroy Activity - will delete the node when destructed
+//
+//-=========================================================
+
+EXPORT_C MeshMachine::CNodeActivityBase* CDestroyActivity::New(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ TAny* space = BorrowPreallocatedSpace(aNode, sizeof(CDestroyActivity));
+ CDestroyActivity* self = new (space) CDestroyActivity(aActivitySig, aNode);
+ self->InsertPreallocatedDestroyActivity(); //Destructing preallocated activity
+ return self;
+ }
+
+CDestroyActivity::CDestroyActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+: CNodeRetryActivity(aActivitySig, aNode),
+ APreallocatedOriginators<1>(iOriginators)
+ {
+ //Mark the provider for deletion, so that it's not served by the factory from now on.
+ static_cast<ESock::CMMCommsProviderBase&>(iNode).MarkMeForDeletion();
+ }
+
+void CDestroyActivity::Destroy()
+ {
+ ReturnPreallocatedSpace(this);
+ this->~CDestroyActivity(); //Run the destructor
+
+ //Delete the provider.
+ static_cast<ESock::CMMCommsProviderBase&>(iNode).DeleteMeNow();
+ }
+
+TBool CDestroyActivity::Next(TNodeContextBase& aContext)
+ {
+ if (aContext.iMessage.IsMessage<TEBase::TCancel>())
+ {
+ return ETrue;
+ }
+ else
+ return CNodeActivityBase::Next(aContext);
+ }
+
+EXPORT_DEFINE_SMELEMENT(CDestroyActivity::TNoTagOrNoTagBackwards, NetStateMachine::MStateFork, PRStates::TContext)
+EXPORT_C TInt CDestroyActivity::TNoTagOrNoTagBackwards::TransitionTag()
+ {
+ if (iContext.iMessage.IsMessage<TEChild::TLeft>())
+ {
+ TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData|TCFClientType::ECtrl));
+ __ASSERT_DEBUG(iter[0], User::Panic(KSpecAssert_ESockCrStaCPRAC, 7)); //One leaving client must still be there.
+ return iter[1] == NULL ? MeshMachine::KNoTag : MeshMachine::KNoTag | NetStateMachine::EBackward;
+ }
+ else if (iContext.iMessage.IsMessage<TEPeer::TLeaveComplete>())
+ {
+ __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl|TCFClientType::EData))==NULL,
+ User::Panic(KCorePrPanic, KPanicClientsStillPresent));
+ if (iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider))==NULL)
+ {
+ return NetStateMachine::EForward | MeshMachine::KNoTag;
+ }
+ return NetStateMachine::EBackward | MeshMachine::KNoTag; //Loop back to the same triple (& remove the peer)
+ }
+ __ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockCrStaCPRAC, 8));
+ return KNoTag;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave, NetStateMachine::MStateTransition, PRStates::TContext)
+EXPORT_C void CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave::DoL()
+ {
+ if (iContext.iMessage.IsMessage<TEChild::TLeft>())
+ {
+ ProcessClientLeaveL();
+ }
+ else
+ {
+ MakeClientsLeaveL();
+ }
+ }
+
+void CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave::MakeClientsLeaveL()
+ {
+ __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl))==NULL,
+ User::Panic(KCorePrPanic, KPanicClientsStillPresent));
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ iContext.iNodeActivity->ClearPostedTo();
+
+ //MZTODO: this asserion may need to be changed since TDestroy can
+ //come while data client is active etc.
+ __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EActive|TCFClientType::EActivating|TCFClientType::EStarting|TCFClientType::EStarted))==NULL,
+ User::Panic(KCorePrPanic, KPanicClientsStillPresent));
+
+ TClientIter<TDefaultClientMatchPolicy> dciter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData), TClientType(0, TCFClientType::ELeaving));
+ RNodeInterface* dc = NULL;
+ while ((dc = dciter[0]) != NULL) //always inspect the first elem as we're invalidating the iterator with each hit.
+ {
+ dc->PostMessage(iContext.NodeId(), TEChild::TDestroy().CRef());
+ dc->SetFlags(TCFClientType::ELeaving);
+ }
+ }
+
+void CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave::ProcessClientLeaveL()
+ {
+ CDestroyActivity::TProcessClientLeave processClientLeave(iContext);
+ processClientLeave.DoL();
+ }
+
+
+//-=========================================================
+//
+//Loppin Activity
+//
+//-=========================================================
+EXPORT_C ACountLoopActivity::~ACountLoopActivity()
+ {
+ }
+
+
+EXPORT_C MeshMachine::CNodeActivityBase* CCountLoopActivityBase::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ return new (ELeave) CCountLoopActivityBase(aActivitySig, aNode);
+ }
+
+EXPORT_C CCountLoopActivityBase::CCountLoopActivityBase(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+: MeshMachine::CNodeActivityBase(aActivitySig, aNode),
+ TIfStaticFetcherNearestInHierarchy(this)
+ {
+ }
+
+EXPORT_C CCountLoopActivityBase::~CCountLoopActivityBase()
+ {
+ }
+
+EXPORT_DEFINE_SMELEMENT(ACountLoopActivity::TNoTagOrNoTagBackwards, NetStateMachine::MStateFork, PRStates::TContext)
+EXPORT_C TInt ACountLoopActivity::TNoTagOrNoTagBackwards::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(ACountLoopActivity::KInterfaceId),User::Panic(KCorePrPanic, KPanicInterfaceNotSupported));
+ ACountLoopActivity* countLoopActivity = static_cast<ACountLoopActivity*>(iContext.iNodeActivity->FetchExtInterface(ACountLoopActivity::KInterfaceId));
+ if (countLoopActivity->DecCount() > 0)
+ {
+ return KNoTag | NetStateMachine::EBackward;
+ }
+ return KNoTag | NetStateMachine::EForward;
+ }
+
+
+
+
+
+//-=========================================================
+//
+//
+//Binding Activity
+//
+//
+//-=========================================================
+EXPORT_C ABindingActivity::~ABindingActivity()
+ {
+ //Handle premature termination of the ABindingActivity object
+ //by responding to the originator
+ //If the originator has not been replied to yet, reply now with an error code
+ if (IsBinding())
+ {
+ ReplyToOriginator(KErrAbort);
+ }
+ }
+
+EXPORT_C void ABindingActivity::StoreOriginator(const TRuntimeCtxId& aNodeCtxId)
+ {
+ //Check if the originator wasn't set before. If it was, it must be replied to before storing ths new one.
+ __ASSERT_DEBUG(iOriginator.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 9));
+ iOriginator = aNodeCtxId;
+ }
+
+EXPORT_C void ABindingActivity::ReplyToOriginator(TInt aError)
+ {
+ //NOTE: Please do not make this diagnostic panic conditional.
+ //Please allow it to server everyone equally.
+ //Please handle the error conditions properly so that you obey this API's semantics.
+ //If you are not providing a clean error handling solution for your activity,
+ //please use IsBinding() before calling this API!
+ __ASSERT_DEBUG(!iOriginator.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 10)); //The iOriginator must be set.
+ RClientInterface::OpenPostMessageClose(iOurNode, iOriginator, TCFDataClient::TBindToComplete(aError).CRef());
+ iOriginator.SetNull();
+ }
+
+EXPORT_DEFINE_SMELEMENT(ABindingActivity::TSendBindToComplete, NetStateMachine::MStateTransition, CoreStates::TContext)
+EXPORT_C void ABindingActivity::TSendBindToComplete::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(ABindingActivity::KInterfaceId), User::Panic(KSpecAssert_ESockCrStaCPRAC, 11));
+ ABindingActivity* bindingActivity = reinterpret_cast<ABindingActivity*>(iContext.iNodeActivity->FetchExtInterfaceL(ABindingActivity::KInterfaceId));
+ bindingActivity->ReplyToOriginator(iContext.iNodeActivity->Error());
+ }
+
+EXPORT_DEFINE_SMELEMENT(ABindingActivity::TSendBindToCompleteIfExpected, NetStateMachine::MStateTransition, CoreStates::TContext)
+EXPORT_C void ABindingActivity::TSendBindToCompleteIfExpected::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(ABindingActivity::KInterfaceId), User::Panic(KSpecAssert_ESockCrStaCPRAC, 12));
+ ABindingActivity* bindingActivity = reinterpret_cast<ABindingActivity*>(iContext.iNodeActivity->FetchExtInterfaceL(ABindingActivity::KInterfaceId));
+ if (bindingActivity->IsBinding())
+ {
+ bindingActivity->ReplyToOriginator(iContext.iNodeActivity->Error());
+ }
+ }
+
+void ABindingActivity::FinalReplyToOriginator(TInt aError)
+/**
+Intended to be called from derived class destructors to arrange for a TBindToComplete reply to be sent
+before any other messages in those derived class destructors (for example TDestroy).
+*/
+ {
+ if (IsBinding())
+ {
+ ReplyToOriginator(aError);
+ // Ensure that we don't send another reply in ~ABindingActivity.
+ iOriginator = Messages::TNodeCtxId();
+ }
+ }
+
+} // CoreActivities
+
+
+namespace PRActivities
+{
+DECLARE_DEFINE_ACTIVITY_MAP(coreActivitiesPR)
+ ACTIVITY_MAP_ENTRY(PRDataClientJoinActivity, PRDataClientJoin)
+ ACTIVITY_MAP_ENTRY(PRControlClientJoinActivity, PRControlClientJoin)
+ ACTIVITY_MAP_ENTRY(PRClientLeaveActivity, PRClientLeave)
+ ACTIVITY_MAP_ENTRY(PRForwardStateChangeActivity, PRForwardStateChange)
+ ACTIVITY_MAP_ENTRY(PRBindToActivity, PRBindTo)
+ ACTIVITY_MAP_ENTRY(PRDataClientStartActivity, PRDataClientStart)
+ ACTIVITY_MAP_ENTRY(PRDataClientStopActivity, PRDataClientStop)
+ACTIVITY_MAP_END_BASE(CoreActivities,coreActivitiesAll)
+
+//Activity Map provided by CorePr to be used by SCprs.
+//(it is further extended in CoreSCpr).
+DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesSCpr)
+ ACTIVITY_MAP_ENTRY(PRProvisionActivity, PrProvision)
+ ACTIVITY_MAP_ENTRY(PRStartActivity, PRStart)
+ ACTIVITY_MAP_ENTRY(PRStopActivity, PRStop)
+ ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle)
+ ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive)
+ ACTIVITY_MAP_ENTRY(PRDestroyActivity, PRDestroy)
+ ACTIVITY_MAP_ENTRY(PRGoneDownActivity, PRGoneDown)
+ ACTIVITY_MAP_ENTRY(PRGoneUpActivity, PRGoneUp) //robertomaro
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+ ACTIVITY_MAP_ENTRY(PRSetParamsRequest, PRSetParams)
+ ACTIVITY_MAP_ENTRY(PRGetParamsRequest, PRGetParams)
+#endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+ ACTIVITY_MAP_ENTRY(PRLegacyRMessage2HandlerActivity, PRLegacyRMessage2Handler)
+ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
+
+//Activity Map provided by CorePr to be used by Cprs.
+//(it is further extended in CoreCpr).
+DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesCpr)
+ ACTIVITY_MAP_ENTRY(PRProvisionActivity, PrProvision)
+ ACTIVITY_MAP_ENTRY(PRStartActivity, PRStart)
+ ACTIVITY_MAP_ENTRY(PRStopActivity, PRStop)
+ ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle)
+ ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive)
+ ACTIVITY_MAP_ENTRY(PRDestroyActivity, PRDestroy)
+ ACTIVITY_MAP_ENTRY(PRGoneDownActivity, PRGoneDown)
+ ACTIVITY_MAP_ENTRY(PRGoneUpActivity, PRGoneUp) //robertomaro
+ ACTIVITY_MAP_ENTRY(PRDataClientStatusChangeActivity, PRDataClientStatusChange)
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+ ACTIVITY_MAP_ENTRY(PRSetParamsRequest, PRSetParams)
+ ACTIVITY_MAP_ENTRY(PRGetParamsRequest, PRGetParams)
+#endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+ ACTIVITY_MAP_ENTRY(PRLegacyRMessage2HandlerActivity, PRLegacyRMessage2Handler)
+ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
+
+//Activity Map provided by CorePr to be used by MCprs.
+//(it is further extended in CoreMCpr).
+DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesMCpr)
+ ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle)
+ ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive)
+ ACTIVITY_MAP_ENTRY(PRDataClientStatusChangeActivity, PRDataClientStatusChange)
+ ACTIVITY_MAP_ENTRY(PRLegacyRMessage2HandlerActivity, PRLegacyRMessage2Handler)
+ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
+
+//Activity Map provided by CorePr to be used by TMs.
+//(it is further extended in CoreTM).
+DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesTM)
+ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
+
+
+
+
+//-=========================================================
+//
+//CBindToActivity
+//
+//-=========================================================
+EXPORT_C CBindToActivity::CBindToActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TInt aNextActivityCount)
+ : MeshMachine::CNodeParallelActivityBase(aActivitySig, aNode, aNextActivityCount),
+ CoreActivities::ABindingActivity(aNode.Id()),
+ TIfStaticFetcherNearestInHierarchy(this)
+ {
+ }
+
+EXPORT_C MeshMachine::CNodeActivityBase* CBindToActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ //there can be only one BindTo activity running at a time.
+ TUint c = GetNextActivityCountL(aActivitySig,aNode);
+ __ASSERT_DEBUG(c == 1,User::Panic(KCorePrPanic, KPanicPeerMisbehaving));
+ if (c > 1)
+ {
+ User::Leave(KErrInUse);
+ }
+ return new (ELeave) CBindToActivity(aActivitySig, aNode, c);
+ }
+
+EXPORT_C CBindToActivity::~CBindToActivity()
+ {
+ //If the activity is aborted then no cleanup will be performed (the destroy activity will do
+ //that for us) so we should not assert that iSuccessfulDataClients is empty or iNewServiceProvider
+ //is null.
+
+ //CBindToActivity::TCommit or CBindToActivity::TCancel should have been executed
+ //and rendered iSuccessfulDataClients empty.
+ //__ASSERT_DEBUG(iSuccessfulDataClients.Count() == 0, User::Panic(KCorePrPanic, KPanicIncorrectState));
+
+ //CBindToActivity::iNewServiceProvider should have been cleared by CBindToActivity::TCommit or CBindToActivity::TCancel
+ //__ASSERT_DEBUG(iNewServiceProvider == NULL, User::Panic(KCorePrPanic, KPanicIncorrectState));
+
+ iSuccessfulDataClients.Close();
+ }
+
+Messages::RNodeInterface* CBindToActivity::NextDataClient()
+ {
+ TClientIter<TDefaultClientMatchPolicy> iter = iNode.GetClientIter<TDefaultClientMatchPolicy>(
+ /*include*/TClientType(TCFClientType::EData),
+ /*exclude*/TClientType(0, TCFClientType::ELeaving | TCFClientType::EConfigAccessPoint));
+ iCurrentDataClient = iter++;
+ while (iCurrentDataClient && (iSuccessfulDataClients.Find(iCurrentDataClient) != KErrNotFound))
+ {
+ iCurrentDataClient = iter++;
+ };
+ return iCurrentDataClient;
+ }
+
+TBool CBindToActivity::DataClientsAutocommit()
+ {
+ TInt nonLeavingDataClients = iNode.CountClients<TDefaultClientMatchPolicy>(
+ /*include*/TClientType(TCFClientType::EData),
+ /*exclude*/TClientType(0, TCFClientType::ELeaving | TCFClientType::EConfigAccessPoint));
+ return nonLeavingDataClients <=1 && IsAutocommit();
+ }
+
+
+void CBindToActivity::AddClientAsSuccessfulL(Messages::RNodeInterface* aDataClient)
+ {
+ __ASSERT_DEBUG(aDataClient, User::Panic(KCorePrPanic, KPanicDataClient));
+ __ASSERT_DEBUG(iSuccessfulDataClients.Find(aDataClient) == KErrNotFound, User::Panic(KCorePrPanic, KPanicIncorrectState));
+ iSuccessfulDataClients.Append(aDataClient);
+ }
+
+void CBindToActivity::RemoveClientFromSuccessful(Messages::RNodeInterface* aDataClient)
+ {
+ TInt index = iSuccessfulDataClients.Find(aDataClient);
+ __ASSERT_DEBUG(index >= 0, User::Panic(KCorePrPanic, KPanicDataClient));
+ iSuccessfulDataClients.Remove(index);
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TSendControlClientJoinRequest, NetStateMachine::MStateTransition, CBindToActivity::TContext)
+void CBindToActivity::TSendControlClientJoinRequest::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+ const TCFDataClient::TBindTo& bindToMsg(message_cast<const TCFDataClient::TBindTo>(iContext.iMessage));
+
+ __ASSERT_DEBUG(!bindToMsg.iNodeId.IsNull(), User::Panic(KCorePrPanic, KPanicNoServiceProvider));
+ RNodeInterface* newServiceProvider = iContext.Node().AddClientL(bindToMsg.iNodeId,
+ TClientType(TCFClientType::EServProvider, TCFClientType::EActivating));
+ __ASSERT_DEBUG(newServiceProvider, User::Panic(KCorePrPanic, KPanicNoServiceProvider));
+ activity.iNewServiceProvider = bindToMsg.iNodeId;
+ //Join the new service provider
+ iContext.Activity()->PostRequestTo(*newServiceProvider,
+ TCFControlClient::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::ECtrl)).CRef());
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TAwaitingBindToCompleteOrError, NetStateMachine::MState, CRejoinDataClientActivity::TContext)
+TBool CBindToActivity::TAwaitingBindToCompleteOrError::Accept()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+ if (CoreNetStates::TAwaitingBindToComplete(iContext).Accept())
+ {
+ if (activity.IsBinding())
+ {
+ //Activity is binding (i.e.: we havent received TBindToComplete as a response
+ //to null-carrying TBindTo.
+ activity.ReplyToOriginator(KErrNone);
+ }
+ activity.ResetCurrentDataClient();
+ return ETrue;
+ }
+ else if (iContext.iMessage.IsMessage<TEBase::TError>())
+ {
+ activity.ReplyToOriginator(message_cast<TEBase::TError>(iContext.iMessage).iValue);
+ activity.RemoveClientFromSuccessful(activity.CurrentDataClient());
+ activity.ResetCurrentDataClient();
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrDataClientReady, NetStateMachine::MStateFork, CBindToActivity::TContext)
+TInt CBindToActivity::TNoTagOrDataClientReady::TransitionTag()
+ {
+ //Any non-leaving dataclients already present?
+ if (iContext.Node().CountClients<TDefaultClientMatchPolicy>(
+ /*include*/TClientType(TCFClientType::EData),
+ /*exclude*/TClientType(0, TCFClientType::ELeaving | TCFClientType::EConfigAccessPoint)))
+ {
+ return KDataClientReady;
+ }
+ return KNoTag;
+ }
+
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TRequestCommsBinder, NetStateMachine::MStateTransition, CBindToActivity::TContext)
+void CBindToActivity::TRequestCommsBinder::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData)),User::Panic(KCorePrPanic, KPanicDataClient));
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+
+ //The service provider has been joined already and must be found here
+ __ASSERT_DEBUG(!activity.iNewServiceProvider.IsNull(), User::Panic(KCorePrPanic, KPanicNoServiceProvider));
+ RNodeInterface* newServiceProvider = iContext.Node().FindClient(activity.iNewServiceProvider);
+ __ASSERT_DEBUG(newServiceProvider, User::Panic(KCorePrPanic, KPanicNoServiceProvider));
+ //We must not be in this transition if dc was not found
+ __ASSERT_DEBUG(activity.CurrentDataClient(), User::Panic(KCorePrPanic, KPanicDataClient));
+
+ // Also if it is not so common to have multiple DataClient (except
+ // for the relation "SCPR<-CPR"), there are situation where it happens
+ // and where only one of them is marked as Default.
+ // So, we check if this is the case and, in case the
+ // Originator of this activity is NOT a Default one, send ECreateNew.
+
+ // If the Current DC is marked as Default, we ask to the lower layer
+ // to "AttachToDefault". If it is not, we ask "CreateNew".
+ TInt subConnOpenType = (activity.CurrentDataClient()->Flags() & TCFClientType::EDefault) ?
+ TSubConnOpen::EAttachToDefault : TSubConnOpen::ECreateNew;
+
+ // --- WORKAROUND START ---
+ // [399TODO] There are situation were we don't have any DataClient marked
+ // as Default, but, asking for ECreateNew, the lower layer doesn't
+ // manage the request very well.
+ // This is a WORKAROUND and need fixing (see DEF113154).
+ // In the meanwhile, we count the number of "DefaultDataClient" and,
+ // if the result is "0", we ask the lower layer "AttachToDefault"
+ TInt numberOfDefaultDataClient = iContext.Node().CountClients<TDefaultClientMatchPolicy>(
+ TClientType(TCFClientType::EData, TCFClientType::EDefault)
+ );
+ if (numberOfDefaultDataClient == 0)
+ {
+ subConnOpenType = TSubConnOpen::EAttachToDefault;
+ }
+ // --- WORKAROUND END ---
+
+ // Send "TCommsBinderRequest" to the Current ServiceProvider
+ activity.PostRequestTo(
+ *newServiceProvider,
+ TCFServiceProvider::TCommsBinderRequest(subConnOpenType).CRef()
+ );
+ }
+
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCreateDataClient, NetStateMachine::MStateTransition, CBindToActivity::TContext)
+void CBindToActivity::TCreateDataClient::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+
+ IssuePeerCreationRequestL ();
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TSendBindTo, NetStateMachine::MStateTransition, CBindToActivity::TContext)
+void CBindToActivity::TSendBindTo::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+
+ //Provisionally stash the current dataclient as successful. If it fails to bind, we'll unstash it
+ //We're doing this now, as stashing may fail and we don't want that to be the sole reason for
+ //unrolling.
+ bindToActivity.AddClientAsSuccessfulL(bindToActivity.CurrentDataClient());
+
+ TCFServiceProvider::TCommsBinderResponse* commsBinderResponse = message_cast<TCFServiceProvider::TCommsBinderResponse>(&iContext.iMessage);
+ Messages::TNodeId commsBinder = commsBinderResponse ? commsBinderResponse->iNodeId : Messages::TNodeId::NullId();
+
+ bindToActivity.PostRequestTo(*bindToActivity.CurrentDataClient(),
+ TCFDataClient::TBindTo(commsBinder, !bindToActivity.DataClientsAutocommit()).CRef());
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TSendBindToComplete, NetStateMachine::MStateTransition, CBindToActivity::TContext)
+void CBindToActivity::TSendBindToComplete::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ iContext.iNodeActivity->PostToOriginators(TCFDataClient::TBindToComplete().CRef());
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrCommit, NetStateMachine::MStateFork, CBindToActivity::TContext)
+TInt CBindToActivity::TNoTagOrCommit::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+ if (bindToActivity.IsAutocommit())
+ {
+ return KCommit;
+ }
+ return KNoTag;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrBindToComplete, NetStateMachine::MStateFork, CBindToActivity::TContext)
+EXPORT_C TInt CBindToActivity::TNoTagOrBindToComplete::TransitionTag()
+ {
+ TCFFactory::TPeerFoundOrCreated& dcJoined = message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage);
+
+ if (dcJoined.iNodeId.IsNull())
+ {
+ //Factory decided not to create a dataclient;
+ return KBindToComplete;
+ }
+
+ //factory created a new citizen.
+ return KNoTag;
+ }
+
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrBearerReady, NetStateMachine::MStateFork, CBindToActivity::TContext)
+TInt CBindToActivity::TNoTagOrBearerReady::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+ TCFDataClient::TBindTo& bindToReq = message_cast<TCFDataClient::TBindTo>(iContext.iMessage);
+ bindToActivity.SetAutocommit(!bindToReq.iValue);
+
+ if (bindToReq.iNodeId.IsNull())
+ //received a null service provider, the node is at the stack's bottom.
+ {
+ return KBearerReady;
+ }
+
+ RNodeInterface* sp = iContext.Node().ServiceProvider();
+ if (sp && bindToReq.iNodeId == sp->RecipientId())
+ {
+ //received the same service provider, it's already bound to.
+ bindToActivity.iNewServiceProvider = sp->RecipientId();
+ return KBearerReady;
+ }
+ RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToReq.iNodeId);
+ if (newServiceProvider)
+ {
+ __ASSERT_DEBUG(newServiceProvider->Type() == TCFClientType::EServProvider, User::Panic(KCorePrPanic, KPanicIncorrectState));
+ //Ok, we've received a TBindTo holding a service provider that we already know of and that is not
+ //our current service provider. We're going to assume this node tolerates multiple service providers (like MCPRs do).
+ //the current service provider will be swapped, but won't be dropped.
+ bindToActivity.iNewServiceProvider = bindToReq.iNodeId;
+ newServiceProvider->SetFlags(TCFClientType::EActivating);
+ bindToActivity.SetDontLeaveServiceProvider();
+ return KBearerReady;
+ }
+ else
+ {
+ bindToActivity.iNewServiceProvider = TNodeId::NullId();
+ }
+ //The node received a new service provider...
+ return KNoTag;
+ }
+
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrBearerReadyOrBindToComplete, NetStateMachine::MStateFork, CBindToActivity::TContext)
+TInt CBindToActivity::TNoTagOrBearerReadyOrBindToComplete::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+
+ if (!bindToActivity.NextDataClient())
+ {
+ //No more dataclients to bind
+ return KBindToComplete;
+ }
+
+ if (bindToActivity.iNewServiceProvider.IsNull())
+ {
+ //There is no service provider (new or old) below us.
+ return KBearerReady;
+ }
+
+ return KNoTag;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCommit, NetStateMachine::MStateTransition, CBindToActivity::TContext)
+void CBindToActivity::TCommit::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+
+ TInt count = bindToActivity.DataClientsAutocommit() ? 0 : bindToActivity.iSuccessfulDataClients.Count();
+ while (count )
+ {
+ bindToActivity.PostRequestTo(*bindToActivity.iSuccessfulDataClients[--count], TCFDataClient::TCommitBindTo().CRef());
+ };
+ bindToActivity.iSuccessfulDataClients.Reset();
+ RNodeInterface* sp = iContext.Node().ServiceProvider();
+
+ if (sp && sp->RecipientId() != bindToActivity.iNewServiceProvider)
+ {
+ if (bindToActivity.ShouldLeaveServiceProvider())
+ {
+ bindToActivity.PostRequestTo(*sp, TEPeer::TLeaveRequest().CRef());
+ sp->SetFlags(TCFClientType::ELeaving);
+ }
+ else
+ {
+ //Didn't leave, no need for waiting for TLeaveComplete;
+ bindToActivity.SetIdle();
+ }
+ sp->ClearFlags(TCFClientType::EActive);
+ }
+ else
+ {
+ //Didn't leave, no need for waiting for TLeaveComplete;
+ bindToActivity.SetIdle();
+ }
+
+ if (!bindToActivity.iNewServiceProvider.IsNull() && (sp == NULL || sp->RecipientId() != bindToActivity.iNewServiceProvider))
+ {
+ RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToActivity.iNewServiceProvider);
+ if (newServiceProvider)
+ {
+ __ASSERT_DEBUG(newServiceProvider->Flags() & TCFClientType::EActivating, User::Panic(KCorePrPanic, KPanicIncorrectState));
+ newServiceProvider->ClearFlags(TCFClientType::EActivating);
+ newServiceProvider->SetFlags(TCFClientType::EActive);
+ // Note: iContext.Node().ServiceProvider() must be re-evaluated in the ASSERT below (i.e. don't use any previously cached value).
+ __ASSERT_DEBUG(iContext.Node().ServiceProvider() == newServiceProvider, User::Panic(KCorePrPanic, KPanicIncorrectState));
+ }
+ }
+ bindToActivity.iNewServiceProvider = TNodeId::NullId();
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCancel, NetStateMachine::MStateTransition, CBindToActivity::TContext)
+void CBindToActivity::TCancel::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+ TInt count = bindToActivity.iSuccessfulDataClients.Count();
+ while (count )
+ {
+ bindToActivity.PostRequestTo(*bindToActivity.iSuccessfulDataClients[--count], TEBase::TCancel().CRef());
+ };
+ bindToActivity.iSuccessfulDataClients.Reset();
+
+ TBool setIdle = ETrue;
+ if (!bindToActivity.iNewServiceProvider.IsNull())
+ {
+ RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToActivity.iNewServiceProvider);
+ if (newServiceProvider && newServiceProvider != iContext.Node().ServiceProvider())
+ {
+ __ASSERT_DEBUG(newServiceProvider->Flags() & TCFClientType::EActivating, User::Panic(KCorePrPanic, KPanicIncorrectState));
+ newServiceProvider->ClearFlags(TCFClientType::EActivating);
+ if (bindToActivity.ShouldLeaveServiceProvider())
+ {
+ bindToActivity.PostRequestTo(*newServiceProvider, TEPeer::TLeaveRequest().CRef());
+ newServiceProvider->SetFlags(TCFClientType::ELeaving);
+ setIdle = EFalse;
+ }
+ }
+ }
+
+ if (setIdle)
+ {
+ bindToActivity.SetIdle();
+ }
+ bindToActivity.iNewServiceProvider = TNodeId::NullId();
+ }
+
+
+//-=========================================================
+//
+//Rejoin DataClient Activity
+//
+//-=========================================================
+EXPORT_C MeshMachine::CNodeActivityBase* CRejoinDataClientActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ TUint c = GetNextActivityCountL(aActivitySig,aNode);
+ return new(ELeave)CRejoinDataClientActivity(aActivitySig, c, aNode);
+ }
+
+CRejoinDataClientActivity::~CRejoinDataClientActivity()
+ {
+ if ( iDataClients.Count() )
+ {
+ if (Error() != KErrNone)
+ {
+ //An error has occured when processing rejoin as the activity hasn't been properly wrapped
+ //up. This error must have happened before any of the clients have been added to the new
+ //owner as such addition must either collectively succeed or collectively fail. Reinstall
+ //clients in at the current owner.
+ for (TInt i = 0; i < iDataClients.Count(); i++)
+ {
+ if (!(iDataClients[i].iDataClient.Flags() & TCFClientType::EActive))
+ {
+#ifndef __GCCXML__
+ //If the dataclient managed to report idle in the mean time, have him destroyed
+ RClientInterface::OpenPostMessageClose(iNode.Id(), iDataClients[i].iDataClient.RecipientId(), TEChild::TDestroy().CRef());
+#endif
+ }
+ iDataClients[i].iDataClient.ClearFlags(TCFClientType::EActivating);
+#ifndef __GCCXML__
+ //Simulate client leaving on the new owner.
+ RClientInterface::OpenPostMessageClose(iDataClients[i].iDataClient.RecipientId(), iDataClients[i].iNewOwner,
+ TEChild::TLeft().CRef());
+#endif
+ }
+ }
+ else
+ {
+ //All clear. Remove the clients for good.
+ for (TInt i = 0; i < iDataClients.Count(); i++)
+ {
+ iNode.RemoveClient(iDataClients[i].iDataClient.RecipientId());
+ }
+ }
+ }
+ iDataClients.Reset();
+ }
+
+
+void CRejoinDataClientActivity::TCFDataClientJoiningRequest::DispatchL(const TRuntimeCtxId& aSender, const TRuntimeCtxId& aRecipient)
+ {
+ const TNodeId& nodeId = address_cast<const TNodeId>(aRecipient); //This message type operates on nodes
+ MeshMachine::AMMNodeBase* nodeBase = reinterpret_cast<MeshMachine::AMMNodeBase*>(nodeId.Node().FetchNodeInterfaceL(AMMNodeBase::KInterfaceId));
+ RNodeInterface* client = NULL;
+ client = nodeBase->AddClientL(iDataClient, iDataClientType);
+ client->SetFlags(TCFClientType::EJoining|TCFClientType::EStarted);
+ RClientInterface::OpenPostMessageClose(nodeId, aSender, TCFPeer::TJoinComplete().CRef());
+ }
+
+
+EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TAwaitingJoinComplete, NetStateMachine::MState, CRejoinDataClientActivity::TContext)
+TBool CRejoinDataClientActivity::TAwaitingJoinComplete::Accept()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 13));
+ if (iContext.iMessage.IsMessage<TCFPeer::TJoinComplete>())
+ {
+ return ETrue;
+ }
+ else if (iContext.iMessage.IsMessage<TEBase::TError>())
+ {
+ iContext.iNodeActivity->SetError(message_cast<TEBase::TError>(iContext.iMessage).iValue);
+ iContext.iNodeActivity->SetIdle();
+ iContext.iMessage.ClearMessageId();
+ }
+ return EFalse;
+ }
+
+
+EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TRejoinDataClient, NetStateMachine::MStateTransition, CRejoinDataClientActivity::TContext)
+EXPORT_C void CRejoinDataClientActivity::TRejoinDataClient::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 14));
+ CRejoinDataClientActivity* rejoinActivity = static_cast<CRejoinDataClientActivity*>(iContext.iNodeActivity);
+
+ TCFRejoiningProvider::TRejoinDataClientRequest& rejoinDCMsg = message_cast<TCFRejoiningProvider::TRejoinDataClientRequest>(iContext.iMessage);
+ RNodeInterface* subject = iContext.Node().FindClient(rejoinDCMsg.iNodeId1);
+ if (NULL == subject //client not found
+ || subject->Flags() & TCFClientType::ELeaving //client leaving/gone
+ || !(subject->Flags() & TCFClientType::EActive)) //client reported idle or never bound to
+ {
+ User::Leave(KErrNotFound);
+ }
+ if (subject->Flags() & TCFClientType::EActivating) //client requested by someone
+ {
+ User::Leave(KErrInUse);
+ }
+
+ rejoinActivity->iDataClients.AppendL(TMigrationPairs(*subject, rejoinDCMsg.iNodeId2));
+
+ CRejoinDataClientActivity::TCFDataClientJoiningRequest msg(subject->RecipientId(), subject->ClientType());
+
+ RClientInterface::OpenPostMessageClose(
+ iContext.NodeId(),
+ rejoinDCMsg.iNodeId2,
+ msg);
+
+ //Set Client being migrated to a new owner.. reference handed over. secure lifetime.
+ subject->SetFlags(TCFClientType::EActivating);
+ }
+
+EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TApplyRejoin, NetStateMachine::MStateTransition, CRejoinDataClientActivity::TContext)
+void CRejoinDataClientActivity::TApplyRejoin::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 15));
+ CRejoinDataClientActivity* rejoinActivity = static_cast<CRejoinDataClientActivity*>(iContext.iNodeActivity);
+ __ASSERT_DEBUG(rejoinActivity->iDataClients.Count(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 16));
+ for (TInt i = 0; i < rejoinActivity->iDataClients.Count(); i++)
+ {
+ RClientInterface::OpenPostMessageClose(iContext.NodeId(), rejoinActivity->iDataClients[i].iDataClient.RecipientId(),
+ TCFFlow::TRejoin(rejoinActivity->iDataClients[i].iNewOwner).CRef());
+ rejoinActivity->iDataClients[i].iDataClient.SetFlags(TCFClientType::ELeaving);
+ }
+ rejoinActivity->PostRequestTo(iContext.NodeId(), TCFScpr::TApplyRequest().CRef());
+ }
+
+EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TRejoinLoopTag,NetStateMachine::MStateFork, CRejoinDataClientActivity::TContext)
+EXPORT_C TInt CRejoinDataClientActivity::TRejoinLoopTag::TransitionTag()
+ {
+ if (iContext.iMessage.IsMessage<TCFRejoiningProvider::TRejoinDataClientRequest>())
+ {
+ return CoreStates::KLoopTag | NetStateMachine::EBackward;
+ }
+ return MeshMachine::KNoTag | NetStateMachine::EForward;
+ }
+
+//-=========================================================
+//
+// CommsBinderActivity (parallel)
+//
+//-=========================================================
+
+EXPORT_C MeshMachine::CNodeActivityBase* CCommsBinderActivity::NewL( const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode )
+ {
+ TUint c = GetNextActivityCountL(aActivitySig,aNode);
+ return new(ELeave)CCommsBinderActivity(aActivitySig, aNode, c);
+ }
+
+EXPORT_C CCommsBinderActivity::CCommsBinderActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TUint aNextActivityCount)
+: MeshMachine::CNodeRetryParallelActivity(aActivitySig, aNode, aNextActivityCount),
+ TIfStaticFetcherNearestInHierarchy(this)
+ {
+ }
+
+//-=========================================================
+//
+// CCommsBinderActivity
+//
+// Aggregate class containing common functionality for
+// CommsBinderActivity and CCommsBinderCombiningActivity.
+//
+//-=========================================================
+
+EXPORT_C TBool CCommsBinderActivity::TDataClientMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext)
+ {
+ TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId());
+ __ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 17)); //Diagnostic
+ if (c == 1 || CCommsBinderActivity::IsDataClientPresent(aContext))
+ {
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+EXPORT_C TBool CCommsBinderActivity::TDefaultDataClientMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext)
+ {
+ TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId());
+ __ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 18)); //Diagnostic
+ if (c == 1 || CCommsBinderActivity::IsDataClientPresent(aContext, TCFClientType::EDefault))
+ {
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+EXPORT_C /*virtual*/ CCommsBinderActivity::~CCommsBinderActivity()
+ {
+ if(!iBinderRequestParameters.IsNull())
+ {
+ iBinderRequestParameters.Close();
+ }
+ }
+
+EXPORT_C void CCommsBinderActivity::StoreBinder(RNodeInterface* aDataClient)
+ {
+ __ASSERT_DEBUG(iPendingBinder == aDataClient || iPendingBinder == NULL, User::Panic(KSpecAssert_ESockCrStaCPRAC, 19));
+ iPendingBinder = aDataClient;
+ }
+
+EXPORT_C RNodeInterface* CCommsBinderActivity::Binder() const
+ {
+ return iPendingBinder;
+ }
+
+EXPORT_C void CCommsBinderActivity::StoreBinderRequestParameters(const RCFParameterFamilyBundleC& aBinderRequestParameters)
+ {
+ __ASSERT_DEBUG(iBinderRequestParameters.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 20));
+ if(! aBinderRequestParameters.IsNull())
+ {
+ iBinderRequestParameters.Open(aBinderRequestParameters);
+ }
+ }
+
+void CCommsBinderActivity::SendCustomFlowProvision()
+/**
+Send a custom message that provisions a flow with flow parameters
+*/
+ {
+ __ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 21));
+
+ // Only send the message if we have parameters to send
+ if(!iBinderRequestParameters.IsNull())
+ {
+ RParameterFamily parameterFamily =
+ iBinderRequestParameters.FindFamily(KFlowParametersFamily);
+
+ if(!parameterFamily.IsNull())
+ {
+ STypeId typeId = STypeId::CreateSTypeId(CFlowRequestParameters::EUid, CFlowRequestParameters::EType);
+ CFlowRequestParameters* flowParams = static_cast<CFlowRequestParameters*>(parameterFamily.FindParameterSet(typeId, RParameterFamily::ERequested));
+
+ iPendingBinder->PostMessage(
+ iNode.Id(),
+ TCFInternalEsock::TFlowProvision(
+ flowParams->GetFlowParams()
+ ).CRef()
+ );
+ }
+ }
+ }
+
+
+void CCommsBinderActivity::SendBinderResponseToOriginator()
+/**
+Send out CommsBinderResponse to all originators.
+
+We send to all originators that have joined up until this point, and store this count
+in iOriginatorsCountSnapshot. See comment in ProcessBindToComplete().
+*/
+ {
+ __ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 22));
+
+ PostRequestTo(
+ address_cast<Messages::TNodeId>(FirstOriginator().RecipientId()),
+ TCFServiceProvider::TCommsBinderResponse(iPendingBinder->RecipientId()).CRef());
+
+ iPendingBinder->SetFlags(TCFClientType::EActivating);
+ }
+
+void CCommsBinderActivity::BindToComplete()
+ {
+ __ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 23));
+ TUint c = iNode.CountActivities(ActivitySigId());
+ // Note: this routine can be used with parallel and non-parallel binder activities. In the
+ // former case we start with multiple activities and eventually end up with a single one. In
+ // the latter case we have a single activity throughout.
+ if(c == 1)
+ {
+ iPendingBinder->ClearFlags(TCFClientType::EActivating);
+ }
+ iPendingBinder = NULL;
+ }
+
+//
+// CCommsBinderActivity methods that are embedded transitions/states/stateforks
+//
+
+EXPORT_C RNodeInterface* CCommsBinderActivity::IsDataClientPresent(TNodeContextBase& aContext, TUint aClientFlags)
+/**
+Check if we have a data client and, if so, store it as the binder for this activity.
+
+@param aContext Node context
+@param aClientFlags client flags to use in iterator check
+@return ETrue if data client present, else EFalse.
+*/
+ {
+ // Be careful not to use a client to which we have already sent TDestroy previously.
+ // Find the first data client that does not have the ELeaving flag set. If all are
+ // marked ELeaving then return EFalse - they are on the way out and will disappear
+ // eventually. The effect will be that a new data client will be created.
+ RNodeInterface* dataClient = aContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, aClientFlags), TClientType(0, TCFClientType::ELeaving));
+ return dataClient;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TNoTagOrUseExisting, NetStateMachine::MStateFork, CCommsBinderActivity::TContext)
+EXPORT_C TInt CCommsBinderActivity::TNoTagOrUseExisting::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 24));
+ TCFServiceProvider::TCommsBinderRequest& msg = message_cast<TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage);
+
+ // Save away the parameters sent to us so that they are accessible during the activity
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+ CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+ intf->StoreBinderRequestParameters(msg.iFamilyBundle);
+
+ if(msg.iValue == TSubConnOpen::EAttachToDefault)
+ {
+ RNodeInterface* dc = CCommsBinderActivity::IsDataClientPresent(iContext);
+ if (dc)
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+ CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+
+ intf->StoreBinder(dc);
+ return CoreStates::KUseExisting;
+ }
+ }
+ return MeshMachine::KNoTag;
+ }
+
+//MZTODO - logic of:
+//TNoTagOrWaitForIncomingOrUseExisting
+//&
+//TNoTagOrWaitForIncomingOrUseExistingDefault
+//has been copied but does not seem right, as both use EDefault?
+//Why?
+
+//[401TODO] DL : Only one of TNoTagOrWaitForIncomingOrUseExisting(Default) is used, is it ok to nuke one?
+
+EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExisting, NetStateMachine::MStateFork, CCommsBinderActivity::TContext)
+EXPORT_C TInt CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExisting::TransitionTag()
+ {
+ TCFServiceProvider::TCommsBinderRequest& msg = message_cast<TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage);
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 25));
+
+ if (msg.iValue == TSubConnOpen::EWaitForIncoming)
+ {
+ return CoreNetStates::KWaitForIncoming;
+ }
+
+ else
+ {
+ RNodeInterface* dc = CCommsBinderActivity::IsDataClientPresent(iContext, TCFClientType::EDefault);
+ if (dc)
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+ CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+
+ intf->StoreBinder(dc);
+ return CoreStates::KUseExisting;
+ }
+ }
+
+ return MeshMachine::KNoTag;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExistingDefault, NetStateMachine::MStateFork, CCommsBinderActivity::TContext)
+EXPORT_C TInt CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExistingDefault::TransitionTag()
+ {
+ TCFServiceProvider::TCommsBinderRequest& msg = message_cast<TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage);
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 26));
+
+ if(msg.iValue == TSubConnOpen::EAttachToDefault)
+ {
+ RNodeInterface* dc = CCommsBinderActivity::IsDataClientPresent(iContext, TCFClientType::EDefault);
+ if (dc)
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+ CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+
+ intf->StoreBinder(dc);
+ return CoreStates::KUseExisting;
+ }
+ }
+ else if (msg.iValue == TSubConnOpen::EWaitForIncoming)
+ {
+ return CoreNetStates::KWaitForIncoming;
+ }
+ return MeshMachine::KNoTag;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TStorePendingBinder, NetStateMachine::MStateTransition, CCommsBinderActivity::TContext)
+EXPORT_C void CCommsBinderActivity::TStorePendingBinder::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 27));
+ message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage);
+
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+ CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+
+ intf->StoreBinder(iContext.iPeer);
+ }
+
+EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TSendBinderResponse, NetStateMachine::MStateTransition, CCommsBinderActivity::TContext)
+EXPORT_C void CCommsBinderActivity::TSendBinderResponse::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 28));
+
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+ CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+
+ intf->SendBinderResponseToOriginator();
+ }
+
+EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TSendCustomFlowProvision, NetStateMachine::MStateTransition, CCommsBinderActivity::TContext)
+EXPORT_C void CCommsBinderActivity::TSendCustomFlowProvision::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 29));
+
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+ CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+
+ intf->SendCustomFlowProvision();
+ }
+
+EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TAwaitingBindToComplete, NetStateMachine::MState, PRStates::TContext)
+EXPORT_C TBool CCommsBinderActivity::TAwaitingBindToComplete::Accept()
+ {
+ CoreNetStates::TAwaitingBindToComplete awaitingBindToComplete(iContext);
+ if (awaitingBindToComplete.Accept())
+ {
+ CCommsBinderActivity* binderActivity = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+ __ASSERT_DEBUG(binderActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 30));
+ binderActivity->BindToComplete();
+ iContext.Node().DestroyOrphanedDataClients();
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+//-=========================================================
+//
+//CNoBearer Activity
+//
+//-=========================================================
+
+CNoBearer::CNoBearer(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TUint aActivitiesCount)
+: MeshMachine::CNodeRetryParallelActivity(aActivitySig, aNode, aActivitiesCount),
+ ABindingActivity(aNode.Id()),
+ TIfStaticFetcherNearestInHierarchy(this)
+ {
+ }
+
+/*virtual*/ CNoBearer::~CNoBearer()
+ {
+ iNoBearerParameters.Close();
+ }
+
+EXPORT_C MeshMachine::CNodeActivityBase* CNoBearer::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ TUint c = GetNextActivityCountL(aActivitySig,aNode);
+ return new(ELeave)CNoBearer(aActivitySig, aNode, c);
+ }
+
+EXPORT_C TNodePeerId& CNoBearer::GetOriginator()
+ {
+ __ASSERT_DEBUG(iOriginators.Count() == 1, User::Panic(KSpecAssert_ESockCrStaCPRAC, 31));
+ return iOriginators[0];
+ }
+
+EXPORT_C void CNoBearer::ReturnInterfacePtrL(CoreActivities::ABindingActivity*& aInterface)
+ {
+ aInterface = this;
+ }
+
+EXPORT_C TBool CNoBearer::TServiceProviderMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext)
+ {
+ TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId());
+ __ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 32)); //Diagnostic
+ if (c == 1 || aContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)) != 0)
+ {
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CNoBearer::TRequestCommsBinder, NetStateMachine::MStateTransition, CNoBearer::TContext)
+EXPORT_C void CNoBearer::TRequestCommsBinder::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CNoBearer& noBearer = static_cast<CNoBearer&>(*iContext.iNodeActivity);
+
+ RNodeInterface* sp = iContext.Node().ServiceProvider();
+ __ASSERT_DEBUG(sp, User::Panic(KCorePrPanic, KPanicNoServiceProvider));
+
+ TSubConnOpen::TSubConnType type = TSubConnOpen::EAttachToDefault;
+ if (!(noBearer.GetOriginator().Flags() & TCFClientType::EDefault))
+ {
+ type = TSubConnOpen::ECreateNew;
+ }
+
+ noBearer.PostRequestTo(
+ *sp,
+ TCFServiceProvider::TCommsBinderRequest(
+ type, noBearer.iNoBearerParameters
+ ).CRef()
+ );
+ }
+
+EXPORT_DEFINE_SMELEMENT(CNoBearer::TStoreRequestParameters, NetStateMachine::MStateTransition, CNoBearer::TContext)
+EXPORT_C void CNoBearer::TStoreRequestParameters::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CNoBearer& noBearer = static_cast<CNoBearer&>(*iContext.iNodeActivity);
+ const TCFControlProvider::TNoBearer& noBearerMessage = message_cast<TCFControlProvider::TNoBearer>(iContext.iMessage);
+ __ASSERT_DEBUG(noBearer.iNoBearerParameters.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 33)); // handle should be empty when this fn is called
+ if(noBearerMessage.iFamilyBundle.IsNull())
+ {
+ noBearer.iNoBearerParameters.Open();
+ }
+ else
+ {
+ noBearer.iNoBearerParameters.Open(noBearerMessage.iFamilyBundle);
+ }
+ }
+
+EXPORT_DEFINE_SMELEMENT(CNoBearer::TNoTagOrDataClientsToStart, NetStateMachine::MStateFork, CNoBearer::TContext)
+TInt CNoBearer::TNoTagOrDataClientsToStart::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CNoBearer& activity = static_cast<CNoBearer&>(*iContext.iNodeActivity);
+
+ const TNodePeerId& originator = activity.GetOriginator();
+ __ASSERT_DEBUG(originator.Type() & TCFClientType::EData, User::Panic(KSpecAssert_ESockCrStaCPRAC, 34));
+
+ if (activity.Error() == KErrNone && (originator.Flags() & (TCFClientType::EStarting|TCFClientType::EStarted|TCFClientType::ELeaving)) == 0)
+ {
+ //Start dc
+ return CoreNetStates::KDataClientsToStart;
+ }
+ //Finish the activity
+ return MeshMachine::KNoTag;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CNoBearer::TStartOriginatingDataClient, NetStateMachine::MStateTransition, CNoBearer::TContext)
+void CNoBearer::TStartOriginatingDataClient::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CNoBearer& activity = static_cast<CNoBearer&>(*iContext.iNodeActivity);
+ TNodePeerId& originator = activity.GetOriginator();
+ __ASSERT_DEBUG(originator.Type() & TCFClientType::EData, User::Panic(KSpecAssert_ESockCrStaCPRAC, 35));
+ activity.PostRequestTo(originator.Peer(), TCFDataClient::TStart().CRef());
+ originator.SetFlags(TCFClientType::EStarting);
+ }
+
+EXPORT_DEFINE_SMELEMENT(CNoBearer::TNoTagOrBearerPresent, NetStateMachine::MStateFork, CNoBearer::TContext)
+EXPORT_C TInt CNoBearer::TNoTagOrBearerPresent::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CNoBearer& noBearer = static_cast<CNoBearer&>(*iContext.iNodeActivity);
+ const TCFControlProvider::TNoBearer& noBearerMessage = message_cast<TCFControlProvider::TNoBearer>(iContext.iMessage);
+ __ASSERT_DEBUG(noBearer.iNoBearerParameters.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 36)); // should not yet be set when this fn is called
+ noBearer.iNoBearerParameters.Open(noBearerMessage.iFamilyBundle);
+
+ CoreNetStates::TNoTagOrBearerPresent fork(iContext);
+ return fork.TransitionTag();
+ }
+
+EXPORT_DEFINE_SMELEMENT(CNoBearer::TNoTagOrBearerPresentForAutostart, NetStateMachine::MStateFork, CNoBearer::TContext)
+EXPORT_C TInt CNoBearer::TNoTagOrBearerPresentForAutostart::TransitionTag()
+ {
+ TInt cntrlClients = iContext.Node().CountClients<TDefaultClientMatchPolicy>(
+ /*include*/TClientType(TCFClientType::ECtrl));
+ if (cntrlClients > 0 &&
+ iContext.Node().ServiceProvider() &&
+ !(iContext.Node().ServiceProvider()->Flags() & TCFClientType::EStarted))
+ {
+ //This fork calculates if the NoBearer activity (which this fork has been implemented for)
+ //should attempt to autostart the service provider when returning it to the sender of TNoBearer.
+ //The philosphy here is that if the local node doesn't have a control client, then there's noone
+ //that could posibly start it. It will hence decide to autostart as the top layer of what looks
+ //like an implicit connection. In the future this autostart behaviour should become a specialty
+ //of someone more concrete (rather than generic function). We are speculating about the implicit
+ //top layer that could acquire this function if it ever comes into being.
+ return CoreNetStates::KBearerPresent;
+ }
+ return KNoTag;
+ }
+
+
+//-=========================================================
+//
+//CStartActivity Activity
+//
+//-=========================================================
+CStartActivity::CStartActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ : MeshMachine::CNodeRetryActivity(aActivitySig, aNode),
+ CoreActivities::ABindingActivity(aNode.Id()),
+ TIfStaticFetcherNearestInHierarchy(this)
+ {
+ }
+
+EXPORT_C CStartActivity::~CStartActivity()
+ {
+ }
+
+EXPORT_C MeshMachine::CNodeActivityBase* CStartActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ return new (ELeave) CStartActivity(aActivitySig, aNode);
+ }
+
+//-=========================================================
+//
+//Gone Down Activity
+//
+//-=========================================================
+MeshMachine::CNodeActivityBase* CGoneDownActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ CGoneDownActivity* self = new (ELeave) CGoneDownActivity(aActivitySig,aNode);
+ return self;
+ }
+
+CGoneDownActivity::CGoneDownActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+: MeshMachine::CNodeRetryActivity(aActivitySig, aNode)
+ {
+ }
+
+CGoneDownActivity::~CGoneDownActivity()
+ {
+ //This is a gone down activity. Error mode is its only/natural state
+ //CGoneDownActivity inherits ultimatelly from CNodeActivityBase, which
+ //will attempt to interpret the error mode as a failure to execute (and
+ //auto respond to orignators), which we don't want. Hence clearing
+ //the error and allowing 'this' to die peacefully.
+ SetError(KErrNone);
+ }
+
+void CGoneDownActivity::StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& aOriginator, const TStateTriple& aFirst)
+ {
+ //399TODO: for the moment ignore duplicated TGoneDown messages
+ //but this needs to be fixed (someone is sending TGoneDown from TSendDataClientStopped
+ //hence the problem)
+
+ //ASSERT(IsIdle());
+ if (!IsIdle())
+ {
+ return;
+ }
+
+ //This activity provides service for only one single requestor at a time.
+ __ASSERT_DEBUG(iOriginators.Count()==0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 37)); //Diagnostic panic
+
+ TCFControlClient::TGoneDown& msg = message_cast<TCFControlClient::TGoneDown>(aContext.iMessage);
+ SetError(msg.iValue1);
+ iGoneDownApId = msg.iValue2;
+
+ MESH_LOG_ACTIVITY_EXT(KMeshMachineSubTag, this, &aContext, (_L8("CGoneDownActivity %08x:\tStartL->starting activity"), this));
+ NetStateMachine::ACore::Start(&aContext, aFirst);
+
+ MESH_LOG_ACTIVITY_EXT(KMeshMachineSubTag, this, &aContext, (_L8("CGoneDownActivity %08x:\tStartL->activity started"), this));
+ (void)aOriginator;
+ }
+
+//Find next DC to rebind
+TBool CGoneDownActivity::IsIdle() const
+ {
+ return NetStateMachine::ACore::IsIdle();
+ }
+
+DEFINE_SMELEMENT(CGoneDownActivity::TSendErrorRecoveryReq, NetStateMachine::MStateTransition, CGoneDownActivity::TContext)
+void CGoneDownActivity::TSendErrorRecoveryReq::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CGoneDownActivity& activity = static_cast<CGoneDownActivity&>(*iContext.iNodeActivity);
+
+ //TInt error = ExtractErrorCode(iContext.iMessage);
+ TErrContext ctx(iContext.NodeId(), TCFControlClient::TGoneDown::Id(), activity.ActivitySigId(), TStateChange(0, activity.Error()));
+ ctx.iInfo = (TAny*)activity.iGoneDownApId;
+ TEErrorRecovery::TErrorRecoveryRequest msg(ctx);
+
+ //We can not set SetSentTo() to Control Provider, because the response may not be coming from it
+ //(for example it could be coming from the MCpr and we could be the SCpr).
+ //Normally this would be a problem because any unrelated TError message arriving to the node
+ //and presented to the awaiting state would easily be confused with the response (TError ==
+ //no recovery on the MCpr == EPropagate).
+ //We avoid the problem by checking all arriving TError messages if they are adressed to our activity.
+ __ASSERT_DEBUG(iContext.Node().ControlProvider(), User::Panic(KCorePrPanic, KPanicNoControlProvider));
+ activity.PostRequestTo(*iContext.Node().ControlProvider(),
+ TCFSafeMessage::TRequestCarrierEast<TEErrorRecovery::TErrorRecoveryRequest>(msg).CRef());
+ activity.ClearPostedTo();
+ }
+
+DEFINE_SMELEMENT(CGoneDownActivity::TIgnoreOrPropagate, NetStateMachine::MStateFork, CGoneDownActivity::TContext)
+TInt CGoneDownActivity::TIgnoreOrPropagate::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iMessage.IsMessage<TEErrorRecovery::TErrorRecoveryResponse>(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 38));
+ RNodeInterface* sp = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EStarted));
+ if (sp)
+ {
+ return CoreStates::KIgnore | NetStateMachine::EForward;
+ }
+ //There is no started service provider, the reconnection, mobility, etc must have failed,
+ //continue with tearing this layer down.
+ CGoneDownActivity& activity = static_cast<CGoneDownActivity&>(*iContext.iNodeActivity);
+ TErrResponse& resp = message_cast<TEErrorRecovery::TErrorRecoveryResponse>(iContext.iMessage).iErrResponse;
+ resp.iAction=TErrResponse::EPropagate;
+ __ASSERT_DEBUG(activity.Error()!=KErrNone, User::Panic(KSpecAssert_ESockCrStaCPRAC, 39));
+ resp.iError = activity.Error();
+ return CoreStates::KPropagate | NetStateMachine::EForward;
+ }
+
+
+EXPORT_DEFINE_SMELEMENT(CStartActivity::TAwaitingBindToCompleteOrCancel, NetStateMachine::MState, CStartActivity::TContext)
+TBool CStartActivity::TAwaitingBindToCompleteOrCancel::Accept()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ if (iContext.iMessage.IsMessage<TEBase::TCancel>())
+ {
+ iContext.iNodeActivity->SetError(KErrCancel);
+ iContext.iMessage.ClearMessageId();
+ return EFalse;
+ }
+ else
+ {
+ CoreNetStates::TAwaitingBindToComplete state(iContext);
+ return state.Accept();
+ }
+ }
+} //PRActivities
+
+EXPORT_DEFINE_SMELEMENT(PRDataClientStopActivity::TNoTagOrProviderStopped, NetStateMachine::MStateFork, PRDataClientStopActivity::TContext)
+EXPORT_C TInt PRDataClientStopActivity::TNoTagOrProviderStopped::TransitionTag()
+ {
+ iContext.iNodeActivity->SetError(message_cast<TCFDataClient::TStop>(iContext.iMessage).iValue);
+ if (iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(
+ TClientType(TCFClientType::EData, TCFClientType::EStarted)) != NULL)
+ {
+ // At least one started data client
+ return MeshMachine::KNoTag;
+ }
+ return CoreNetStates::KProviderStopped;
+ }
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/core_states/ss_corepractivities.cpp~ Thu Jan 07 13:34:53 2010 +0200
@@ -0,0 +1,2034 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// COREPRACTIVITIES.CPP
+// Core PR Activities
+// THIS API IS INTERNAL TO NETWORKING AND IS SUBJECT TO CHANGE AND NOT FOR EXTERNAL USE
+//
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#define SYMBIAN_NETWORKING_UPS
+
+#include "ss_corepractivities.h"
+
+
+#include <comms-infras/ss_log.h>
+#include "ss_internal_activities.h"
+#include <comms-infras/ss_coreprstates.h>
+#include <comms-infras/ss_subconnprov.h>
+#include <comms-infras/ss_mcprnodemessages.h>
+
+#include <comms-infras/ss_protocolparameterset.h>
+#include <ss_glob.h>
+
+
+#include <elements/nm_messages_child.h>
+#include <elements/nm_messages_peer.h>
+#include <elements/nm_messages_errorrecovery.h>
+#include "ss_nodemessages_dataclient.h"
+#include "ss_nodemessages_serviceprovider.h"
+#include <comms-infras/ss_nodemessages_rejoiningprovider.h>
+#include <comms-infras/ss_nodemessages_flow.h>
+#include "ss_nodemessages_factory.h"
+#include <comms-infras/ss_nodemessages_internal_esock.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)
+_LIT(KSpecAssert_ESockCrStaCPRAC, "ESockCrStaCPRAC");
+#endif
+
+#if defined __CFLOG_ACTIVE || defined ESOCK_EXTLOG_ACTIVE
+ #define KCoreProviderStatesTag KESockCoreProviderTag
+ _LIT8(KCoreProviderStatesSubTag, "coreprovstate");
+#endif
+
+using namespace NetStateMachine;
+using namespace CoreStates;
+using namespace CoreNetStates;
+using namespace PRStates;
+using namespace PRActivities;
+using namespace CoreActivities;
+using namespace ESock;
+using namespace CorePanics;
+using namespace Elements;
+using namespace Messages;
+using namespace MeshMachine;
+using namespace Factories;
+
+
+#ifdef _DEBUG
+_LIT (KCorePrPanic,"CorePrPanic");
+#endif
+
+namespace CoreErrorActivity
+{ //Special parallel activity, must be started as the last one
+DEFINE_EXPORT_CUSTOM_NODEACTIVITY(ECFActivityError, CoreError, TEBase::TError, CErrorActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CErrorActivity::TCFAwaitingError, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CErrorActivity::TSendErrorRecoveryReq, MeshMachine::TAwaitingMessageState<TEErrorRecovery::TErrorRecoveryResponse>, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CErrorActivity::TDoErrorRecovery)
+NODEACTIVITY_END()
+}
+
+namespace PRProvisionActivity
+{
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityStoreProvision, PrProvision, TCFDataClient::TProvisionConfig)
+ NODEACTIVITY_ENTRY(KNoTag, PRStates::TStoreProvision, CoreNetStates::TAwaitingProvision, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace PRControlClientJoinActivity
+{
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityClientJoin, PRControlClientJoin, TNodeSignal::TNullMessageId) //May be waiting for both messages
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TAddControlClientAndSendJoinCompleteIfRequest, CoreNetStates::TAwaitingControlClientJoin, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace PRDataClientJoinActivity
+{ //This activity needs the activity object (& it can fail on AddClientL, so no point converting)
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityDataClientJoin, PRDataClientJoin, TCFPeer::TJoinRequest)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientJoinRequest, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TAddDataClientAndRespond)
+NODEACTIVITY_END()
+}
+
+namespace PRClientLeaveActivity
+{//This activity will wait for ECFActivityBinderRequest to complete
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityClientLeave, PRClientLeave, TNodeSignal::TNullMessageId) //May be waiting for both messages
+NODEACTIVITY_ENTRY(KNoTag, PRStates::TProcessClientLeave, CoreStates::TAwaitingClientLeave, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace PRDataClientIdleActivity
+{
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityDataClientIdle, PRDataClientIdle, TCFControlProvider::TIdle)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::THandleDataClientIdle, CoreNetStates::TAwaitingDataClientIdle, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace PRDataClientActiveActivity
+{
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityDataClientActive, PRDataClientActive, TCFControlProvider::TActive)
+ NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, CoreNetStates::TAwaitingDataClientActive, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace PRDestroyActivity
+{
+//The generic Destroy activity. Carries out the node's goodbye handshake.
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityDestroy, PRDestroy, TEChild::TDestroy, CoreActivities::CDestroyActivity::New)
+ FIRST_NODEACTIVITY_ENTRY(MeshMachine::TAwaitingDestroy, CoreActivities::CDestroyActivity::TNoTagBlockedByActivitiesOrLeavingDataClient)
+
+ //Stop self first
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, CoreStates::TNoTagOrNoClients)
+
+ //The node mustn't go out of scope with clients present. The node must get rid of them first.
+ NODEACTIVITY_ENTRY(KNoTag, CoreActivities::CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave, CoreStates::TAwaitingClientLeave, CDestroyActivity::TNoTagOrNoTagBackwards)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreActivities::CDestroyActivity::TProcessClientLeave, TTag<KNoClients>)
+
+ THROUGH_NODEACTIVITY_ENTRY(KNoClients, PRStates::TProcessDestroy, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, MeshMachine::TAwaitingLeaveComplete, CoreActivities::CDestroyActivity::TNoTagOrNoTagBackwards)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingAndRemoveControlProvider)
+NODEACTIVITY_END()
+}
+
+namespace PRSetParamsRequest
+{
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRSetParams, TCFScpr::TSetParamsRequest)
+ FIRST_NODEACTIVITY_ENTRY(PRStates::TAwaitingParamRequest, CoreNetStates::TNoTagOrBearerPresent)
+ NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, PRStates::TPassToServiceProvider, CoreNetStates::TAwaitingParamResponse, MeshMachine::TTag<CoreNetStates::KBearerPresent>)
+ LAST_NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, PRStates::TStoreParamsAndPostToOriginators)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TStoreAndRespondWithCurrentParams)
+NODEACTIVITY_END()
+#else
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRSetParams, TNodeSignal::TNullMessageId)
+NODEACTIVITY_END()
+#endif
+}
+
+// no Store in case of GetParamsRequest
+namespace PRGetParamsRequest
+{
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRGetParams, TCFScpr::TGetParamsRequest)
+ FIRST_NODEACTIVITY_ENTRY(PRStates::TAwaitingParamRequest, CoreNetStates::TNoTagOrBearerPresent)
+ NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, PRStates::TPassToServiceProvider, CoreNetStates::TAwaitingParamResponse, MeshMachine::TTag<CoreNetStates::KBearerPresent>)
+ LAST_NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreStates::TPostToOriginators)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TRespondWithRetrievedParams)
+NODEACTIVITY_END()
+#else
+DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRGetParams, TNodeSignal::TNullMessageId)
+NODEACTIVITY_END()
+#endif
+}
+
+namespace PRBindToActivity
+{
+//PRBindToActivity is responsible for handling TCFDataClient::TBindTo;
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityBindTo, PRBindTo, TCFDataClient::TBindTo, CBindToActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingBindTo, CBindToActivity::TNoTagOrBearerReady)
+ //TBindTo can hold:
+ //[KNoTag] - a valid serviceProvider cookie that this node isn't bound to;
+ //[KBearerReady] - a valid serviceProvider cookie that this node is already bound to;
+ //[KBearerReady] - a NULL serviceProvider (this node is at the stack's bottom);
+
+ //{ JOINING NEW SERVICE PROVIDER
+ //a valid serviceProvider supplied, new to this node, let's join it;
+ NODEACTIVITY_ENTRY(KNoTag, CBindToActivity::TSendControlClientJoinRequest, CoreStates::TAwaitingJoinComplete, TTag<KBearerReady>)
+ //}
+
+ //serviceProvider provisionally joined. Now the activity needs to propagate iteslf (TBindTo) to its dataclients.
+ //The dataclients are either present or not. If not this activity will assume this is the layer construction phase
+ //and will attempt to construct a default dataclient.
+ THROUGH_NODEACTIVITY_ENTRY(KBearerReady, MeshMachine::TDoNothing, CBindToActivity::TNoTagOrDataClientReady)
+
+ //{ DATA CLIENT CREATION
+ //No dataclients present, assume this is the layer creation phase. Attempt to create a dataclient.
+ NODEACTIVITY_ENTRY(KNoTag, CBindToActivity::TCreateDataClient, TAcceptErrorState<CoreNetStates::TAwaitingDataClientJoin>, MeshMachine::TErrorTagOr<CBindToActivity::TNoTagOrBindToComplete>)
+ //BindTo activity is the pre-start layer builder, hence it always requests the dataclient from the factory.
+ //The factory (being aware of the phase) may decide to:
+ //1. create a new dataclient -> process dataclient creation [KNoTag]
+ //2. return a preexisting dataclient -> bind the client [KDataClientReady]
+ //3. not to create a dataclient -> send TBindToComplete to the originator [KBindToComplete]
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, PRStates::TProcessDataClientCreation, TTag<KDataClientReady>)
+ //}
+
+ THROUGH_NODEACTIVITY_ENTRY(KDataClientReady, MeshMachine::TDoNothing, CBindToActivity::TNoTagOrBearerReadyOrBindToComplete)
+ //{ BINDING DATACLIENTS LOOP
+ //Dataclient(s) is/are ready. Depending on whether the node has the lower layer or not,
+ //we will [KNoTag] or will not [KNoBearer] need to request a binder for the dataclient.
+
+ //{SERVICE PROVIDER PRESENT
+ NODEACTIVITY_ENTRY(KNoTag, CBindToActivity::TRequestCommsBinder, TAcceptErrorState<CoreNetStates::TAwaitingBinderResponse>, TErrorTagOr<TTag<KBearerReady> >)
+ //}
+ NODEACTIVITY_ENTRY(KBearerReady, PRActivities::CBindToActivity::TSendBindTo, CBindToActivity::TAwaitingBindToCompleteOrError,
+ TErrorTagOr<TTag<KDataClientReady | NetStateMachine::EBackward> >)
+ //}
+
+ //Binding is finished. If this is not autocommit (see TCFDataClient::TBindTo), the activity will reply TCFDataClient::TBindToComplete
+ //to the sender await for the confirmation (TCFDataClient::TCommitBindTo) or cancelation (TBase::TCancel) from the sender.
+ //If this is autommit, the activity will skip awaiting for TCFDataClient::TCommitBindTo and commit itself.
+ THROUGH_NODEACTIVITY_ENTRY(KBindToComplete, CBindToActivity::TSendBindToComplete, CBindToActivity::TNoTagOrCommit)
+ NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, MeshMachine::TAwaitingMessageState<TCFDataClient::TCommitBindTo>, TErrorTagOr<TTag<KCommit> >)
+
+ //commiting (either implicit or explicit).
+ NODEACTIVITY_ENTRY(KCommit, CBindToActivity::TCommit, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
+
+ //This is not autocommit and the sender has just explicitly cancelled. Alternativelly this is an error path.
+ //Cancelling/processing error entiles sending TCancel to all dataclients awaiting confirmation
+ //as well as it entiles leaving the new service provider.
+ NODEACTIVITY_ENTRY(KErrorTag, CBindToActivity::TCancel, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
+
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
+NODEACTIVITY_END()
+}
+
+namespace PRStartActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStart, PRStart, TCFServiceProvider::TStart, PRActivities::CStartActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingStart, CoreNetStates::TNoTagOrBearerPresentBlockedByStop)
+ NODEACTIVITY_ENTRY(KBearerPresent, CoreNetStates::TBindSelfToPresentBearer, CoreNetStates::TAwaitingBindToComplete, TTag<KBearerPresent>)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendNoBearer, MeshMachine::TAwaitingMessageState<TCFControlProvider::TBearer>, CoreNetStates::TNoTagOrBearerPresentOrErrorTag)
+
+ //Start the service provider, use the default cancellation.
+ //Forward TCancel to the service provider, wait for TStarted or TError (via the Error Activity)
+ //When TStarted arrives after TCancel the activity will move to the nearest KErrorTag
+ NODEACTIVITY_ENTRY(KBearerPresent, CoreNetStates::TStartServiceProviderRetry, CoreNetStates::TAwaitingStarted, MeshMachine::TNoTagOrErrorTag)
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing)
+ //Start data clients, use the default cancellation.
+ //Forward TCancel to the self, wait for TCFDataClient::TStarted or TError (via the Error Activity)
+ //When TCFDataClient::TStarted arrives after TCancel the activity will move to the nearest KErrorTag
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStartSelf, CoreNetStates::TAwaitingDataClientStarted, MeshMachine::TNoTagOrErrorTag)
+ NODEACTIVITY_ENTRY(KErrorTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TErrorTag)
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TRaiseAndClearActivityError)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendStarted)
+NODEACTIVITY_END()
+}
+
+namespace PRStopActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStop, PRStop, TCFServiceProvider::TStop, MeshMachine::CNodeRetryActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingStop, TActiveOrNoTagBlockedByBindTo)
+ THROUGH_NODEACTIVITY_ENTRY(KActiveTag, CoreNetStates::TCancelDataClientStart, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, CoreNetStates::TNoTagOrNoBearer)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendStop, CoreNetStates::TAwaitingStopped, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingRequestToServiceProvider, MeshMachine::TAwaitingLeaveComplete, TTag<CoreNetStates::KNoBearer>)
+ LAST_NODEACTIVITY_ENTRY(CoreNetStates::KNoBearer, PRStates::TSendStoppedAndGoneDown)
+NODEACTIVITY_END()
+}
+
+namespace PRDataClientStartActivity
+{
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityStartDataClient, PRDataClientStart, TCFDataClient::TStart)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientStart, CoreNetStates::TNoTagOrNoDataClients)
+ NODEACTIVITY_ENTRY(KNoTag, PRStates::TStartDataClients, TAcceptErrorState<CoreNetStates::TAwaitingDataClientsStarted>, MeshMachine::TErrorTagOr<MeshMachine::TTag<CoreNetStates::KNoDataClients> >)
+ LAST_NODEACTIVITY_ENTRY(CoreNetStates::KNoDataClients, PRStates::TSendDataClientStarted)
+
+ NODEACTIVITY_ENTRY(KErrorTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientsStopped, MeshMachine::TErrorTag)
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TRaiseAndClearActivityError)
+NODEACTIVITY_END()
+}
+
+namespace PRDataClientStopActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStopDataClient, PRDataClientStop, TCFDataClient::TStop, MeshMachine::CNodeRetryActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientStop, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, PRStates::TProcessDataClientStop, CoreNetStates::TNoTagOrDataClientsToStopBlockedByStarting)
+
+ NODEACTIVITY_ENTRY(CoreNetStates::KDataClientsToStop, CoreNetStates::TStopDataClients, CoreNetStates::TAwaitingDataClientsStopped, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, CoreNetStates::TNoTagOrUnbindOnStop)
+
+ NODEACTIVITY_ENTRY(CoreNetStates::KUnbind, CoreNetStates::TSendClientLeavingRequestToServiceProvider, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, PRStates::TDestroyOrphanedDataClients, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TSendDataClientStopped)
+NODEACTIVITY_END()
+}
+
+
+namespace PRForwardStateChangeActivity
+{
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityForwardStateChange, PRForwardStateChange, TCFMessage::TStateChange)
+ NODEACTIVITY_ENTRY(KNoTag, PRStates::TForwardStateChange, MeshMachine::TAwaitingMessageState<TCFMessage::TStateChange>, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace PRDataClientStatusChangeActivity
+{
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityDataClientStatusChange, PRDataClientStatusChange, TCFControlProvider::TDataClientStatusChange)
+ NODEACTIVITY_ENTRY(KNoTag, PRStates::THandleDataClientStatusChangeAndDestroyOrphans, CoreNetStates::TAwaitingDataClientStatusChange, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace PRGoneDownActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityGoneDown, PRGoneDown, TCFControlClient::TGoneDown, CGoneDownActivity::NewL)
+ // Our Service Provider has gone down unexpectedly (we haven't issued a TStop)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingGoneDown, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TCancelAndCloseZone0ClientExtIfaces, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingRequestToServiceProvider, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CGoneDownActivity::TSendErrorRecoveryReq, MeshMachine::TAwaitingErrorRecoveryResponseOrError, CoreStates::TRetryOrIgnoreOrPropagate)
+ THROUGH_NODEACTIVITY_ENTRY(CoreStates::KRetry, MeshMachine::TDoNothing, CGoneDownActivity::TIgnoreOrPropagate)
+ LAST_NODEACTIVITY_ENTRY(CoreStates::KIgnore, MeshMachine::TDoNothing)
+ NODEACTIVITY_ENTRY(CoreStates::KPropagate, CoreNetStates::TCancelStartAndStopSelf, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TSendGoneDown)
+NODEACTIVITY_END()
+}
+
+
+namespace PRGoneUpActivity
+{
+// This Activity forward the TGoneUp event to the Control Clients nodes that are
+// not in the originator lis
+
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityGoneUp, PRGoneUp, TCFControlClient::TGoneUp)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingGoneUp, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendGoneUp)
+NODEACTIVITY_END()
+}
+
+namespace PRLegacyRMessage2HandlerActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityLegacyRMessage2Handler, PRLegacyRMessage2Handler, TNodeSignal::TNullMessageId, MeshMachine::CNodeParallelMessageStoreActivityBase::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingLegacyRMessage2Ext, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TProcessOrForwardRMessage2Ext, CoreNetStates::TAwaitingRMessage2Processed, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CoreStates::TPostToOriginators)
+NODEACTIVITY_END()
+}
+
+
+namespace CoreActivities
+{
+DECLARE_DEFINE_ACTIVITY_MAP(coreActivitiesAll)
+ ACTIVITY_MAP_ENTRY(CoreErrorActivity, CoreError) //Must be first in the table
+ACTIVITY_MAP_END()
+
+//-=========================================================
+//
+//Error Activity
+//
+//-=========================================================
+MeshMachine::CNodeActivityBase* CErrorActivity::NewL( const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode )
+ {
+ TUint c = GetNextActivityCountL(aActivitySig,aNode);
+ return new(ELeave)CErrorActivity(aActivitySig, aNode, c);
+ }
+
+CErrorActivity::CErrorActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TUint aActivitiesCount)
+ : MeshMachine::CNodeParallelActivityBase(aActivitySig, aNode, aActivitiesCount), iErroredActivityId(MeshMachine::KActivityNull)
+ {
+ }
+
+CErrorActivity::~CErrorActivity()
+ {
+ if (Error() != KErrNone)
+ {
+ CNodeActivityBase* a = iNode.FindActivityById(iErroredActivityId);
+ if (a)
+ {
+ a->SetError(Error());
+ a->SetIdle();
+ }
+ }
+ SetError(KErrNone);
+ }
+
+TBool CErrorActivity::IsIdle() const
+ {
+ return NetStateMachine::ACore::IsIdle();
+ }
+
+void CErrorActivity::StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& /*aOriginator*/, const TStateTriple& aFirst)
+ {
+ __ASSERT_DEBUG(IsIdle(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 1));
+ MESH_LOG_ACTIVITY_EXT(KESockMeshMachine, this, &aContext, (_L8("CErrorActivity %08x:\tStartL->starting activity"), this));
+
+ NetStateMachine::ACore::Start(&aContext, aFirst);
+
+ MESH_LOG_ACTIVITY_EXT(KESockMeshMachine, this, &aContext, (_L8("CErrorActivity %08x:\tStartL->activity started"),this));
+ }
+
+TBool CErrorActivity::Next(TNodeContextBase& aContext)
+ {
+ TBool ret = EFalse;
+
+
+ if (aContext.iMessage.IsMessage<TEBase::TCancel>())
+ {
+ CNodeActivityBase* a = iNode.FindActivityById(iErroredActivityId);
+ //Special handling for TCancel.
+ if (a && a->FindOriginator(aContext.iSender) != KErrNotFound)
+ {
+ ret = ETrue;
+ //iActiviy could have handled it, but chose not to.
+ Cancel(aContext);
+ //consume the message, otherwise the iActivity will get idled and iActivity reference
+ //will become invalid.
+ aContext.iMessage.ClearMessageId();
+ }
+ }
+ else
+ {
+ //If we have sent TErrorRecoveryRequest, we had to have set PostedToId() to the recipient (ControlProvider)
+ //as otherwise there would be no path for propagating the potential TCancel.
+ //The response however (TErrorRecoveryResponse or TError) will not necesserily come from that recipient (CP)
+ //(for example it could be coming from the MCpr and we could be the SCpr).
+ //Normally this would be a problem because any unrelated TError message arriving to the node
+ //and presented to the awaiting state would easily be confused with the response (TError == no recovery on the MCpr == EPropagate).
+ //We avoid the problem by checking all arriving messages if they are adressed to our activity (but we don't
+ //check the sender.
+ const TNodeCtxId* recipient = address_cast<const TNodeCtxId>(&aContext.iRecipient);
+ if (recipient && (ActivityId() == recipient->NodeCtx()))
+ {
+ ret = ACore::Next(&aContext);
+ if(ret)
+ {
+ MESH_LOG_ACTIVITY_EXT(KMeshMachineSubTag, this, &aContext, (_L8("CNodeActivityBase %08x:\tNext->transition"), this));
+ }
+ }
+ }
+ return ret;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CErrorActivity::TAwaitingError, NetStateMachine::MState, CErrorActivity::TContext)
+EXPORT_C TBool CErrorActivity::TAwaitingError::Accept()
+ {
+ if (! iContext.iMessage.IsMessage<TEBase::TError>())
+ {
+ return EFalse;
+ }
+
+ TEBase::TError& errorMessage = message_cast<TEBase::TError>(iContext.iMessage);
+
+ //Diagnostic panic only. TError message should not be travelling around with KErrNone.
+ //If you see this panic, please send a proper error code.
+ __ASSERT_DEBUG(errorMessage.iValue != KErrNone, User::Panic(KSpecAssert_ESockCrStaCPRAC, 2));
+
+ MeshMachine::CNodeActivityBase* aa = iContext.Node().FindAddressedActivity(iContext);
+
+ //TError is always a response. If there is no activity addressed by the TError,
+ //then we assume the activity hasn't bothered waiting for the result.
+ //We hence ignore the error.
+ if (aa)
+ {
+ aa->SetError(errorMessage.iValue);
+ aa->SetIdle();
+ }
+ errorMessage.ClearMessageId();
+ return EFalse;
+ }
+
+DEFINE_SMELEMENT(CErrorActivity::TCFAwaitingError, NetStateMachine::MState, CErrorActivity::TContext)
+EXPORT_C TBool CErrorActivity::TCFAwaitingError::Accept()
+ {
+ if (! iContext.iMessage.IsMessage<TEBase::TError>())
+ {
+ return EFalse;
+ }
+
+ TEBase::TError& errorMessage = message_cast<TEBase::TError>(iContext.iMessage);
+
+ //Diagnostic panic only. TError message should not be travelling around with KErrNone.
+ //If you see this panic, please send a proper error code.
+ __ASSERT_DEBUG(errorMessage.iValue != KErrNone, User::Panic(KSpecAssert_ESockCrStaCPRAC, 3));
+
+ RNodeInterface* client = iContext.Node().FindClient(iContext.iSender);
+ if (client &&
+ client->Type() & TCFClientType::EServProvider &&
+ iContext.Node().ControlProvider() != NULL &&
+ iContext.Node().CountActivities(ECFActivityDestroy) == 0)
+ {
+ //this is the only way out into the activity and into error recovery steps
+ //that error activity is responsible for doing.
+ return ETrue;
+ }
+
+ return CErrorActivity::TAwaitingError::Accept();
+ }
+
+//Simply leaving from this DoL will NOT have the effect of sending TError to originators
+//of the Errored activity! iContext.iNodeActivity is the Error activity.
+//Reassign iContext.iNodeActivity before leaving or handle the error.
+EXPORT_DEFINE_SMELEMENT(CErrorActivity::TSendErrorRecoveryReq, NetStateMachine::MStateTransition, CErrorActivity::TContext)
+EXPORT_C void CErrorActivity::TSendErrorRecoveryReq::DoL()
+ {
+ //Find matching activity, if any
+ MeshMachine::CNodeActivityBase* aa = iContext.Node().FindAddressedActivity(iContext);
+ //we are started based on the fact the the last message iContext.Node()'s received is TError
+ TEBase::TError& errmsg = message_cast<TEBase::TError>(iContext.iMessage);
+
+ //The error comes from someone else than our Data Client (or we wouldn't be here).
+ //It may be our Service Provider or it can be some other node which has originated
+ //an activity on us (in which case the errored activity must be present).
+ if (aa==NULL)
+ {
+ __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ASendErrorRecoveryReq::DoL - TError but no addressed activity - ignoring")));
+#ifdef SYMBIAN_NETWORKING_UPS
+ // Terminate the error activity (not UPS specific).
+ iContext.iNodeActivity->SetIdle();
+#endif //SYMBIAN_NETWORKING_UPS
+ return;
+ }
+
+ AContextStore* intf = NULL;
+ if (aa->SupportsExtInterface(AContextStore::KInterfaceId))
+ {
+ //FetchExtInterfaceL below can never leave because it is being checked few lines above in the "if"
+ intf = reinterpret_cast<AContextStore*>(aa->FetchExtInterfaceL(AContextStore::KInterfaceId));
+ }
+
+ //Check if there is any point in sending Error Recovery Request
+ if (intf==NULL || !intf->IsStored() || !iContext.Node().ControlProvider())
+ {
+ __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ERROR: ASendErrorRecoveryReq::DoL - KErrNotSupported")));
+ iContext.iNodeActivity->SetIdle();
+ aa->SetError(errmsg.iValue);
+ aa->SetIdle();
+ return;
+ }
+
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CoreActivities::CErrorActivity& activity = static_cast<CoreActivities::CErrorActivity&>(*iContext.iNodeActivity);
+ __ASSERT_DEBUG(activity.iErroredActivityId==MeshMachine::KActivityNull, User::Panic(KSpecAssert_ESockCrStaCPRAC, 4));
+ // Save a reference to the activity and a point
+ // Each time we use the activity, query it from the node, because the activity may have gone away (originator left node etc)
+ activity.iErroredActivityId = aa->ActivityId();
+
+ activity.SetError(errmsg.iValue);
+ activity.iMessageId = errmsg.iMsgId;
+
+ TErrContext ctx(iContext.NodeId(), errmsg.iMsgId, aa->ActivitySigId(), TStateChange(0, errmsg.iValue));
+ TEErrorRecovery::TErrorRecoveryRequest msg(ctx);
+
+ activity.PostRequestTo(
+ *iContext.Node().ControlProvider(),//ControlProvider() verified above
+ TCFSafeMessage::TRequestCarrierEast<TEErrorRecovery::TErrorRecoveryRequest>(msg).CRef()
+ );
+
+ //The original activiy might have set 'sent to', but that's surely
+ //not meaningful anymore (we've just received a response from that 'sent to').
+ //We could have pretended that the orginal activity knows it's sent
+ //error recovery to the control provider but it's best just to clear
+ //'sent to' (and handle TCancel from here (CErrorActivity::Next()).
+ aa->ClearPostedTo();
+ }
+
+EXPORT_DEFINE_SMELEMENT(CErrorActivity::TDoErrorRecovery, NetStateMachine::MStateTransition, CErrorActivity::TContext)
+EXPORT_C void CErrorActivity::TDoErrorRecovery::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CoreActivities::CErrorActivity* act = static_cast<CoreActivities::CErrorActivity*>(iContext.iNodeActivity);
+ CNodeActivityBase* a = iContext.Node().FindActivityById(act->iErroredActivityId);
+ if (a == NULL)
+ {
+ iContext.iNodeActivity->SetIdle();
+ return;
+ }
+
+ if (iContext.iMessage.IsMessage<TEErrorRecovery::TErrorRecoveryResponse>())
+ {
+ TErrResponse& resp = message_cast<TEErrorRecovery::TErrorRecoveryResponse>(iContext.iMessage).iErrResponse;
+ if (resp.iAction == TErrResponse::ERetry)
+ { //rerun current transition
+ __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ADoErrorRecovery::DoL - instructed to retry")));
+ __ASSERT_DEBUG(a->SupportsExtInterface(AContextStore::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+
+ AContextStore* intf = reinterpret_cast<AContextStore*>(a->FetchExtInterfaceL(AContextStore::KInterfaceId));
+ __ASSERT_DEBUG(intf->IsStored(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 5));
+ intf->Retry(*a,iContext);
+ if (iContext.iReturn == KErrNone)
+ { //retry succeded
+ act->SetError(KErrNone);
+ }
+ //if Retry had failed, then the d'tor of act will raise the error on
+ //and terminate act->iActivity,
+ }
+ else if (resp.iAction == TErrResponse::EPropagate)
+ { //set new error values and fall through
+ __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ADoErrorRecovery::DoL - instructed to propagate the error")));
+ act->iMessageId = resp.iMessageId;
+ a->SetError(resp.iError);
+ }
+ else //if (resp.iAction == TErrResponse::EIgnore)
+ {
+ __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag,
+ _L8("WARNING: ADoErrorRecovery::DoL() - instructed to ignore the error!")));
+ }
+ }
+ }
+
+
+//-=========================================================
+//
+//Destroy Activity - will delete the node when destructed
+//
+//-=========================================================
+
+EXPORT_C MeshMachine::CNodeActivityBase* CDestroyActivity::New(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ TAny* space = BorrowPreallocatedSpace(aNode, sizeof(CDestroyActivity));
+ CDestroyActivity* self = new (space) CDestroyActivity(aActivitySig, aNode);
+ self->InsertPreallocatedDestroyActivity(); //Destructing preallocated activity
+ return self;
+ }
+
+CDestroyActivity::CDestroyActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+: CNodeRetryActivity(aActivitySig, aNode),
+ APreallocatedOriginators<1>(iOriginators)
+ {
+ //Mark the provider for deletion, so that it's not served by the factory from now on.
+ static_cast<ESock::CMMCommsProviderBase&>(iNode).MarkMeForDeletion();
+ }
+
+void CDestroyActivity::Destroy()
+ {
+ ReturnPreallocatedSpace(this);
+ this->~CDestroyActivity(); //Run the destructor
+
+ //Delete the provider.
+ static_cast<ESock::CMMCommsProviderBase&>(iNode).DeleteMeNow();
+ }
+
+TBool CDestroyActivity::Next(TNodeContextBase& aContext)
+ {
+ if (aContext.iMessage.IsMessage<TEBase::TCancel>())
+ {
+ return ETrue;
+ }
+ else
+ return CNodeActivityBase::Next(aContext);
+ }
+
+EXPORT_DEFINE_SMELEMENT(CDestroyActivity::TNoTagOrNoTagBackwards, NetStateMachine::MStateFork, PRStates::TContext)
+EXPORT_C TInt CDestroyActivity::TNoTagOrNoTagBackwards::TransitionTag()
+ {
+ if (iContext.iMessage.IsMessage<TEChild::TLeft>())
+ {
+ TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData|TCFClientType::ECtrl));
+ __ASSERT_DEBUG(iter[0], User::Panic(KSpecAssert_ESockCrStaCPRAC, 7)); //One leaving client must still be there.
+ return iter[1] == NULL ? MeshMachine::KNoTag : MeshMachine::KNoTag | NetStateMachine::EBackward;
+ }
+ else if (iContext.iMessage.IsMessage<TEPeer::TLeaveComplete>())
+ {
+ __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl|TCFClientType::EData))==NULL,
+ User::Panic(KCorePrPanic, KPanicClientsStillPresent));
+ if (iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider))==NULL)
+ {
+ return NetStateMachine::EForward | MeshMachine::KNoTag;
+ }
+ return NetStateMachine::EBackward | MeshMachine::KNoTag; //Loop back to the same triple (& remove the peer)
+ }
+ __ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockCrStaCPRAC, 8));
+ return KNoTag;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave, NetStateMachine::MStateTransition, PRStates::TContext)
+EXPORT_C void CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave::DoL()
+ {
+ if (iContext.iMessage.IsMessage<TEChild::TLeft>())
+ {
+ ProcessClientLeaveL();
+ }
+ else
+ {
+ MakeClientsLeaveL();
+ }
+ }
+
+void CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave::MakeClientsLeaveL()
+ {
+ __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl))==NULL,
+ User::Panic(KCorePrPanic, KPanicClientsStillPresent));
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ iContext.iNodeActivity->ClearPostedTo();
+
+ //MZTODO: this asserion may need to be changed since TDestroy can
+ //come while data client is active etc.
+ __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EActive|TCFClientType::EActivating|TCFClientType::EStarting|TCFClientType::EStarted))==NULL,
+ User::Panic(KCorePrPanic, KPanicClientsStillPresent));
+
+ TClientIter<TDefaultClientMatchPolicy> dciter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData), TClientType(0, TCFClientType::ELeaving));
+ RNodeInterface* dc = NULL;
+ while ((dc = dciter[0]) != NULL) //always inspect the first elem as we're invalidating the iterator with each hit.
+ {
+ dc->PostMessage(iContext.NodeId(), TEChild::TDestroy().CRef());
+ dc->SetFlags(TCFClientType::ELeaving);
+ }
+ }
+
+void CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave::ProcessClientLeaveL()
+ {
+ CDestroyActivity::TProcessClientLeave processClientLeave(iContext);
+ processClientLeave.DoL();
+ }
+
+
+//-=========================================================
+//
+//Loppin Activity
+//
+//-=========================================================
+EXPORT_C ACountLoopActivity::~ACountLoopActivity()
+ {
+ }
+
+
+EXPORT_C MeshMachine::CNodeActivityBase* CCountLoopActivityBase::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ return new (ELeave) CCountLoopActivityBase(aActivitySig, aNode);
+ }
+
+EXPORT_C CCountLoopActivityBase::CCountLoopActivityBase(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+: MeshMachine::CNodeActivityBase(aActivitySig, aNode),
+ TIfStaticFetcherNearestInHierarchy(this)
+ {
+ }
+
+EXPORT_C CCountLoopActivityBase::~CCountLoopActivityBase()
+ {
+ }
+
+EXPORT_DEFINE_SMELEMENT(ACountLoopActivity::TNoTagOrNoTagBackwards, NetStateMachine::MStateFork, PRStates::TContext)
+EXPORT_C TInt ACountLoopActivity::TNoTagOrNoTagBackwards::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(ACountLoopActivity::KInterfaceId),User::Panic(KCorePrPanic, KPanicInterfaceNotSupported));
+ ACountLoopActivity* countLoopActivity = static_cast<ACountLoopActivity*>(iContext.iNodeActivity->FetchExtInterface(ACountLoopActivity::KInterfaceId));
+ if (countLoopActivity->DecCount() > 0)
+ {
+ return KNoTag | NetStateMachine::EBackward;
+ }
+ return KNoTag | NetStateMachine::EForward;
+ }
+
+
+
+
+
+//-=========================================================
+//
+//
+//Binding Activity
+//
+//
+//-=========================================================
+EXPORT_C ABindingActivity::~ABindingActivity()
+ {
+ //Handle premature termination of the ABindingActivity object
+ //by responding to the originator
+ //If the originator has not been replied to yet, reply now with an error code
+ if (IsBinding())
+ {
+ ReplyToOriginator(KErrAbort);
+ }
+ }
+
+EXPORT_C void ABindingActivity::StoreOriginator(const TRuntimeCtxId& aNodeCtxId)
+ {
+ //Check if the originator wasn't set before. If it was, it must be replied to before storing ths new one.
+ __ASSERT_DEBUG(iOriginator.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 9));
+ iOriginator = aNodeCtxId;
+ }
+
+EXPORT_C void ABindingActivity::ReplyToOriginator(TInt aError)
+ {
+ //NOTE: Please do not make this diagnostic panic conditional.
+ //Please allow it to server everyone equally.
+ //Please handle the error conditions properly so that you obey this API's semantics.
+ //If you are not providing a clean error handling solution for your activity,
+ //please use IsBinding() before calling this API!
+ __ASSERT_DEBUG(!iOriginator.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 10)); //The iOriginator must be set.
+ RClientInterface::OpenPostMessageClose(iOurNode, iOriginator, TCFDataClient::TBindToComplete(aError).CRef());
+ iOriginator.SetNull();
+ }
+
+EXPORT_DEFINE_SMELEMENT(ABindingActivity::TSendBindToComplete, NetStateMachine::MStateTransition, CoreStates::TContext)
+EXPORT_C void ABindingActivity::TSendBindToComplete::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(ABindingActivity::KInterfaceId), User::Panic(KSpecAssert_ESockCrStaCPRAC, 11));
+ ABindingActivity* bindingActivity = reinterpret_cast<ABindingActivity*>(iContext.iNodeActivity->FetchExtInterfaceL(ABindingActivity::KInterfaceId));
+ bindingActivity->ReplyToOriginator(iContext.iNodeActivity->Error());
+ }
+
+EXPORT_DEFINE_SMELEMENT(ABindingActivity::TSendBindToCompleteIfExpected, NetStateMachine::MStateTransition, CoreStates::TContext)
+EXPORT_C void ABindingActivity::TSendBindToCompleteIfExpected::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(ABindingActivity::KInterfaceId), User::Panic(KSpecAssert_ESockCrStaCPRAC, 12));
+ ABindingActivity* bindingActivity = reinterpret_cast<ABindingActivity*>(iContext.iNodeActivity->FetchExtInterfaceL(ABindingActivity::KInterfaceId));
+ if (bindingActivity->IsBinding())
+ {
+ bindingActivity->ReplyToOriginator(iContext.iNodeActivity->Error());
+ }
+ }
+
+void ABindingActivity::FinalReplyToOriginator(TInt aError)
+/**
+Intended to be called from derived class destructors to arrange for a TBindToComplete reply to be sent
+before any other messages in those derived class destructors (for example TDestroy).
+*/
+ {
+ if (IsBinding())
+ {
+ ReplyToOriginator(aError);
+ // Ensure that we don't send another reply in ~ABindingActivity.
+ iOriginator = Messages::TNodeCtxId();
+ }
+ }
+
+} // CoreActivities
+
+
+namespace PRActivities
+{
+DECLARE_DEFINE_ACTIVITY_MAP(coreActivitiesPR)
+ ACTIVITY_MAP_ENTRY(PRDataClientJoinActivity, PRDataClientJoin)
+ ACTIVITY_MAP_ENTRY(PRControlClientJoinActivity, PRControlClientJoin)
+ ACTIVITY_MAP_ENTRY(PRClientLeaveActivity, PRClientLeave)
+ ACTIVITY_MAP_ENTRY(PRForwardStateChangeActivity, PRForwardStateChange)
+ ACTIVITY_MAP_ENTRY(PRBindToActivity, PRBindTo)
+ACTIVITY_MAP_END_BASE(CoreActivities,coreActivitiesAll)
+
+//Activity Map provided by CorePr to be used by SCprs.
+//(it is further extended in CoreSCpr).
+DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesSCpr)
+ ACTIVITY_MAP_ENTRY(PRProvisionActivity, PrProvision)
+ ACTIVITY_MAP_ENTRY(PRStartActivity, PRStart)
+ ACTIVITY_MAP_ENTRY(PRStopActivity, PRStop)
+ ACTIVITY_MAP_ENTRY(PRDataClientStartActivity, PRDataClientStart)
+ ACTIVITY_MAP_ENTRY(PRDataClientStopActivity, PRDataClientStop)
+ ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle)
+ ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive)
+ ACTIVITY_MAP_ENTRY(PRDestroyActivity, PRDestroy)
+ ACTIVITY_MAP_ENTRY(PRGoneDownActivity, PRGoneDown)
+ ACTIVITY_MAP_ENTRY(PRGoneUpActivity, PRGoneUp) //robertomaro
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+ ACTIVITY_MAP_ENTRY(PRSetParamsRequest, PRSetParams)
+ ACTIVITY_MAP_ENTRY(PRGetParamsRequest, PRGetParams)
+#endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+ ACTIVITY_MAP_ENTRY(PRLegacyRMessage2HandlerActivity, PRLegacyRMessage2Handler)
+ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
+
+//Activity Map provided by CorePr to be used by Cprs.
+//(it is further extended in CoreCpr).
+DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesCpr)
+ ACTIVITY_MAP_ENTRY(PRProvisionActivity, PrProvision)
+ ACTIVITY_MAP_ENTRY(PRStartActivity, PRStart)
+ ACTIVITY_MAP_ENTRY(PRStopActivity, PRStop)
+ ACTIVITY_MAP_ENTRY(PRDataClientStartActivity, PRDataClientStart)
+ ACTIVITY_MAP_ENTRY(PRDataClientStopActivity, PRDataClientStop)
+ ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle)
+ ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive)
+ ACTIVITY_MAP_ENTRY(PRDestroyActivity, PRDestroy)
+ ACTIVITY_MAP_ENTRY(PRGoneDownActivity, PRGoneDown)
+ ACTIVITY_MAP_ENTRY(PRGoneUpActivity, PRGoneUp) //robertomaro
+ ACTIVITY_MAP_ENTRY(PRDataClientStatusChangeActivity, PRDataClientStatusChange)
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+ ACTIVITY_MAP_ENTRY(PRSetParamsRequest, PRSetParams)
+ ACTIVITY_MAP_ENTRY(PRGetParamsRequest, PRGetParams)
+#endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+ ACTIVITY_MAP_ENTRY(PRLegacyRMessage2HandlerActivity, PRLegacyRMessage2Handler)
+ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
+
+//Activity Map provided by CorePr to be used by MCprs.
+//(it is further extended in CoreMCpr).
+DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesMCpr)
+ ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle)
+ ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive)
+ ACTIVITY_MAP_ENTRY(PRDataClientStatusChangeActivity, PRDataClientStatusChange)
+ ACTIVITY_MAP_ENTRY(PRLegacyRMessage2HandlerActivity, PRLegacyRMessage2Handler)
+ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
+
+//Activity Map provided by CorePr to be used by TMs.
+//(it is further extended in CoreTM).
+DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesTM)
+ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
+
+
+
+
+//-=========================================================
+//
+//CBindToActivity
+//
+//-=========================================================
+EXPORT_C CBindToActivity::CBindToActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TInt aNextActivityCount)
+ : MeshMachine::CNodeParallelActivityBase(aActivitySig, aNode, aNextActivityCount),
+ CoreActivities::ABindingActivity(aNode.Id()),
+ TIfStaticFetcherNearestInHierarchy(this)
+ {
+ }
+
+EXPORT_C MeshMachine::CNodeActivityBase* CBindToActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ //there can be only one BindTo activity running at a time.
+ TUint c = GetNextActivityCountL(aActivitySig,aNode);
+ __ASSERT_DEBUG(c == 1,User::Panic(KCorePrPanic, KPanicPeerMisbehaving));
+ if (c > 1)
+ {
+ User::Leave(KErrInUse);
+ }
+ return new (ELeave) CBindToActivity(aActivitySig, aNode, c);
+ }
+
+EXPORT_C CBindToActivity::~CBindToActivity()
+ {
+ //If the activity is aborted then no cleanup will be performed (the destroy activity will do
+ //that for us) so we should not assert that iSuccessfulDataClients is empty or iNewServiceProvider
+ //is null.
+
+ //CBindToActivity::TCommit or CBindToActivity::TCancel should have been executed
+ //and rendered iSuccessfulDataClients empty.
+ //__ASSERT_DEBUG(iSuccessfulDataClients.Count() == 0, User::Panic(KCorePrPanic, KPanicIncorrectState));
+
+ //CBindToActivity::iNewServiceProvider should have been cleared by CBindToActivity::TCommit or CBindToActivity::TCancel
+ //__ASSERT_DEBUG(iNewServiceProvider == NULL, User::Panic(KCorePrPanic, KPanicIncorrectState));
+
+ iSuccessfulDataClients.Close();
+ }
+
+Messages::RNodeInterface* CBindToActivity::NextDataClient()
+ {
+ TClientIter<TDefaultClientMatchPolicy> iter = iNode.GetClientIter<TDefaultClientMatchPolicy>(
+ /*include*/TClientType(TCFClientType::EData),
+ /*exclude*/TClientType(0, TCFClientType::ELeaving | TCFClientType::EConfigAccessPoint));
+ iCurrentDataClient = iter++;
+ while (iCurrentDataClient && (iSuccessfulDataClients.Find(iCurrentDataClient) != KErrNotFound))
+ {
+ iCurrentDataClient = iter++;
+ };
+ return iCurrentDataClient;
+ }
+
+TBool CBindToActivity::DataClientsAutocommit()
+ {
+ TInt nonLeavingDataClients = iNode.CountClients<TDefaultClientMatchPolicy>(
+ /*include*/TClientType(TCFClientType::EData),
+ /*exclude*/TClientType(0, TCFClientType::ELeaving | TCFClientType::EConfigAccessPoint));
+ return nonLeavingDataClients <=1 && IsAutocommit();
+ }
+
+
+void CBindToActivity::AddClientAsSuccessfulL(Messages::RNodeInterface* aDataClient)
+ {
+ __ASSERT_DEBUG(aDataClient, User::Panic(KCorePrPanic, KPanicDataClient));
+ __ASSERT_DEBUG(iSuccessfulDataClients.Find(aDataClient) == KErrNotFound, User::Panic(KCorePrPanic, KPanicIncorrectState));
+ iSuccessfulDataClients.Append(aDataClient);
+ }
+
+void CBindToActivity::RemoveClientFromSuccessful(Messages::RNodeInterface* aDataClient)
+ {
+ TInt index = iSuccessfulDataClients.Find(aDataClient);
+ __ASSERT_DEBUG(index >= 0, User::Panic(KCorePrPanic, KPanicDataClient));
+ iSuccessfulDataClients.Remove(index);
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TSendControlClientJoinRequest, NetStateMachine::MStateTransition, CBindToActivity::TContext)
+void CBindToActivity::TSendControlClientJoinRequest::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+ const TCFDataClient::TBindTo& bindToMsg(message_cast<const TCFDataClient::TBindTo>(iContext.iMessage));
+
+ __ASSERT_DEBUG(!bindToMsg.iNodeId.IsNull(), User::Panic(KCorePrPanic, KPanicNoServiceProvider));
+ RNodeInterface* newServiceProvider = iContext.Node().AddClientL(bindToMsg.iNodeId,
+ TClientType(TCFClientType::EServProvider, TCFClientType::EActivating));
+ __ASSERT_DEBUG(newServiceProvider, User::Panic(KCorePrPanic, KPanicNoServiceProvider));
+ activity.iNewServiceProvider = bindToMsg.iNodeId;
+ //Join the new service provider
+ iContext.Activity()->PostRequestTo(*newServiceProvider,
+ TCFControlClient::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::ECtrl)).CRef());
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TAwaitingBindToCompleteOrError, NetStateMachine::MState, CRejoinDataClientActivity::TContext)
+TBool CBindToActivity::TAwaitingBindToCompleteOrError::Accept()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+ if (CoreNetStates::TAwaitingBindToComplete(iContext).Accept())
+ {
+ if (activity.IsBinding())
+ {
+ //Activity is binding (i.e.: we havent received TBindToComplete as a response
+ //to null-carrying TBindTo.
+ activity.ReplyToOriginator(KErrNone);
+ }
+ activity.ResetCurrentDataClient();
+ return ETrue;
+ }
+ else if (iContext.iMessage.IsMessage<TEBase::TError>())
+ {
+ activity.ReplyToOriginator(message_cast<TEBase::TError>(iContext.iMessage).iValue);
+ activity.RemoveClientFromSuccessful(activity.CurrentDataClient());
+ activity.ResetCurrentDataClient();
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrDataClientReady, NetStateMachine::MStateFork, CBindToActivity::TContext)
+TInt CBindToActivity::TNoTagOrDataClientReady::TransitionTag()
+ {
+ //Any non-leaving dataclients already present?
+ if (iContext.Node().CountClients<TDefaultClientMatchPolicy>(
+ /*include*/TClientType(TCFClientType::EData),
+ /*exclude*/TClientType(0, TCFClientType::ELeaving | TCFClientType::EConfigAccessPoint)))
+ {
+ return KDataClientReady;
+ }
+ return KNoTag;
+ }
+
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TRequestCommsBinder, NetStateMachine::MStateTransition, CBindToActivity::TContext)
+void CBindToActivity::TRequestCommsBinder::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData)),User::Panic(KCorePrPanic, KPanicDataClient));
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+
+ //The service provider has been joined already and must be found here
+ __ASSERT_DEBUG(!activity.iNewServiceProvider.IsNull(), User::Panic(KCorePrPanic, KPanicNoServiceProvider));
+ RNodeInterface* newServiceProvider = iContext.Node().FindClient(activity.iNewServiceProvider);
+ __ASSERT_DEBUG(newServiceProvider, User::Panic(KCorePrPanic, KPanicNoServiceProvider));
+ //We must not be in this transition if dc was not found
+ __ASSERT_DEBUG(activity.CurrentDataClient(), User::Panic(KCorePrPanic, KPanicDataClient));
+
+ // Also if it is not so common to have multiple DataClient (except
+ // for the relation "SCPR<-CPR"), there are situation where it happens
+ // and where only one of them is marked as Default.
+ // So, we check if this is the case and, in case the
+ // Originator of this activity is NOT a Default one, send ECreateNew.
+
+ // If the Current DC is marked as Default, we ask to the lower layer
+ // to "AttachToDefault". If it is not, we ask "CreateNew".
+ TInt subConnOpenType = (activity.CurrentDataClient()->Flags() & TCFClientType::EDefault) ?
+ TSubConnOpen::EAttachToDefault : TSubConnOpen::ECreateNew;
+
+ // --- WORKAROUND START ---
+ // [399TODO] There are situation were we don't have any DataClient marked
+ // as Default, but, asking for ECreateNew, the lower layer doesn't
+ // manage the request very well.
+ // This is a WORKAROUND and need fixing (see DEF113154).
+ // In the meanwhile, we count the number of "DefaultDataClient" and,
+ // if the result is "0", we ask the lower layer "AttachToDefault"
+ TInt numberOfDefaultDataClient = iContext.Node().CountClients<TDefaultClientMatchPolicy>(
+ TClientType(TCFClientType::EData, TCFClientType::EDefault)
+ );
+ if (numberOfDefaultDataClient == 0)
+ {
+ subConnOpenType = TSubConnOpen::EAttachToDefault;
+ }
+ // --- WORKAROUND END ---
+
+ // Send "TCommsBinderRequest" to the Current ServiceProvider
+ activity.PostRequestTo(
+ *newServiceProvider,
+ TCFServiceProvider::TCommsBinderRequest(subConnOpenType).CRef()
+ );
+ }
+
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCreateDataClient, NetStateMachine::MStateTransition, CBindToActivity::TContext)
+void CBindToActivity::TCreateDataClient::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+
+ IssuePeerCreationRequestL ();
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TSendBindTo, NetStateMachine::MStateTransition, CBindToActivity::TContext)
+void CBindToActivity::TSendBindTo::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+
+ //Provisionally stash the current dataclient as successful. If it fails to bind, we'll unstash it
+ //We're doing this now, as stashing may fail and we don't want that to be the sole reason for
+ //unrolling.
+ bindToActivity.AddClientAsSuccessfulL(bindToActivity.CurrentDataClient());
+
+ TCFServiceProvider::TCommsBinderResponse* commsBinderResponse = message_cast<TCFServiceProvider::TCommsBinderResponse>(&iContext.iMessage);
+ Messages::TNodeId commsBinder = commsBinderResponse ? commsBinderResponse->iNodeId : Messages::TNodeId::NullId();
+
+ bindToActivity.PostRequestTo(*bindToActivity.CurrentDataClient(),
+ TCFDataClient::TBindTo(commsBinder, !bindToActivity.DataClientsAutocommit()).CRef());
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TSendBindToComplete, NetStateMachine::MStateTransition, CBindToActivity::TContext)
+void CBindToActivity::TSendBindToComplete::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ iContext.iNodeActivity->PostToOriginators(TCFDataClient::TBindToComplete().CRef());
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrCommit, NetStateMachine::MStateFork, CBindToActivity::TContext)
+TInt CBindToActivity::TNoTagOrCommit::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+ if (bindToActivity.IsAutocommit())
+ {
+ return KCommit;
+ }
+ return KNoTag;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrBindToComplete, NetStateMachine::MStateFork, CBindToActivity::TContext)
+EXPORT_C TInt CBindToActivity::TNoTagOrBindToComplete::TransitionTag()
+ {
+ TCFFactory::TPeerFoundOrCreated& dcJoined = message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage);
+
+ if (dcJoined.iNodeId.IsNull())
+ {
+ //Factory decided not to create a dataclient;
+ return KBindToComplete;
+ }
+
+ //factory created a new citizen.
+ return KNoTag;
+ }
+
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrBearerReady, NetStateMachine::MStateFork, CBindToActivity::TContext)
+TInt CBindToActivity::TNoTagOrBearerReady::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+ TCFDataClient::TBindTo& bindToReq = message_cast<TCFDataClient::TBindTo>(iContext.iMessage);
+ bindToActivity.SetAutocommit(!bindToReq.iValue);
+
+ if (bindToReq.iNodeId.IsNull())
+ //received a null service provider, the node is at the stack's bottom.
+ {
+ return KBearerReady;
+ }
+
+ RNodeInterface* sp = iContext.Node().ServiceProvider();
+ if (sp && bindToReq.iNodeId == sp->RecipientId())
+ {
+ //received the same service provider, it's already bound to.
+ bindToActivity.iNewServiceProvider = sp->RecipientId();
+ return KBearerReady;
+ }
+ RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToReq.iNodeId);
+ if (newServiceProvider)
+ {
+ __ASSERT_DEBUG(newServiceProvider->Type() == TCFClientType::EServProvider, User::Panic(KCorePrPanic, KPanicIncorrectState));
+ //Ok, we've received a TBindTo holding a service provider that we already know of and that is not
+ //our current service provider. We're going to assume this node tolerates multiple service providers (like MCPRs do).
+ //the current service provider will be swapped, but won't be dropped.
+ bindToActivity.iNewServiceProvider = bindToReq.iNodeId;
+ newServiceProvider->SetFlags(TCFClientType::EActivating);
+ bindToActivity.SetDontLeaveServiceProvider();
+ return KBearerReady;
+ }
+ else
+ {
+ bindToActivity.iNewServiceProvider = TNodeId::NullId();
+ }
+ //The node received a new service provider...
+ return KNoTag;
+ }
+
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrBearerReadyOrBindToComplete, NetStateMachine::MStateFork, CBindToActivity::TContext)
+TInt CBindToActivity::TNoTagOrBearerReadyOrBindToComplete::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+
+ if (!bindToActivity.NextDataClient())
+ {
+ //No more dataclients to bind
+ return KBindToComplete;
+ }
+
+ if (bindToActivity.iNewServiceProvider.IsNull())
+ {
+ //There is no service provider (new or old) below us.
+ return KBearerReady;
+ }
+
+ return KNoTag;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCommit, NetStateMachine::MStateTransition, CBindToActivity::TContext)
+void CBindToActivity::TCommit::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+
+ TInt count = bindToActivity.DataClientsAutocommit() ? 0 : bindToActivity.iSuccessfulDataClients.Count();
+ while (count )
+ {
+ bindToActivity.PostRequestTo(*bindToActivity.iSuccessfulDataClients[--count], TCFDataClient::TCommitBindTo().CRef());
+ };
+ bindToActivity.iSuccessfulDataClients.Reset();
+ RNodeInterface* sp = iContext.Node().ServiceProvider();
+
+ if (sp && sp->RecipientId() != bindToActivity.iNewServiceProvider)
+ {
+ if (bindToActivity.ShouldLeaveServiceProvider())
+ {
+ bindToActivity.PostRequestTo(*sp, TEPeer::TLeaveRequest().CRef());
+ sp->SetFlags(TCFClientType::ELeaving);
+ }
+ else
+ {
+ //Didn't leave, no need for waiting for TLeaveComplete;
+ bindToActivity.SetIdle();
+ }
+ sp->ClearFlags(TCFClientType::EActive);
+ }
+ else
+ {
+ //Didn't leave, no need for waiting for TLeaveComplete;
+ bindToActivity.SetIdle();
+ }
+
+ if (!bindToActivity.iNewServiceProvider.IsNull() && (sp == NULL || sp->RecipientId() != bindToActivity.iNewServiceProvider))
+ {
+ RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToActivity.iNewServiceProvider);
+ if (newServiceProvider)
+ {
+ __ASSERT_DEBUG(newServiceProvider->Flags() & TCFClientType::EActivating, User::Panic(KCorePrPanic, KPanicIncorrectState));
+ newServiceProvider->ClearFlags(TCFClientType::EActivating);
+ newServiceProvider->SetFlags(TCFClientType::EActive);
+ // Note: iContext.Node().ServiceProvider() must be re-evaluated in the ASSERT below (i.e. don't use any previously cached value).
+ __ASSERT_DEBUG(iContext.Node().ServiceProvider() == newServiceProvider, User::Panic(KCorePrPanic, KPanicIncorrectState));
+ }
+ }
+ bindToActivity.iNewServiceProvider = TNodeId::NullId();
+ }
+
+EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCancel, NetStateMachine::MStateTransition, CBindToActivity::TContext)
+void CBindToActivity::TCancel::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
+ TInt count = bindToActivity.iSuccessfulDataClients.Count();
+ while (count )
+ {
+ bindToActivity.PostRequestTo(*bindToActivity.iSuccessfulDataClients[--count], TEBase::TCancel().CRef());
+ };
+ bindToActivity.iSuccessfulDataClients.Reset();
+
+ TBool setIdle = ETrue;
+ if (!bindToActivity.iNewServiceProvider.IsNull())
+ {
+ RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToActivity.iNewServiceProvider);
+ if (newServiceProvider && newServiceProvider != iContext.Node().ServiceProvider())
+ {
+ __ASSERT_DEBUG(newServiceProvider->Flags() & TCFClientType::EActivating, User::Panic(KCorePrPanic, KPanicIncorrectState));
+ newServiceProvider->ClearFlags(TCFClientType::EActivating);
+ if (bindToActivity.ShouldLeaveServiceProvider())
+ {
+ bindToActivity.PostRequestTo(*newServiceProvider, TEPeer::TLeaveRequest().CRef());
+ newServiceProvider->SetFlags(TCFClientType::ELeaving);
+ setIdle = EFalse;
+ }
+ }
+ }
+
+ if (setIdle)
+ {
+ bindToActivity.SetIdle();
+ }
+ bindToActivity.iNewServiceProvider = TNodeId::NullId();
+ }
+
+
+//-=========================================================
+//
+//Rejoin DataClient Activity
+//
+//-=========================================================
+EXPORT_C MeshMachine::CNodeActivityBase* CRejoinDataClientActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ TUint c = GetNextActivityCountL(aActivitySig,aNode);
+ return new(ELeave)CRejoinDataClientActivity(aActivitySig, c, aNode);
+ }
+
+CRejoinDataClientActivity::~CRejoinDataClientActivity()
+ {
+ if ( iDataClients.Count() )
+ {
+ if (Error() != KErrNone)
+ {
+ //An error has occured when processing rejoin as the activity hasn't been properly wrapped
+ //up. This error must have happened before any of the clients have been added to the new
+ //owner as such addition must either collectively succeed or collectively fail. Reinstall
+ //clients in at the current owner.
+ for (TInt i = 0; i < iDataClients.Count(); i++)
+ {
+ if (!(iDataClients[i].iDataClient.Flags() & TCFClientType::EActive))
+ {
+#ifndef __GCCXML__
+ //If the dataclient managed to report idle in the mean time, have him destroyed
+ RClientInterface::OpenPostMessageClose(iNode.Id(), iDataClients[i].iDataClient.RecipientId(), TEChild::TDestroy().CRef());
+#endif
+ }
+ iDataClients[i].iDataClient.ClearFlags(TCFClientType::EActivating);
+#ifndef __GCCXML__
+ //Simulate client leaving on the new owner.
+ RClientInterface::OpenPostMessageClose(iDataClients[i].iDataClient.RecipientId(), iDataClients[i].iNewOwner,
+ TEChild::TLeft().CRef());
+#endif
+ }
+ }
+ else
+ {
+ //All clear. Remove the clients for good.
+ for (TInt i = 0; i < iDataClients.Count(); i++)
+ {
+ iNode.RemoveClient(iDataClients[i].iDataClient.RecipientId());
+ }
+ }
+ }
+ iDataClients.Reset();
+ }
+
+
+void CRejoinDataClientActivity::TCFDataClientJoiningRequest::DispatchL(const TRuntimeCtxId& aSender, const TRuntimeCtxId& aRecipient)
+ {
+ const TNodeId& nodeId = address_cast<const TNodeId>(aRecipient); //This message type operates on nodes
+ MeshMachine::AMMNodeBase* nodeBase = reinterpret_cast<MeshMachine::AMMNodeBase*>(nodeId.Node().FetchNodeInterfaceL(AMMNodeBase::KInterfaceId));
+ RNodeInterface* client = NULL;
+ client = nodeBase->AddClientL(iDataClient, iDataClientType);
+ client->SetFlags(TCFClientType::EJoining|TCFClientType::EStarted);
+ RClientInterface::OpenPostMessageClose(nodeId, aSender, TCFPeer::TJoinComplete().CRef());
+ }
+
+
+EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TAwaitingJoinComplete, NetStateMachine::MState, CRejoinDataClientActivity::TContext)
+TBool CRejoinDataClientActivity::TAwaitingJoinComplete::Accept()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 13));
+ if (iContext.iMessage.IsMessage<TCFPeer::TJoinComplete>())
+ {
+ return ETrue;
+ }
+ else if (iContext.iMessage.IsMessage<TEBase::TError>())
+ {
+ iContext.iNodeActivity->SetError(message_cast<TEBase::TError>(iContext.iMessage).iValue);
+ iContext.iNodeActivity->SetIdle();
+ iContext.iMessage.ClearMessageId();
+ }
+ return EFalse;
+ }
+
+
+EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TRejoinDataClient, NetStateMachine::MStateTransition, CRejoinDataClientActivity::TContext)
+EXPORT_C void CRejoinDataClientActivity::TRejoinDataClient::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 14));
+ CRejoinDataClientActivity* rejoinActivity = static_cast<CRejoinDataClientActivity*>(iContext.iNodeActivity);
+
+ TCFRejoiningProvider::TRejoinDataClientRequest& rejoinDCMsg = message_cast<TCFRejoiningProvider::TRejoinDataClientRequest>(iContext.iMessage);
+ RNodeInterface* subject = iContext.Node().FindClient(rejoinDCMsg.iNodeId1);
+ if (NULL == subject //client not found
+ || subject->Flags() & TCFClientType::ELeaving //client leaving/gone
+ || !(subject->Flags() & TCFClientType::EActive)) //client reported idle or never bound to
+ {
+ User::Leave(KErrNotFound);
+ }
+ if (subject->Flags() & TCFClientType::EActivating) //client requested by someone
+ {
+ User::Leave(KErrInUse);
+ }
+
+ rejoinActivity->iDataClients.AppendL(TMigrationPairs(*subject, rejoinDCMsg.iNodeId2));
+
+ CRejoinDataClientActivity::TCFDataClientJoiningRequest msg(subject->RecipientId(), subject->ClientType());
+
+ RClientInterface::OpenPostMessageClose(
+ iContext.NodeId(),
+ rejoinDCMsg.iNodeId2,
+ msg);
+
+ //Set Client being migrated to a new owner.. reference handed over. secure lifetime.
+ subject->SetFlags(TCFClientType::EActivating);
+ }
+
+EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TApplyRejoin, NetStateMachine::MStateTransition, CRejoinDataClientActivity::TContext)
+void CRejoinDataClientActivity::TApplyRejoin::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 15));
+ CRejoinDataClientActivity* rejoinActivity = static_cast<CRejoinDataClientActivity*>(iContext.iNodeActivity);
+ __ASSERT_DEBUG(rejoinActivity->iDataClients.Count(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 16));
+ for (TInt i = 0; i < rejoinActivity->iDataClients.Count(); i++)
+ {
+ RClientInterface::OpenPostMessageClose(iContext.NodeId(), rejoinActivity->iDataClients[i].iDataClient.RecipientId(),
+ TCFFlow::TRejoin(rejoinActivity->iDataClients[i].iNewOwner).CRef());
+ rejoinActivity->iDataClients[i].iDataClient.SetFlags(TCFClientType::ELeaving);
+ }
+ rejoinActivity->PostRequestTo(iContext.NodeId(), TCFScpr::TApplyRequest().CRef());
+ }
+
+EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TRejoinLoopTag,NetStateMachine::MStateFork, CRejoinDataClientActivity::TContext)
+EXPORT_C TInt CRejoinDataClientActivity::TRejoinLoopTag::TransitionTag()
+ {
+ if (iContext.iMessage.IsMessage<TCFRejoiningProvider::TRejoinDataClientRequest>())
+ {
+ return CoreStates::KLoopTag | NetStateMachine::EBackward;
+ }
+ return MeshMachine::KNoTag | NetStateMachine::EForward;
+ }
+
+//-=========================================================
+//
+// CommsBinderActivity (parallel)
+//
+//-=========================================================
+
+EXPORT_C MeshMachine::CNodeActivityBase* CCommsBinderActivity::NewL( const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode )
+ {
+ TUint c = GetNextActivityCountL(aActivitySig,aNode);
+ return new(ELeave)CCommsBinderActivity(aActivitySig, aNode, c);
+ }
+
+EXPORT_C CCommsBinderActivity::CCommsBinderActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TUint aNextActivityCount)
+: MeshMachine::CNodeRetryParallelActivity(aActivitySig, aNode, aNextActivityCount),
+ TIfStaticFetcherNearestInHierarchy(this)
+ {
+ }
+
+//-=========================================================
+//
+// CCommsBinderActivity
+//
+// Aggregate class containing common functionality for
+// CommsBinderActivity and CCommsBinderCombiningActivity.
+//
+//-=========================================================
+
+EXPORT_C TBool CCommsBinderActivity::TDataClientMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext)
+ {
+ TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId());
+ __ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 17)); //Diagnostic
+ if (c == 1 || CCommsBinderActivity::IsDataClientPresent(aContext))
+ {
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+EXPORT_C TBool CCommsBinderActivity::TDefaultDataClientMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext)
+ {
+ TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId());
+ __ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 18)); //Diagnostic
+ if (c == 1 || CCommsBinderActivity::IsDataClientPresent(aContext, TCFClientType::EDefault))
+ {
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+EXPORT_C /*virtual*/ CCommsBinderActivity::~CCommsBinderActivity()
+ {
+ if(!iBinderRequestParameters.IsNull())
+ {
+ iBinderRequestParameters.Close();
+ }
+ }
+
+EXPORT_C void CCommsBinderActivity::StoreBinder(RNodeInterface* aDataClient)
+ {
+ __ASSERT_DEBUG(iPendingBinder == aDataClient || iPendingBinder == NULL, User::Panic(KSpecAssert_ESockCrStaCPRAC, 19));
+ iPendingBinder = aDataClient;
+ }
+
+EXPORT_C RNodeInterface* CCommsBinderActivity::Binder() const
+ {
+ return iPendingBinder;
+ }
+
+EXPORT_C void CCommsBinderActivity::StoreBinderRequestParameters(const RCFParameterFamilyBundleC& aBinderRequestParameters)
+ {
+ __ASSERT_DEBUG(iBinderRequestParameters.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 20));
+ if(! aBinderRequestParameters.IsNull())
+ {
+ iBinderRequestParameters.Open(aBinderRequestParameters);
+ }
+ }
+
+void CCommsBinderActivity::SendCustomFlowProvision()
+/**
+Send a custom message that provisions a flow with flow parameters
+*/
+ {
+ __ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 21));
+
+ // Only send the message if we have parameters to send
+ if(!iBinderRequestParameters.IsNull())
+ {
+ RParameterFamily parameterFamily =
+ iBinderRequestParameters.FindFamily(KFlowParametersFamily);
+
+ if(!parameterFamily.IsNull())
+ {
+ STypeId typeId = STypeId::CreateSTypeId(CFlowRequestParameters::EUid, CFlowRequestParameters::EType);
+ CFlowRequestParameters* flowParams = static_cast<CFlowRequestParameters*>(parameterFamily.FindParameterSet(typeId, RParameterFamily::ERequested));
+
+ iPendingBinder->PostMessage(
+ iNode.Id(),
+ TCFInternalEsock::TFlowProvision(
+ flowParams->GetFlowParams()
+ ).CRef()
+ );
+ }
+ }
+ }
+
+
+void CCommsBinderActivity::SendBinderResponseToOriginator()
+/**
+Send out CommsBinderResponse to all originators.
+
+We send to all originators that have joined up until this point, and store this count
+in iOriginatorsCountSnapshot. See comment in ProcessBindToComplete().
+*/
+ {
+ __ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 22));
+
+ PostRequestTo(
+ address_cast<Messages::TNodeId>(FirstOriginator().RecipientId()),
+ TCFServiceProvider::TCommsBinderResponse(iPendingBinder->RecipientId()).CRef());
+
+ iPendingBinder->SetFlags(TCFClientType::EActivating);
+ }
+
+void CCommsBinderActivity::BindToComplete()
+ {
+ __ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 23));
+ TUint c = iNode.CountActivities(ActivitySigId());
+ // Note: this routine can be used with parallel and non-parallel binder activities. In the
+ // former case we start with multiple activities and eventually end up with a single one. In
+ // the latter case we have a single activity throughout.
+ if(c == 1)
+ {
+ iPendingBinder->ClearFlags(TCFClientType::EActivating);
+ }
+ iPendingBinder = NULL;
+ }
+
+//
+// CCommsBinderActivity methods that are embedded transitions/states/stateforks
+//
+
+EXPORT_C RNodeInterface* CCommsBinderActivity::IsDataClientPresent(TNodeContextBase& aContext, TUint aClientFlags)
+/**
+Check if we have a data client and, if so, store it as the binder for this activity.
+
+@param aContext Node context
+@param aClientFlags client flags to use in iterator check
+@return ETrue if data client present, else EFalse.
+*/
+ {
+ // Be careful not to use a client to which we have already sent TDestroy previously.
+ // Find the first data client that does not have the ELeaving flag set. If all are
+ // marked ELeaving then return EFalse - they are on the way out and will disappear
+ // eventually. The effect will be that a new data client will be created.
+ RNodeInterface* dataClient = aContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, aClientFlags), TClientType(0, TCFClientType::ELeaving));
+ return dataClient;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TNoTagOrUseExisting, NetStateMachine::MStateFork, CCommsBinderActivity::TContext)
+EXPORT_C TInt CCommsBinderActivity::TNoTagOrUseExisting::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 24));
+ TCFServiceProvider::TCommsBinderRequest& msg = message_cast<TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage);
+
+ // Save away the parameters sent to us so that they are accessible during the activity
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+ CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+ intf->StoreBinderRequestParameters(msg.iFamilyBundle);
+
+ if(msg.iValue == TSubConnOpen::EAttachToDefault)
+ {
+ RNodeInterface* dc = CCommsBinderActivity::IsDataClientPresent(iContext);
+ if (dc)
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+ CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+
+ intf->StoreBinder(dc);
+ return CoreStates::KUseExisting;
+ }
+ }
+ return MeshMachine::KNoTag;
+ }
+
+//MZTODO - logic of:
+//TNoTagOrWaitForIncomingOrUseExisting
+//&
+//TNoTagOrWaitForIncomingOrUseExistingDefault
+//has been copied but does not seem right, as both use EDefault?
+//Why?
+
+//[401TODO] DL : Only one of TNoTagOrWaitForIncomingOrUseExisting(Default) is used, is it ok to nuke one?
+
+EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExisting, NetStateMachine::MStateFork, CCommsBinderActivity::TContext)
+EXPORT_C TInt CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExisting::TransitionTag()
+ {
+ TCFServiceProvider::TCommsBinderRequest& msg = message_cast<TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage);
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 25));
+
+ if (msg.iValue == TSubConnOpen::EWaitForIncoming)
+ {
+ return CoreNetStates::KWaitForIncoming;
+ }
+
+ else
+ {
+ RNodeInterface* dc = CCommsBinderActivity::IsDataClientPresent(iContext, TCFClientType::EDefault);
+ if (dc)
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+ CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+
+ intf->StoreBinder(dc);
+ return CoreStates::KUseExisting;
+ }
+ }
+
+ return MeshMachine::KNoTag;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExistingDefault, NetStateMachine::MStateFork, CCommsBinderActivity::TContext)
+EXPORT_C TInt CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExistingDefault::TransitionTag()
+ {
+ TCFServiceProvider::TCommsBinderRequest& msg = message_cast<TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage);
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 26));
+
+ if(msg.iValue == TSubConnOpen::EAttachToDefault)
+ {
+ RNodeInterface* dc = CCommsBinderActivity::IsDataClientPresent(iContext, TCFClientType::EDefault);
+ if (dc)
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+ CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+
+ intf->StoreBinder(dc);
+ return CoreStates::KUseExisting;
+ }
+ }
+ else if (msg.iValue == TSubConnOpen::EWaitForIncoming)
+ {
+ return CoreNetStates::KWaitForIncoming;
+ }
+ return MeshMachine::KNoTag;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TStorePendingBinder, NetStateMachine::MStateTransition, CCommsBinderActivity::TContext)
+EXPORT_C void CCommsBinderActivity::TStorePendingBinder::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 27));
+ message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage);
+
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+ CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+
+ intf->StoreBinder(iContext.iPeer);
+ }
+
+EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TSendBinderResponse, NetStateMachine::MStateTransition, CCommsBinderActivity::TContext)
+EXPORT_C void CCommsBinderActivity::TSendBinderResponse::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 28));
+
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+ CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+
+ intf->SendBinderResponseToOriginator();
+ }
+
+EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TSendCustomFlowProvision, NetStateMachine::MStateTransition, CCommsBinderActivity::TContext)
+EXPORT_C void CCommsBinderActivity::TSendCustomFlowProvision::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 29));
+
+ __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
+ CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+
+ intf->SendCustomFlowProvision();
+ }
+
+EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TAwaitingBindToComplete, NetStateMachine::MState, PRStates::TContext)
+EXPORT_C TBool CCommsBinderActivity::TAwaitingBindToComplete::Accept()
+ {
+ CoreNetStates::TAwaitingBindToComplete awaitingBindToComplete(iContext);
+ if (awaitingBindToComplete.Accept())
+ {
+ CCommsBinderActivity* binderActivity = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
+ __ASSERT_DEBUG(binderActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 30));
+ binderActivity->BindToComplete();
+ iContext.Node().DestroyOrphanedDataClients();
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+//-=========================================================
+//
+//CNoBearer Activity
+//
+//-=========================================================
+
+CNoBearer::CNoBearer(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TUint aActivitiesCount)
+: MeshMachine::CNodeRetryParallelActivity(aActivitySig, aNode, aActivitiesCount),
+ ABindingActivity(aNode.Id()),
+ TIfStaticFetcherNearestInHierarchy(this)
+ {
+ }
+
+/*virtual*/ CNoBearer::~CNoBearer()
+ {
+ iNoBearerParameters.Close();
+ }
+
+EXPORT_C MeshMachine::CNodeActivityBase* CNoBearer::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ TUint c = GetNextActivityCountL(aActivitySig,aNode);
+ return new(ELeave)CNoBearer(aActivitySig, aNode, c);
+ }
+
+EXPORT_C TNodePeerId& CNoBearer::GetOriginator()
+ {
+ __ASSERT_DEBUG(iOriginators.Count() == 1, User::Panic(KSpecAssert_ESockCrStaCPRAC, 31));
+ return iOriginators[0];
+ }
+
+EXPORT_C void CNoBearer::ReturnInterfacePtrL(CoreActivities::ABindingActivity*& aInterface)
+ {
+ aInterface = this;
+ }
+
+EXPORT_C TBool CNoBearer::TServiceProviderMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext)
+ {
+ TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId());
+ __ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 32)); //Diagnostic
+ if (c == 1 || aContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)) != 0)
+ {
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CNoBearer::TRequestCommsBinder, NetStateMachine::MStateTransition, CNoBearer::TContext)
+EXPORT_C void CNoBearer::TRequestCommsBinder::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CNoBearer& noBearer = static_cast<CNoBearer&>(*iContext.iNodeActivity);
+
+ RNodeInterface* sp = iContext.Node().ServiceProvider();
+ __ASSERT_DEBUG(sp, User::Panic(KCorePrPanic, KPanicNoServiceProvider));
+
+ TSubConnOpen::TSubConnType type = TSubConnOpen::EAttachToDefault;
+ if (!(noBearer.GetOriginator().Flags() & TCFClientType::EDefault))
+ {
+ type = TSubConnOpen::ECreateNew;
+ }
+
+ noBearer.PostRequestTo(
+ *sp,
+ TCFServiceProvider::TCommsBinderRequest(
+ type, noBearer.iNoBearerParameters
+ ).CRef()
+ );
+ }
+
+EXPORT_DEFINE_SMELEMENT(CNoBearer::TStoreRequestParameters, NetStateMachine::MStateTransition, CNoBearer::TContext)
+EXPORT_C void CNoBearer::TStoreRequestParameters::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CNoBearer& noBearer = static_cast<CNoBearer&>(*iContext.iNodeActivity);
+ const TCFControlProvider::TNoBearer& noBearerMessage = message_cast<TCFControlProvider::TNoBearer>(iContext.iMessage);
+ __ASSERT_DEBUG(noBearer.iNoBearerParameters.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 33)); // handle should be empty when this fn is called
+ if(noBearerMessage.iFamilyBundle.IsNull())
+ {
+ noBearer.iNoBearerParameters.Open();
+ }
+ else
+ {
+ noBearer.iNoBearerParameters.Open(noBearerMessage.iFamilyBundle);
+ }
+ }
+
+EXPORT_DEFINE_SMELEMENT(CNoBearer::TNoTagOrDataClientsToStart, NetStateMachine::MStateFork, CNoBearer::TContext)
+TInt CNoBearer::TNoTagOrDataClientsToStart::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CNoBearer& activity = static_cast<CNoBearer&>(*iContext.iNodeActivity);
+
+ const TNodePeerId& originator = activity.GetOriginator();
+ __ASSERT_DEBUG(originator.Type() & TCFClientType::EData, User::Panic(KSpecAssert_ESockCrStaCPRAC, 34));
+
+ if (activity.Error() == KErrNone && (originator.Flags() & (TCFClientType::EStarting|TCFClientType::EStarted|TCFClientType::ELeaving)) == 0)
+ {
+ //Start dc
+ return CoreNetStates::KDataClientsToStart;
+ }
+ //Finish the activity
+ return MeshMachine::KNoTag;
+ }
+
+EXPORT_DEFINE_SMELEMENT(CNoBearer::TStartOriginatingDataClient, NetStateMachine::MStateTransition, CNoBearer::TContext)
+void CNoBearer::TStartOriginatingDataClient::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CNoBearer& activity = static_cast<CNoBearer&>(*iContext.iNodeActivity);
+ TNodePeerId& originator = activity.GetOriginator();
+ __ASSERT_DEBUG(originator.Type() & TCFClientType::EData, User::Panic(KSpecAssert_ESockCrStaCPRAC, 35));
+ activity.PostRequestTo(originator.Peer(), TCFDataClient::TStart().CRef());
+ originator.SetFlags(TCFClientType::EStarting);
+ }
+
+EXPORT_DEFINE_SMELEMENT(CNoBearer::TNoTagOrBearerPresent, NetStateMachine::MStateFork, CNoBearer::TContext)
+EXPORT_C TInt CNoBearer::TNoTagOrBearerPresent::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CNoBearer& noBearer = static_cast<CNoBearer&>(*iContext.iNodeActivity);
+ const TCFControlProvider::TNoBearer& noBearerMessage = message_cast<TCFControlProvider::TNoBearer>(iContext.iMessage);
+ __ASSERT_DEBUG(noBearer.iNoBearerParameters.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 36)); // should not yet be set when this fn is called
+ noBearer.iNoBearerParameters.Open(noBearerMessage.iFamilyBundle);
+
+ CoreNetStates::TNoTagOrBearerPresent fork(iContext);
+ return fork.TransitionTag();
+ }
+
+EXPORT_DEFINE_SMELEMENT(CNoBearer::TNoTagOrBearerPresentForAutostart, NetStateMachine::MStateFork, CNoBearer::TContext)
+EXPORT_C TInt CNoBearer::TNoTagOrBearerPresentForAutostart::TransitionTag()
+ {
+ TInt cntrlClients = iContext.Node().CountClients<TDefaultClientMatchPolicy>(
+ /*include*/TClientType(TCFClientType::ECtrl));
+ if (cntrlClients > 0 &&
+ iContext.Node().ServiceProvider() &&
+ !(iContext.Node().ServiceProvider()->Flags() & TCFClientType::EStarted))
+ {
+ //This fork calculates if the NoBearer activity (which this fork has been implemented for)
+ //should attempt to autostart the service provider when returning it to the sender of TNoBearer.
+ //The philosphy here is that if the local node doesn't have a control client, then there's noone
+ //that could posibly start it. It will hence decide to autostart as the top layer of what looks
+ //like an implicit connection. In the future this autostart behaviour should become a specialty
+ //of someone more concrete (rather than generic function). We are speculating about the implicit
+ //top layer that could acquire this function if it ever comes into being.
+ return CoreNetStates::KBearerPresent;
+ }
+ return KNoTag;
+ }
+
+
+//-=========================================================
+//
+//CStartActivity Activity
+//
+//-=========================================================
+CStartActivity::CStartActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ : MeshMachine::CNodeRetryActivity(aActivitySig, aNode),
+ CoreActivities::ABindingActivity(aNode.Id()),
+ TIfStaticFetcherNearestInHierarchy(this)
+ {
+ }
+
+EXPORT_C CStartActivity::~CStartActivity()
+ {
+ }
+
+EXPORT_C MeshMachine::CNodeActivityBase* CStartActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ return new (ELeave) CStartActivity(aActivitySig, aNode);
+ }
+
+//-=========================================================
+//
+//Gone Down Activity
+//
+//-=========================================================
+MeshMachine::CNodeActivityBase* CGoneDownActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ CGoneDownActivity* self = new (ELeave) CGoneDownActivity(aActivitySig,aNode);
+ return self;
+ }
+
+CGoneDownActivity::CGoneDownActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+: MeshMachine::CNodeRetryActivity(aActivitySig, aNode)
+ {
+ }
+
+CGoneDownActivity::~CGoneDownActivity()
+ {
+ //This is a gone down activity. Error mode is its only/natural state
+ //CGoneDownActivity inherits ultimatelly from CNodeActivityBase, which
+ //will attempt to interpret the error mode as a failure to execute (and
+ //auto respond to orignators), which we don't want. Hence clearing
+ //the error and allowing 'this' to die peacefully.
+ SetError(KErrNone);
+ }
+
+void CGoneDownActivity::StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& aOriginator, const TStateTriple& aFirst)
+ {
+ //399TODO: for the moment ignore duplicated TGoneDown messages
+ //but this needs to be fixed (someone is sending TGoneDown from TSendDataClientStopped
+ //hence the problem)
+
+ //ASSERT(IsIdle());
+ if (!IsIdle())
+ {
+ return;
+ }
+
+ //This activity provides service for only one single requestor at a time.
+ __ASSERT_DEBUG(iOriginators.Count()==0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 37)); //Diagnostic panic
+
+ TCFControlClient::TGoneDown& msg = message_cast<TCFControlClient::TGoneDown>(aContext.iMessage);
+ SetError(msg.iValue1);
+ iGoneDownApId = msg.iValue2;
+
+ MESH_LOG_ACTIVITY_EXT(KMeshMachineSubTag, this, &aContext, (_L8("CGoneDownActivity %08x:\tStartL->starting activity"), this));
+ NetStateMachine::ACore::Start(&aContext, aFirst);
+
+ MESH_LOG_ACTIVITY_EXT(KMeshMachineSubTag, this, &aContext, (_L8("CGoneDownActivity %08x:\tStartL->activity started"), this));
+ (void)aOriginator;
+ }
+
+//Find next DC to rebind
+TBool CGoneDownActivity::IsIdle() const
+ {
+ return NetStateMachine::ACore::IsIdle();
+ }
+
+DEFINE_SMELEMENT(CGoneDownActivity::TSendErrorRecoveryReq, NetStateMachine::MStateTransition, CGoneDownActivity::TContext)
+void CGoneDownActivity::TSendErrorRecoveryReq::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ CGoneDownActivity& activity = static_cast<CGoneDownActivity&>(*iContext.iNodeActivity);
+
+ //TInt error = ExtractErrorCode(iContext.iMessage);
+ TErrContext ctx(iContext.NodeId(), TCFControlClient::TGoneDown::Id(), activity.ActivitySigId(), TStateChange(0, activity.Error()));
+ ctx.iInfo = (TAny*)activity.iGoneDownApId;
+ TEErrorRecovery::TErrorRecoveryRequest msg(ctx);
+
+ //We can not set SetSentTo() to Control Provider, because the response may not be coming from it
+ //(for example it could be coming from the MCpr and we could be the SCpr).
+ //Normally this would be a problem because any unrelated TError message arriving to the node
+ //and presented to the awaiting state would easily be confused with the response (TError ==
+ //no recovery on the MCpr == EPropagate).
+ //We avoid the problem by checking all arriving TError messages if they are adressed to our activity.
+ __ASSERT_DEBUG(iContext.Node().ControlProvider(), User::Panic(KCorePrPanic, KPanicNoControlProvider));
+ activity.PostRequestTo(*iContext.Node().ControlProvider(),
+ TCFSafeMessage::TRequestCarrierEast<TEErrorRecovery::TErrorRecoveryRequest>(msg).CRef());
+ activity.ClearPostedTo();
+ }
+
+DEFINE_SMELEMENT(CGoneDownActivity::TIgnoreOrPropagate, NetStateMachine::MStateFork, CGoneDownActivity::TContext)
+TInt CGoneDownActivity::TIgnoreOrPropagate::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iMessage.IsMessage<TEErrorRecovery::TErrorRecoveryResponse>(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 38));
+ RNodeInterface* sp = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EStarted));
+ if (sp)
+ {
+ return CoreStates::KIgnore | NetStateMachine::EForward;
+ }
+ //There is no started service provider, the reconnection, mobility, etc must have failed,
+ //continue with tearing this layer down.
+ CGoneDownActivity& activity = static_cast<CGoneDownActivity&>(*iContext.iNodeActivity);
+ TErrResponse& resp = message_cast<TEErrorRecovery::TErrorRecoveryResponse>(iContext.iMessage).iErrResponse;
+ resp.iAction=TErrResponse::EPropagate;
+ __ASSERT_DEBUG(activity.Error()!=KErrNone, User::Panic(KSpecAssert_ESockCrStaCPRAC, 39));
+ resp.iError = activity.Error();
+ return CoreStates::KPropagate | NetStateMachine::EForward;
+ }
+
+
+EXPORT_DEFINE_SMELEMENT(CStartActivity::TAwaitingBindToCompleteOrCancel, NetStateMachine::MState, CStartActivity::TContext)
+TBool CStartActivity::TAwaitingBindToCompleteOrCancel::Accept()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
+ if (iContext.iMessage.IsMessage<TEBase::TCancel>())
+ {
+ iContext.iNodeActivity->SetError(KErrCancel);
+ iContext.iMessage.ClearMessageId();
+ return EFalse;
+ }
+ else
+ {
+ CoreNetStates::TAwaitingBindToComplete state(iContext);
+ return state.Accept();
+ }
+ }
+} //PRActivities
+
+EXPORT_DEFINE_SMELEMENT(PRDataClientStopActivity::TNoTagOrProviderStopped, NetStateMachine::MStateFork, PRDataClientStopActivity::TContext)
+EXPORT_C TInt PRDataClientStopActivity::TNoTagOrProviderStopped::TransitionTag()
+ {
+ iContext.iNodeActivity->SetError(message_cast<TCFDataClient::TStop>(iContext.iMessage).iValue);
+ if (iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(
+ TClientType(TCFClientType::EData, TCFClientType::EStarted)) != NULL)
+ {
+ // At least one started data client
+ return MeshMachine::KNoTag;
+ }
+ return CoreNetStates::KProviderStopped;
+ }
+
+
+
--- a/datacommsserver/esockserver/core_states/ss_corepractivities.h Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/core_states/ss_corepractivities.h Thu Jan 07 13:34:53 2010 +0200
@@ -174,6 +174,7 @@
protected:
CDestroyActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode);
virtual void Destroy();
+ virtual TBool Next(MeshMachine::TNodeContextBase& aContext);
//States, StateForks & StateTransitions
protected:
@@ -435,7 +436,9 @@
IMPORT_C CBindToActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TInt aNextActivityCount);
protected:
- Messages::RNodeInterface* iNewServiceProvider;
+ // We cannot store iNewServiceProvider as an RNodeInterface* in case an activity (like GoneDown) executes simultaneously and removes
+ // the client we hold a reference to. Hence use the NodeId and lookup the corresponding RNodeInterface* as and when required.
+ Messages::TNodeId iNewServiceProvider;
private:
Messages::RNodeInterface* iCurrentDataClient;
RPointerArray<Messages::RNodeInterface> iSuccessfulDataClients;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/debug/documentation/DISTRIBUTION.POLICY Thu Jan 07 13:34:53 2010 +0200
@@ -0,0 +1,2 @@
+Category T
+OSD: Reference/Test Tools
--- a/datacommsserver/esockserver/group/BLD.INF Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/group/BLD.INF Thu Jan 07 13:34:53 2010 +0200
@@ -234,5 +234,5 @@
#endif
PRJ_TESTMMPFILES
-#include "../test/bld.inf"
+//#include "../test/bld.inf"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/group/BLD.INF~ Thu Jan 07 13:34:53 2010 +0200
@@ -0,0 +1,238 @@
+// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Sockets/Networking Server
+//
+//
+
+/**
+ @file
+*/
+
+#define SYMBIAN_NETWORKING_UPS
+
+
+PRJ_PLATFORMS
+
+DEFAULT
+
+PRJ_EXPORTS
+
+../core_states/ss_esockstates.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_esockstates.h)
+../core_states/ss_esockactivities.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_esockactivities.h)
+../core_states/ss_coreprstates.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_coreprstates.h)
+../core_states/ss_corepractivities.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_corepractivities.h)
+
+../csock/SOCKMES.H SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/sockmes.h)
+
+../inc/es_connectionservermessages.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/es_connectionservermessages.h)
+
+../eintsock/eintsock.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/eintsock.h)
+../inc/ss_intsock.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_intsock.h)
+
+../group/esock.iby /epoc32/rom/include/esock.iby
+../group/esock_core.iby /epoc32/rom/include/esock_core.iby
+
+../inc/ss_DataMonitoringProvider.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_datamonitoringprovider.h)
+../inc/ConnPref.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(connpref.h)
+../inc/es_commsdataobject.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/es_commsdataobject.h)
+../inc/es_accesspointstatus.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/es_accesspointstatus.h)
+../inc/es_availability.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/es_availability.h)
+../inc/es_config.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/es_config.h)
+../inc/es_connectionserv.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/es_connectionserv.h)
+../inc/es_connectionservparameterbundle.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/es_connectionservparameterbundle.h)
+../inc/es_connectionservparameterbundletrace.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/es_connectionservparameterbundletrace.h)
+../inc/es_connectionservparameterbundletraceimpl.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/es_connectionservparameterbundletraceimpl.h)
+../inc/es_connPref.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_connpref.h)
+../inc/es_enum.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(es_enum.h)
+../inc/es_enum.inl SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_enum.inl)
+../inc/ES_INI.H SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_ini.h)
+../inc/es_mbufif.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_mbufif.h)
+../inc/es_notq.inl SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_notq.inl)
+../inc/es_panic.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(es_panic.h)
+../inc/es_parameterset.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/es_parameterset.h)
+../inc/es_event.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/es_event.h)
+../inc/ss_protopt.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/ss_protopt.h)
+../inc/es_parameterbundle.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/es_parameterbundle.h)
+../inc/es_parameterfamily.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/es_parameterfamily.h)
+../inc/es_parameterfamily.inl SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/es_parameterfamily.inl)
+../inc/ES_PROT.H SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_prot.h)
+../inc/ES_PROT.INL SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_prot.inl)
+../inc/es_protbinder.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/es_protbinder.h)
+../inc/es_prov.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_prov.h)
+../inc/es_sap.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/es_sap.h)
+../inc/ES_SOCK.H SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(es_sock.h)
+../inc/ES_SOCK.INL SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_sock.inl)
+../inc/ES_VER.H SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(es_ver.h)
+../inc/ss_activities.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_activities.h)
+../inc/ss_common.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/ss_common.h)
+../inc/ss_commsprov.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_commsprov.h)
+../inc/ss_commsprov_internal.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/ss_commsprov_internal.h)
+../inc/ss_api_ext.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_api_ext.h)
+../inc/ss_apiext_register.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/ss_apiext_register.h)
+../inc/ss_connLegacy.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/ss_connlegacy.h)
+../inc/ss_connprov.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/ss_connprov.h)
+../inc/ss_connselect.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/ss_connselect.h)
+../inc/ss_connsettings.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/ss_connsettings.h)
+../inc/ss_cprnodeinterfaces.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/ss_cprnodeinterfaces.h)
+../inc/ss_datatransfer.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/ss_datatransfer.h)
+../inc/ss_fact.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ss_fact.h)
+../inc/ss_fact_internal.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/ss_fact_internal.h)
+../inc/ss_factorycontainermap.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/ss_factorycontainermap.h)
+../inc/ss_flowbinders.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_flowbinders.h)
+../inc/ss_flowbinders_internal.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_flowbinders_internal.h)
+../inc/SS_GLOB.H SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ss_glob.h)
+../inc/ss_log.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_log.h)
+../inc/ss_logext.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_logext.h)
+../inc/ss_mcprnodemessages.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_mcprnodemessages.h)
+../inc/ss_metaconnprov.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_metaconnprov.h)
+../inc/ss_metaconnprov_internal.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_metaconnprov_internal.h)
+../inc/ss_mmcommsprov.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_mmcommsprov.h)
+../inc/ss_mmnode.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_mmnode.h)
+../inc/ss_mmnode_subsess.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_mmnode_subsess.h)
+../inc/ss_nodeinterfaces.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodeinterfaces.h)
+../inc/ss_dispatchers.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_dispatchers.h)
+../inc/ss_nodemessages.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages.h)
+../inc/ss_nodemessages_internal.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_internal.h)
+../inc/ss_nodemessages_legacy.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_legacy.h)
+../inc/ss_nodemessages_legacy_internal.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_legacy_internal.h)
+../inc/ss_nodemessages_dataclient.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_dataclient.h)
+../inc/ss_nodemessages_peer.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_peer.h)
+../inc/ss_nodemessages_mobility.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_mobility.h)
+../inc/ss_nodemessages_availability.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_availability.h)
+../inc/ss_nodemessages_serviceprovider.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_serviceprovider.h)
+../inc/ss_nodemessages_subconn.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_subconn.h)
+../inc/ss_nodemessages_rejoiningprovider.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_rejoiningprovider.h)
+../inc/ss_nodemessages_selector.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_selector.h)
+../inc/ss_nodemessages_ipmessages.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_ipmessages.h)
+../inc/ss_nodemessages_flow.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_flow.h)
+../inc/ss_nodemessages_internal_esock.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_internal_esock.h)
+../inc/ss_nodemessages_parameters.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_parameters.h)
+../inc/ss_nodemessages_factory.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_factory.h)
+../inc/ss_nodemessages_tiermanagerfactory.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_tiermanagerfactory.h)
+../inc/ss_nodemessages_tiermanager.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_tiermanager.h)
+../inc/ss_nodemessages_mcpr.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_mcpr.h)
+../inc/ss_nodemessages_cpr.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_cpr.h)
+../inc/ss_nodemessages_scpr.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_nodemessages_scpr.h)
+../inc/ss_commsdataobject.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_commsdataobject.h)
+../inc/ss_parameterfamilybundle.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_parameterfamilybundle.h)
+../inc/SS_PMAN.H SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ss_pman.h)
+../inc/SS_PMAN.INL SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ss_pman.inl)
+../inc/ss_protflow.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_protflow.h)
+../inc/ss_protprov.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ss_protprov.h)
+../inc/ss_protcfgldr.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_protcfgldr.h)
+../inc/ss_roles.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_roles.h)
+../inc/ss_roles.inl SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_roles.inl)
+../inc/ss_sapshim.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_sapshim.h)
+../inc/ss_select.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ss_select.h)
+../inc/SS_sock.H SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ss_sock.h)
+../inc/SS_STD.H SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ss_std.h)
+../inc/SS_STD.INL SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ss_std.inl)
+../inc/ss_subconnflow.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_subconnflow.h)
+../inc/ss_subconnprov.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_subconnprov.h)
+../inc/ss_thread.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_thread.h)
+../inc/ss_threadtransport.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_threadtransport.h)
+../inc/ss_threadtransport.inl SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_threadtransport.inl)
+../inc/ss_tiermanager.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_tiermanager.h)
+../inc/ss_tiermanager_internal.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_tiermanager_internal.h)
+../inc/ss_tiermanagerutils.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_tiermanagerutils.h)
+../inc/ss_rmetaextensioncontainer.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_rmetaextensioncontainer.h)
+
+// Would rather not export these headers, but they are needed by BT Avctp for the time being
+../inc/ss_legacyinterfaces.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_legacyinterfaces.h)
+
+../subcon_params/group/SUBCONPARAMS.iby /epoc32/rom/include/subconparams.iby
+../subcon_params/inc/cs_subconevents.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(cs_subconevents.h)
+../subcon_params/inc/cs_subconevents.inl SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(cs_subconevents.inl)
+../subcon_params/inc/cs_subconparams.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(cs_subconparams.h)
+../subcon_params/inc/cs_subconparams.inl SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(cs_subconparams.inl)
+
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+../subcon_params/inc/cs_genevent.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(cs_genevent.h)
+../subcon_params/inc/cs_genevent.inl SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(cs_genevent.inl)
+#endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+
+../esock_params/group/esock_params.iby /epoc32/rom/include/esock_params.iby
+../esock_params/inc/esock_params.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/esock_params.h)
+../esock_params/inc/esock_params.inl SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/esock_params.inl)
+../esock_params/inc/esock_params_internal.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/esock_params_internal.h)
+../esock_params/inc/esock_params_internal.inl SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/esock_params_internal.inl)
+
+../connserv_params/group/CONNSERVPARAMS.iby /epoc32/rom/include/connservparams.iby
+../connserv_params/inc/cs_connservparams.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/cs_connservparams.h)
+../connserv_params/inc/cs_connservparams_internal.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/cs_connservparams_internal.h)
+
+../inc/es_api_ext.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/es_api_ext.h)
+../inc/es_datamon_apiext.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/es_datamon_apiext.h)
+../inc/es_mobility_apiext.h SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(comms-infras/es_mobility_apiext.h)
+
+../inc/ss_datamon_apiext.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_datamon_apiext.h)
+../inc/ss_mobility_apiext.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_mobility_apiext.h)
+../inc/ss_platsec_apiext.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_platsec_apiext.h)
+../inc/ss_msgintercept.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_msgintercept.h)
+
+../inc/ss_protocolparameterset.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_protocolparameterset.h)
+../inc/ss_protocolparameterset.inl SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_protocolparameterset.inl)
+
+#ifdef SYMBIAN_NETWORKING_UPS
+../inc/ss_upsaccesspointconfigext.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_upsaccesspointconfigext.h)
+#endif
+
+
+../inc/addressupdate.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(addressupdate.h)
+../inc/es_enum_partner.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_enum_partner.h)
+../inc/es_enum_partner.inl SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_enum_partner.inl)
+../inc/es_enum_internal.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_enum_internal.h)
+../inc/es_enum_internal.inl SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_enum_internal.inl)
+../inc/es_panic_partner.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_panic_partner.h)
+../inc/es_panic_internal.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_panic_internal.h)
+../inc/es_sock_internal.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_sock_internal.h)
+../inc/es_sock_internal.inl SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_sock_internal.inl)
+../inc/es_sock_partner.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_sock_partner.h)
+../inc/es_prot_internal.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(es_prot_internal.h)
+
+
+../inc/ss_mobility_apiext_internal.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_mobility_apiext_internal.h)
+../inc/ss_refcountowner.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(comms-infras/ss_refcountowner.h)
+
+#include "../etc/BLD.INF"
+#include "../compatibility_headers/group/bld.inf"
+
+//Backup and restore exports
+../group/backup_registration.xml z:/private/101f7989/backup_registration.xml
+
+PRJ_MMPFILES
+
+../group/ESOCK.MMP
+../group/ESockSvr.MMP
+../eintsock_transport/group/eintsock_transport.mmp
+../subcon_params/group/subconparams.mmp
+../esock_params/group/esock_params.mmp
+../connserv_params/group/connservparams.mmp
+
+#include "../debug/MessageInterceptRegister/group/bld.inf"
+#include "../commsdataobjects/group/bld.inf"
+#include "../api_ext/group/bld.inf"
+#include "../esock_messages/group/bld.inf"
+#include "../esock_internal_messages/group/bld.inf"
+#include "../CoreProviders/group/bld.inf"
+#include "../MobilityCoreProviders/group/bld.inf"
+#include "../simpleselectorbase/group/bld.inf"
+
+#ifdef SYMBIAN_NETWORKING_UPS
+#include "../UpsCoreProviders/group/bld.inf"
+#endif
+
+PRJ_TESTMMPFILES
+#include "../test/bld.inf"
+
--- a/datacommsserver/esockserver/group/ESockSvr.MMP Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/group/ESockSvr.MMP Thu Jan 07 13:34:53 2010 +0200
@@ -124,7 +124,6 @@
USERINCLUDE ../inc
USERINCLUDE ../eintsock
-USERINCLUDE ../../../commsfwsupport/commselements/serverden/inc
OS_LAYER_SYSTEMINCLUDE_SYMBIAN
--- a/datacommsserver/esockserver/inc/SS_conn.H Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/inc/SS_conn.H Thu Jan 07 13:34:53 2010 +0200
@@ -152,6 +152,7 @@
friend class EnumerateConnectionsActivity::TCacheConnectionInfo;
friend class EnumerateConnectionsActivity::TCompleteClient;
friend class AllInterfaceNotificationActivity::TEnqueueNotification;
+ friend class AllInterfaceNotificationActivity::TSendErrorToConnection;
friend class ConnSubConnEventsActivity::TProcessSubConnEvent;
friend class ConnStates::TGenerateConnectionUpProgress;
--- a/datacommsserver/esockserver/inc/ss_connLegacy.h Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/inc/ss_connLegacy.h Thu Jan 07 13:34:53 2010 +0200
@@ -46,6 +46,7 @@
namespace AllInterfaceNotificationActivity
{
class TEnqueueNotification;
+class TSendErrorToConnection;
}
namespace EnumerateConnectionsActivity
@@ -82,6 +83,7 @@
friend class EnumerateConnectionsActivity::TCacheConnectionInfo;
friend class EnumerateConnectionsActivity::TCompleteClient;
friend class AllInterfaceNotificationActivity::TEnqueueNotification;
+ friend class AllInterfaceNotificationActivity::TSendErrorToConnection;
friend class ConnStates::TNoTagOrCancelAllInterfaceWorker;
friend class ConnStates::TCancelAllInterfaceNotificationWorker;
--- a/datacommsserver/esockserver/inc/ss_connprov.h Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/inc/ss_connprov.h Thu Jan 07 13:34:53 2010 +0200
@@ -61,10 +61,15 @@
: iProviderInfo(aProviderInfo)
{
}
+ explicit XConnectionProviderInfoQuery(const TUint32 aAPid)
+ : iAPid(aAPid)
+ {
+ }
IMPORT_C virtual TMatchResult Match(Factories::TFactoryObjectInfo& aProviderInfo);
TProviderInfo iProviderInfo;
+ TUint32 iAPid;
protected:
explicit XConnectionProviderInfoQuery()
--- a/datacommsserver/esockserver/inc/ss_connstates.h Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/inc/ss_connstates.h Thu Jan 07 13:34:53 2010 +0200
@@ -388,7 +388,8 @@
TConnPrefList* iConnPrefList;
TConnCSRPref* iCSRPreferences;
TBool iIsAutoStartPresent;
-
+ TBool iStartReceived; // Indicates that ECNStart has been received
+
protected:
typedef MeshMachine::TNodeContext<ESock::CConnection, SubSessStates::TContext> TContext;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/inc/ss_nodemessages_selector.h~ Thu Jan 07 13:34:53 2010 +0200
@@ -0,0 +1,693 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Symbian Foundation License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/**
+ @file
+ @publishedPartner
+ @released
+*/
+
+#ifndef SYMBIAN_NODEMESSAGES_SELECTOR_H
+#define SYMBIAN_NODEMESSAGES_SELECTOR_H
+
+#include <connpref.h>
+#include <comms-infras/metadata.h>
+#include <elements/nm_signatures.h>
+
+#include <comms-infras/ss_nodemessages.h>
+#include <comms-infras/cfmacro.h>
+#include <comms-infras/api_ext_msg.h>
+
+#include <es_enum.h>
+#include <comms-infras/ss_commsprov.h>
+#include <comms-infras/es_availability.h>
+
+namespace ConnStates
+{
+ class TSelectMetaPlane;
+}
+
+class TConnProviderInfo;
+
+namespace ESock
+{
+
+/**
+TConnProviderInfo based preferences. Can be passed into RConnection::Start
+to specify what connection should be started. The handling of this preference
+is implementation specific.
+
+@publishedPartner
+@released
+*/
+
+class TConnProviderInfoPref : public TConnPref
+ {
+public:
+ IMPORT_C explicit TConnProviderInfoPref(const TConnProviderInfo& aProviderInfo);
+
+ IMPORT_C const TConnProviderInfo& Info() const;
+ };
+
+/**
+Selection preferences object used internally by the 3 plane comms implementation.
+
+@publishedPartner
+@released
+*/
+class TSelectionPrefs : public Meta::SMetaData
+ {
+public:
+ /**
+ Uid and TypeId for SMetaData
+ */
+ enum {EUid = 0x10272C79, ETypeId = 1};
+
+ /**
+ Scopes for which the selection can take place.
+
+ Each of the flags may be set, alone, all or in any combinations
+ */
+ enum TSelectionScope
+ {
+ /**
+ For initialisation only
+ */
+ ENone = 0x00,
+ /**
+ Select only from preexisting providers. Do not create new ones.
+ */
+ ESelectFromExisting = 0x01,
+ /**
+ Select only the top provider.
+ */
+ EExplicitConnection = 0x02,
+ /**
+ Do not request a comms binder.
+ */
+ ERequestCommsBinder = 0x04
+ };
+
+ /**
+ Flags to indicate what type of selection is taking place.
+ */
+ enum TSelectionFlags
+ {
+ /**
+ Selecting for a monitor access point. This access point does not affect the idleness
+ of a node.
+ */
+ EMonitor = 0x01,
+ /**
+ Selecting for an access point wishing to attach to a specified access point which
+ already exists
+ */
+ EAttach = 0x02
+ };
+
+public:
+ IMPORT_C TSelectionPrefs();
+ /**
+ @param aSelectionScope Scope for which the selection will take place
+ */
+ IMPORT_C TSelectionPrefs(TSelectionScope aSelectionScope);
+ /**
+ @param aPref Preferences used to decide which access point to select
+ */
+ IMPORT_C TSelectionPrefs(const TConnPref& aPref);
+
+ /**
+ @param aPref Preferences used to decide which access point to select
+ */
+ inline void SetPrefs(const TConnPref& aPref);
+
+ /**
+ @return Mutable connection preferences of this selection preference.
+ */
+ inline TConnPref& Prefs();
+
+ /**
+ @return Immutable connection preferences of this selection preference.
+ */
+ inline const TConnPref& Prefs() const;
+
+ /**
+ @return ETrue if no preferences has been set in the selection preferences object
+ */
+ inline TBool IsEmpty() const;
+
+ /**
+ @return the scope of the selection preferences
+ */
+ inline TUint Scope() const;
+
+ /**
+ @param aScope a new scope for the selection preferences
+ */
+ inline void SetScope(TUint aScope);
+
+ /**
+ @return The flags which have been set for the selection preferences
+ */
+ inline TUint Flags() const;
+
+ /**
+ @param aFlags New flags for set for the selection preferences. Overwrites the old flags
+ */
+ inline void SetFlags(TUint aFlags);
+
+ /**
+ @return The subsession unique id of the subsession which initiated this selection
+ */
+ inline TSubSessionUniqueId SubSessionUniqueId() const;
+
+ /**
+ @param aSubSessionUniqueId The subsession unique id of the subsession initiated this selection
+ */
+ inline void SetSubSessionUniqueId(TSubSessionUniqueId aSubSessionUniqueId);
+
+ EXPORT_DATA_VTABLE_AND_FN
+
+private:
+ TConnPref iPrefs;
+ union
+ {
+ TUint iSelectionParams; //used by meta data offset
+ struct //used by node
+ {
+ TUint iScope : 16;
+ TUint iFlags : 16;
+ } iS;
+ } iU;
+ TSubSessionUniqueId iSubSessionUniqueId;
+ };
+
+void TSelectionPrefs::SetPrefs(const TConnPref& aPref)
+ {
+ iPrefs = aPref;
+ }
+
+TConnPref& TSelectionPrefs::Prefs()
+ {
+ return iPrefs;
+ }
+
+const TConnPref& TSelectionPrefs::Prefs() const
+ {
+ return iPrefs;
+ }
+
+TBool TSelectionPrefs::IsEmpty() const
+ {
+ return iPrefs.ExtensionId() == TConnPref::EConnPrefUnknown;
+ }
+
+TUint TSelectionPrefs::Scope() const
+ {
+ return iU.iS.iScope;
+ }
+
+void TSelectionPrefs::SetScope(TUint aScope)
+ {
+ iU.iS.iScope = aScope;
+ }
+
+TUint TSelectionPrefs::Flags() const
+ {
+ return iU.iS.iFlags;
+ }
+
+void TSelectionPrefs::SetFlags(TUint aFlags)
+ {
+ iU.iS.iFlags = aFlags;
+ }
+
+TSubSessionUniqueId TSelectionPrefs::SubSessionUniqueId() const
+ {
+ return iSubSessionUniqueId;
+ }
+
+void TSelectionPrefs::SetSubSessionUniqueId(TSubSessionUniqueId aSubSessionUniqueId)
+ {
+ iSubSessionUniqueId = aSubSessionUniqueId;
+ }
+
+/**
+Selection preferences override. By default a mcpr will select using the selection prefs
+which were used to create it. The selection preferences override can be used to make them use
+something else.
+
+@publishedPartner
+@released
+*/
+class TOverridenSelectionPrefsExt : public Meta::SMetaData
+ {
+public:
+ enum {EUid = 0x10272C79, ETypeId = 2};
+
+public:
+ /**
+ @param aTierId The tier on which the preferences will be used
+ @param aPrefs The preferences which will override the default preferences
+ */
+ IMPORT_C explicit TOverridenSelectionPrefsExt(TUid aTierId, const TSelectionPrefs& aPrefs);
+
+ EXPORT_DATA_VTABLE_AND_FN
+
+ TSelectionPrefs iPrefs;
+ TUid iTierId;
+ };
+
+/**
+Panic catagory for RConnPrefList panics
+*/
+_LIT (RConnPrefListPanic,"RConnPrefListPanic");
+
+/**
+Null element panic code. An attempt was made to access an element in the
+preferences list that didn't exist
+*/
+const TInt ENullElement = 1;
+
+/**
+This class will be used as a handle to TConnPrefList. During construction of
+the stack this class will be sent in messages as TConnPrefList cannot be sent
+in every message. The overhead of this would be too great (as it would have to
+be serialized and deserialized every time the message was sent). A reference
+cannot be sent as this would not work across processes.
+
+
+@publishedPartner
+@released
+*/
+class RConnPrefList
+ {
+ friend class ConnStates::TSelectMetaPlane;
+public:
+ /**
+ Base class for RConnPrefList iterators
+ */
+ class TIterBase
+ {
+ protected:
+ /**
+ @param aConnPrefList Connection preference list to iterate over
+ */
+ TIterBase(RConnPrefList &aConnPrefList)
+ : iConnPrefList(aConnPrefList), iMasterIndex(0)
+ {
+
+ }
+
+ /**
+ @param aType Only return preferences of this type
+ @param aIndex Index of preference requested
+ @return The requested connection preference, or NULL if no preference of the specified type was found at aIndex
+ */
+ IMPORT_C Meta::SMetaData* AtIndex(const Meta::STypeId& aType, TInt aIndex);
+
+ protected:
+ RConnPrefList& iConnPrefList;
+ TInt iMasterIndex;
+ };
+
+ template<class TYPE>
+ /**
+ This iterator will return objects of the templated class. It will only
+ return objects from the list that are of the type passed in as the template parameter
+ */
+ class TIter : public TIterBase
+ {
+ public:
+ /**
+ @param aConnPrefList Connection preferences to iterate over
+ */
+ TIter(RConnPrefList &aConnPrefList)
+ : TIterBase(aConnPrefList)
+ {
+ iIndex = 0;
+ }
+
+ /**
+ This will return the instance of the given type in the list at the
+ point specified by aIndex
+
+ @param aIndex index of item to return
+ @return The item found at the index, or NULL if not found
+ */
+ TYPE* operator[](TInt aIndex)
+ {
+ return static_cast<TYPE*>(AtIndex(Meta::STypeId::CreateSTypeId(TYPE::EUid,TYPE::ETypeId) , aIndex));
+ }
+
+ /**
+ @return the next instance of the given tpye in the list or NULL if no more instances remain
+ */
+ TYPE* operator++(TInt)
+ {
+ return static_cast<TYPE*>((*this)[iIndex++]);
+ }
+
+ /**
+ @return a reference to the current object pointed to by the iterator
+ */
+ TYPE& operator*()
+ {
+ TYPE* ptr = static_cast<TYPE*>(iConnPrefList[iMasterIndex]);
+ __ASSERT_ALWAYS(ptr != NULL,User::Panic(RConnPrefListPanic, ENullElement));
+ return *ptr;
+ }
+
+ /**
+ @return a pointer to the current object pointed to by the iterator
+ */
+ TYPE* operator->()
+ {
+ TYPE* ptr = static_cast<TYPE*>(iConnPrefList[iMasterIndex]);
+ return ptr;
+ }
+
+ /**
+ @return ETrue if there are no more elements to iterate over. EFalse, otherwise
+ */
+ TBool IsEnd()
+ {
+ if((*this)[iIndex] == NULL)
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+ /**
+ Remove the current object from the iterators associated RConnPrefList
+ @return a pointer to the removed object
+ */
+ TYPE* Remove()
+ {
+ TYPE* ptr = static_cast<TYPE*>(iConnPrefList[iMasterIndex]);
+ iConnPrefList.Remove(iMasterIndex);
+ (*this)[iIndex];
+ return ptr;
+ }
+
+ private:
+ TInt iIndex;
+ };
+
+public:
+ IMPORT_C RConnPrefList();
+
+ /**
+ Open and initialise with data from passed in RConnPrefList
+ @param aPrefList RConnPrefList to copy data from. The copy is shallow.
+ */
+ IMPORT_C void Open(RConnPrefList& aPrefList);
+
+ /**
+ Close the RConnPrefList object
+ */
+ IMPORT_C void Close();
+
+ /**
+ Create an iterator for template parameter TYPE. The iterator will be able to
+ iterate over all the members of the RConnPrefList which match the type specified.
+ @return A new iterator object for this connection preferences list
+ */
+ template<class TYPE>
+ RConnPrefList::TIter<TYPE> getIter()
+ {
+ return RConnPrefList::TIter<TYPE>(*this);
+ }
+
+ /**
+ Append a preference to connection preferences list
+ @param aFamily Preference to append
+ @leave System wide error code.
+ */
+ IMPORT_C void AppendL(SMetaDataECom* aFamily);
+
+ /**
+ @param aIndex index of requested object
+ @return The object at aIndex
+ */
+ IMPORT_C SMetaData* operator[](TInt aIndex);
+
+ /**
+ Remove an object from the RConnPrefList
+ @param aIndex the index of the object to remove
+ */
+ IMPORT_C void Remove(TInt aIndex);
+
+ /**
+ @return the number of preferences in the list
+ */
+ IMPORT_C TInt Count();
+
+private:
+ TInt Open(TConnPrefList* aObject);
+ TConnPrefList* iObject;
+ };
+
+
+/**
+Signature for a message which can carry selection preferences
+*/
+struct TSigSelectionPrefs : public Messages::TSignatureBase
+ {
+protected:
+ inline TSigSelectionPrefs() {}
+
+ /**
+ @param aMessageId Id of the message this signature is being created for.
+ */
+ TSigSelectionPrefs(const Messages::TNodeSignal::TMessageId& aMessageId)
+ : Messages::TSignatureBase(aMessageId)
+ {}
+
+ /**
+ @param aMessageId Id of the message this signature is being created for.
+ @param aSelectionPrefs Selection preferences object to be passed in the message
+ */
+ TSigSelectionPrefs(const Messages::TNodeSignal::TMessageId& aMessageId, const Meta::SMetaData& aSelectionPrefs)
+ : Messages::TSignatureBase(aMessageId)
+ {
+ //TODO: the copy can be optimised out when SMetaDataNetCtr handlers supported.
+ iSelectionPrefs.Copy(aSelectionPrefs);
+ }
+public:
+ DECLARE_MVIP_CTR(TSigSelectionPrefs)
+ EXPORT_DATA_VTABLE_AND_FN
+
+ /**
+ Selection preferences object passed in the message
+ */
+ TSelectionPrefs iSelectionPrefs;
+ };
+
+/**
+Signature for a message which can carry a list of connection preferences
+*/
+struct TSigConnPrefList : public Messages::TSignatureBase
+ {
+protected:
+ inline TSigConnPrefList() {}
+
+ /**
+ @param aMessageId Id of the message this signature is being created for.
+ */
+ TSigConnPrefList(const Messages::TNodeSignal::TMessageId& aMessageId)
+ : Messages::TSignatureBase(aMessageId)
+ {}
+
+ /**
+ @param aMessageId Id of the message this signature is being created for.
+ @param aConnPrefList List of connection preferences to be passed in this message
+ */
+ TSigConnPrefList(const Messages::TNodeSignal::TMessageId& aMessageId, RConnPrefList& aConnPrefList)
+ : Messages::TSignatureBase(aMessageId)
+ {
+ iConnPrefList = aConnPrefList;
+ }
+public:
+ DECLARE_MVIP_CTR(TSigConnPrefList)
+ EXPORT_DATA_VTABLE_AND_FN
+
+ /**
+ List of connection preferences passed in this message
+ */
+ RConnPrefList iConnPrefList;
+ };
+
+
+/**
+Message signature template for a message which can carry selection preferences
+
+@see TSigSelectionPrefs
+*/
+template<TInt id, TInt32 realm>
+struct TMessageSigSelectionPrefs : public TSigSelectionPrefs, public Messages::TSignatureBase::TTypeToMessageId<id, realm>
+ {
+ explicit TMessageSigSelectionPrefs() :
+ TSigSelectionPrefs(Messages::TNodeSignal::TMessageId(id, realm))
+ { }
+
+ explicit TMessageSigSelectionPrefs(const Meta::SMetaData& aSelectionPrefs)
+ : TSigSelectionPrefs(Messages::TNodeSignal::TMessageId(id, realm), aSelectionPrefs)
+ {
+ }
+ };
+
+/**
+Message signature template for a message which can carry a list of connection preferences
+
+@see TSigConnPrefList
+*/
+template<TInt id, TInt32 realm>
+ struct TMessageSigConnPrefList : public TSigConnPrefList, public Messages::TSignatureBase::TTypeToMessageId<id, realm>
+ {
+ explicit TMessageSigConnPrefList()
+ : TSigConnPrefList(Messages::TNodeSignal::TMessageId(id, realm))
+ {}
+
+ explicit TMessageSigConnPrefList(RConnPrefList& aCustomPrefs)
+ : TSigConnPrefList(Messages::TNodeSignal::TMessageId(id, realm), aCustomPrefs)
+ {}
+ };
+
+/**
+Signature for a select complete message.
+*/
+struct TSigSelectComplete : public Messages::TSignatureBase
+ {
+protected:
+ inline TSigSelectComplete() {}
+
+ /**
+ @param aMessageId Id of the message this signature is being created for.
+ @param aNodeId Node id of node which has been created
+ @param aProviderInfo Provider info of access point which has been created.
+ */
+ TSigSelectComplete(const Messages::TNodeSignal::TMessageId& aMessageId, const Messages::TNodeId& aNodeId, const TProviderInfo& aProviderInfo)
+ : Messages::TSignatureBase(aMessageId),
+ iNodeId(aNodeId),
+ iProviderInfo(aProviderInfo)
+ {
+ }
+public:
+ DECLARE_MVIP_CTR(TSigSelectComplete)
+ EXPORT_DATA_VTABLE_AND_FN
+ /**
+ Node id of node which has been created
+ */
+ Messages::TNodeId iNodeId;
+ /**
+ Provider info of the access point which has been created
+ */
+ TProviderInfo iProviderInfo;
+ };
+
+/**
+Message signature template for a select complete message
+
+@see TSigSelectComplete
+ */
+template<TInt id, TInt32 realm>
+struct TMessageSigSelectComplete : public TSigSelectComplete, public Messages::TSignatureBase::TTypeToMessageId<id, realm>
+ {
+ explicit TMessageSigSelectComplete(const Messages::TNodeId& aNodeId, const TProviderInfo aProviderInfo)
+ : TSigSelectComplete(Messages::TNodeSignal::TMessageId(id, realm), aNodeId, aProviderInfo)
+ {
+ }
+ };
+
+/**
+Message signature template for availability subscription message
+ */
+DECLARE_MESSAGE_SIG_1(SigAvailabilitySubscriptionOptions, TAvailabilitySubscriptionOptions, AvailabilitySubscriptionOptions)
+/**
+Message signature for availability status message
+*/
+DECLARE_MESSAGE_SIG_1(SigAvailabilityStatus, TAvailabilityStatus, AvailabilityStatus)
+
+/**
+Message interface for selector nodes
+Nodes wishing to implement this interface must implement all message protocols in the interface.
+
+@publishedPartner
+@released
+*/
+class TCFSelector
+ {
+ private:
+ enum
+ {
+ ECFSimpleSelect = 1,
+ ECFSelect = 2,
+ ECFSelectComplete = 3
+ };
+
+public:
+ enum { ERealmId = 0x10285F4E }; //UID allocated on 4/6/08 from KUidNodeMessageRealms
+
+ /**
+ Selection request sent to TierManagers (usually by MCPRs). Can only carry one type of selection preferences at a time, and for this
+ reason, using TSelect is preferred. It should be noted however, that multiple nodes may be returned in exchange for this single
+ preference, for example in the case of SNAP preferences.
+
+ This request is completed only after TSelectComplete with a NULL address has been received by the requestor.
+
+ @li Type: Request
+ @li Fallible: Yes
+
+ @param iSelectionPrefs preferences used by the selection process to choose nodes
+ */
+ typedef TMessageSigSelectionPrefs<ECFSimpleSelect, TCFSelector::ERealmId> TSimpleSelect;
+
+
+ /**
+ Selection request sent to Tier Managers (usually by MCPRs or CSR). Carries an RConnPrefList instance, the objects in the list are used
+ during the construction of the stack. Multiple nodes may be returned by the selection activity. This request is completed only after
+ TSelectComplete with a NULL address has been received by the requestor.
+
+ @li Type: Request
+ @li Fallible: Yes
+
+ @param aConnPrefList an instance of RConnPrefList
+ */
+ typedef TMessageSigConnPrefList<ECFSelect, TCFSelector::ERealmId> TSelect;
+
+ /**
+ Response to TSelect or TSelectNextLayer. Carries address to selected providers (MCPRs). A selection request is completed only after
+ TSelectComplete with a NULL address has been received by the requestor. This response also carries some additional information about
+ the selected provider.
+
+ @li Type: Response to TSimpleSelect or TSelect
+ @li Fallible: No
+
+ @param iNodeId node id of the node which has been selected
+ @param iProviderInfo additional information about the created node
+ */
+ typedef TMessageSigSelectComplete<ECFSelectComplete, TCFSelector::ERealmId> TSelectComplete;
+ };
+
+} //namespace esock
+
+#endif
+//SYMBIAN_NODEMESSAGES_SELECTOR_H
+
--- a/datacommsserver/esockserver/ssock/ss_conn.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/ssock/ss_conn.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -303,7 +303,6 @@
}
-
namespace ConnectionGoingDownActivity
{
DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityGoneDown, ConnectionGoingDown, TCFControlClient::TGoneDown, PRActivities::CGoneDownActivity::NewL)
@@ -311,9 +310,10 @@
THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnectionGoingDownActivity::TStoreGoneDownError, MeshMachine::TNoTag)
THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TCancelAndCloseZone0ClientExtIfaces, MeshMachine::TNoTag)
THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TCancelAllLegacyRMessage2Activities, ConnStates::TNoTagBlockedByLegacyRMessage2Activities)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TGenerateConnectionDownProgress, MeshMachine::TNoTag)
NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingRequestToServiceProviders, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSetIdleIfNoServiceProviders, MeshMachine::TAwaitingLeaveComplete, ConnectionCleanupActivities::TNoTagOrNoTagBackwards)
- LAST_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TGenerateConnectionDownProgress)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
NODEACTIVITY_END()
}
@@ -402,6 +402,8 @@
: CMMSockSubSession(ConnectionActivities::connectionActivities::Self(), aSession, aPlayer, aSubSessionUniqueId),
ASubSessionPlatsecApiExt(UniqueId()),
TIfStaticFetcherNearestInHierarchy(this),
+ iLastProgress(KConnectionUninitialised, KErrNone),
+ iLastProgressError(KConnectionUninitialised, KErrNone),
iTierId(aTierId),
iLegacyConnection(*this)
{
@@ -516,6 +518,18 @@
Main body of CConnection::NewL(CSockSession* aSession, const CConnection& aExistingConnection)
*/
{
+ // will need to be brought over
+ iLastProgress = aExistingConnection.iLastProgress;
+ iLastProgressError = aExistingConnection.iLastProgressError;
+ iProgressQueue = aExistingConnection.iProgressQueue;
+
+ /**
+ The first commented in section of code here is incorrect. It only clones one of the service providers and not them
+ all. This means that certain calls, GetIntSetting being one, does not work on cloned connections. Unfortunately,
+ some code now relies on this being broken (browser). This code needs to be fixed before the first section of code
+ is removed and the proper code reinstated.
+ */
+#if 1 // BAD CODE
RNodeInterface* sp = aExistingConnection.ServiceProvider();
if (sp)
{
@@ -529,6 +543,59 @@
LOG( ESockLog::Printf(KESockConnectionTag, _L8("CConnection %08x CloneL KErrNotReady"), this) );
User::Leave(KErrNotReady);
}
+
+#else // PROPER CODE
+ /*
+ This function looks like it'd be better to do in one loop. dont do this though. All fallible parts need to be done before
+ sending the messages to ourselves, otherwise the mesh machine will panic.
+ */
+ TInt numSP = 0;
+ TClientIter<TDefaultClientMatchPolicy> iter = aExistingConnection.GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider),
+ Messages::TClientType(TCFClientType::EServProvider, Messages::TClientType::ELeaving));
+
+ /**
+ Add clients to client list. If this fails at any point, remove anything we've added.
+ Makes assumption that we are the only thing adding service providers.
+ */
+ RNodeInterface* sp = iter++;
+ while (sp)
+ {
+ TRAPD(err, AddClientL(sp->RecipientId(), sp->ClientType()));
+ if (err != KErrNone)
+ {
+ sp = GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider));
+ while (sp)
+ {
+ RemoveClient(sp->RecipientId());
+ sp = GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider));
+ }
+ User::Leave(err);
+ }
+
+ sp = iter++;
+ numSP++;
+ }
+
+ /**
+ If we managed to add anything, post messages to them so that we get added as control clients
+ */
+ if (numSP == 0)
+ {
+ LOG( ESockLog::Printf(KESockConnectionTag, _L8("CConnection %08x CloneL KErrNotReady"), this) );
+ User::Leave(KErrNotReady);
+ }
+ else
+ {
+ TClientIter<TDefaultClientMatchPolicy> iter = GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider));
+ sp = iter++;
+ while (sp)
+ {
+ // TODO IK: This is the wrong message to be using here, should use JoinRequest/Complete handshake
+ sp->PostMessage(Id(), TCFFactory::TPeerFoundOrCreated(Id(), 0).CRef());
+ sp = iter++;
+ }
+ }
+#endif
}
@@ -791,7 +858,9 @@
void CConnection::ProgressL()
{
- if (iLastProgress.iStage != KConnectionUp && iLastProgress.iStage != KConnectionDown)
+ if (iLastProgress.iStage != KConnectionUp
+ && iLastProgress.iStage != KConnectionDown
+ && iLastProgress.iStage != KConnectionUninitialised)
{
RNodeInterface* sp = ServiceProvider();
User::LeaveIfError(sp? KErrNone : KErrNotReady);
@@ -812,7 +881,9 @@
void CConnection::LastProgressErrorL()
{
- if (iLastProgress.iStage != KConnectionUp && iLastProgress.iStage != KConnectionDown)
+ if (iLastProgress.iStage != KConnectionUp
+ && iLastProgress.iStage != KConnectionDown
+ && iLastProgress.iStage != KConnectionUninitialised)
{
RNodeInterface* sp = ServiceProvider();
User::LeaveIfError(sp? KErrNone : KErrNotReady);
@@ -997,10 +1068,9 @@
// Enqueue the notification and wait for the next one - we loop here forever
NODEACTIVITY_ENTRY(KNoTag, TEnqueueNotification, TAwaitingLinkNotification, CoreStates::TCancelOrErrorOrTag<KNoTag|EBackward>)
- THROUGH_TRIPLE_ENTRY(KErrorTag, MeshMachine::TStoreError, MeshMachine::TTag<KCancelTag>)
// If we received a TCancel from CConnection, reply with TError to complete shutdown handshake.
- THROUGH_NODEACTIVITY_ENTRY(KCancelTag, TSendErrorToConnection, MeshMachine::TTag<KCancelTag>)
- NODEACTIVITY_ENTRY(KCancelTag, TCancelLinkNotification, TAwaitingLinkNotificationError, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KCancelTag, TCancelLinkNotification, TAwaitingLinkNotificationError, MeshMachine::TTag<KErrorTag>)
+ THROUGH_TRIPLE_ENTRY(KErrorTag, TSendErrorToConnection, MeshMachine::TNoTag)
LAST_NODEACTIVITY_ENTRY(KNoTag, TLeaveTierManager) // no other sessions with tier so can safely fire & forget this
NODEACTIVITY_END()
}
--- a/datacommsserver/esockserver/ssock/ss_connprov.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/ssock/ss_connprov.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -59,7 +59,9 @@
CConnectionProviderBase* prov = static_cast<CConnectionProviderBase*>(aProviderInfo.iInfo.iFactoryObject);
const TProviderInfo& thePI = static_cast<const TProviderInfoExt&>(prov->AccessPointConfig().FindExtensionL(
STypeId::CreateSTypeId(TProviderInfoExt::EUid, TProviderInfoExt::ETypeId))).iProviderInfo;
- TBool isMatch = (thePI.TierId() == iProviderInfo.TierId()) && (thePI.APId() == iProviderInfo.APId());
+ TBool isMatch = (thePI.APId() == iAPid);
+ LOG(ESockLog::Printf(KESockCtrlFactTag, _L("XConnectionProviderInfoQuery::Match %08x:\tiAPid is = %08x THePI.APId = %08x"),
+ this, iAPid, thePI.APId()));
return (isMatch ? MFactoryQuery::EMatch : MFactoryQuery::EContinue);
}
--- a/datacommsserver/esockserver/ssock/ss_connstates.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/ssock/ss_connstates.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -168,6 +168,7 @@
}
else
{
+ ac.iStartReceived = ETrue;
ac.SetSelectionScope(TSelectionPrefs::EExplicitConnection);
}
}
@@ -845,10 +846,18 @@
// activity Id and so will never give a match. Here we ensure that our second IPC is matched and accepted.
TCFInternalEsock::TSubSess* msg = message_cast<TCFInternalEsock::TSubSess>(&aContext.iMessage);
- if (!msg || msg->iMessage.Function() != ECNStart)
+ if (!msg || (msg->iMessage.Function() != ECNStart && msg->iMessage.Function() != ECNSetStartPrefs))
{
return CNodeActivityBase::Next(aContext);
}
+ else if (iStartReceived)
+ {
+ // ECNSetStartPrefs should only ever be seen as the IPC in the TSubSess kick off message
+ // ECNStart should only be seen once after an ECNSetStartPrefs or as the kick off message
+ PanicClient(ETwice);
+ aContext.iReturn = KErrInUse;
+ return ETrue;
+ }
MESH_LOG((KESockConnectionTag, _L8("CStartAttachActivity::Next:\tAccepted ECNStart IPC after ECNSetStartPrefs")));
TBool nextRet = ACore::Next(&aContext);
@@ -1440,8 +1449,12 @@
DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TSendErrorToConnection, NetStateMachine::MStateTransition, TContext)
void AllInterfaceNotificationActivity::TSendErrorToConnection::DoL()
{
- // Send a TError to the CConnection to complete the shutdown handshake.
- RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.Node().iConnection.Id(), TEBase::TError(iContext.Activity()->KickOffMessageId(), KErrCancel).CRef());
+ iContext.Node().iConnection.iLegacyConnection.CompleteAllInterfaceNotificationL(iContext.Activity()->Error());
+
+ TEBase::TError msg(iContext.Activity()->KickOffMessageId(), iContext.Activity()->Error());
+ iContext.Activity()->PostToOriginators(msg);
+
+ iContext.Activity()->SetError(KErrNone);
}
DEFINE_SMELEMENT(TNoTagOrCancelAllInterfaceWorker, NetStateMachine::MStateFork, TContext)
--- a/datacommsserver/esockserver/ssock/ss_thread.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/ssock/ss_thread.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -32,7 +32,7 @@
#include <elements/cftransportmsg.h>
#include <elements/nm_address_internal.h>
#include <elements/sd_msgs.h>
-#include "sd_rootserverchannelhandler.h"
+#include <elements/sd_rootserverchannelhandler.h>
#include "ss_connectionserver.h"
#include <comms-infras/ss_common.h>
#include <comms-infras/ss_tiermanager.h>
--- a/datacommsserver/esockserver/test/TE_EsockTestSteps/inc/EsockTestBase.h Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_EsockTestSteps/inc/EsockTestBase.h Thu Jan 07 13:34:53 2010 +0200
@@ -139,6 +139,19 @@
TBool iValueExpected;
};
+struct TRSocketSetOptParams
+ {
+ void Reset();
+
+ TPtrC iSocketName;
+ TInt iOptionName;
+ TInt iOptionLevel;
+ TPtrC iOptionToSetText;
+ TInt iOptionToSetValue;
+ TBool iTextSet;
+ TBool iValueSet;
+ };
+
struct TProtocolDescriptionParams
{
void Reset();
@@ -482,6 +495,8 @@
TProtocolDesc& aProtocolDescriptionOutput);
TInt GetOptSocket(const TRSocketGetOptParams& aParams, TDes8& aGetOptOutput);
TInt GetOptSocket(const TRSocketGetOptParams& aParams, TInt& aGetOptOutput);
+ TInt SetOptSocket(const TRSocketSetOptParams& aParams, TDes8& aSetOptOutput);
+ TInt SetOptSocket(const TRSocketSetOptParams& aParams, TInt& aSetOptOutput);
//connection functions library
RConnection* FindConnection(const TDesC& aConnectionName);
--- a/datacommsserver/esockserver/test/TE_EsockTestSteps/inc/Sockets.TestSteps.h Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_EsockTestSteps/inc/Sockets.TestSteps.h Thu Jan 07 13:34:53 2010 +0200
@@ -375,6 +375,23 @@
_LIT(KSocketGetOptionStep, "SocketGetOptionStep");
+/**
+Class implementing control and confirmation of RSocket::SetOpt() calls
+
+@internalComponent
+*/
+class CSocketSetOptionStep : public CTe_EsockStepBase
+ {
+public:
+ CSocketSetOptionStep(CCEsockTestBase*& aEsockTest);
+ TVerdict doSingleTestStep();
+ TInt ConfigureFromIni();
+
+private:
+ TRSocketSetOptParams iParams;
+ };
+
+_LIT(KSocketSetOptionStep, "SocketSetOptionStep");
/**
Class implementing confirmation of protocol description retrieved from a socket with:
--- a/datacommsserver/esockserver/test/TE_EsockTestSteps/src/EsockTestBase.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_EsockTestSteps/src/EsockTestBase.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -195,6 +195,16 @@
iValueExpected = EFalse;
}
+void TRSocketSetOptParams::Reset()
+ {
+ iSocketName.Set(KNullDesC);
+ iOptionName = 0;
+ iOptionLevel = 0;
+ iOptionToSetText.Set(KNullDesC);
+ iTextSet = EFalse;
+ iValueSet = EFalse;
+ }
+
void TRSocketIoctlParams::Reset()
{
iSocketName.Set(KNullDesC);
@@ -1061,6 +1071,24 @@
return s->GetOpt(aParams.iOptionName, aParams.iOptionLevel, aGetOptOutput);
}
+TInt CCEsockTestBase::SetOptSocket(const TRSocketSetOptParams& aParams, TDes8& aSetOptInput)
+ {
+ RSocket* s = iSocks.Find(aParams.iSocketName);
+ if (s == NULL)
+ return KErrNotFound;
+
+ return s->SetOpt(aParams.iOptionName, aParams.iOptionLevel, aSetOptInput);
+ }
+
+TInt CCEsockTestBase::SetOptSocket(const TRSocketSetOptParams& aParams, TInt& aSetOptInput)
+ {
+ RSocket* s = iSocks.Find(aParams.iSocketName);
+ if (s == NULL)
+ return KErrNotFound;
+
+ return s->SetOpt(aParams.iOptionName, aParams.iOptionLevel, aSetOptInput);
+ }
+
TInt CCEsockTestBase::ProtocolDescription(
const TSocketProtocolDescriptionParams& aParams,
TProtocolDesc& aProtocolDescriptionOutput)
--- a/datacommsserver/esockserver/test/TE_EsockTestSteps/src/Sockets.TestSteps.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_EsockTestSteps/src/Sockets.TestSteps.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -1019,6 +1019,8 @@
// Get options
//------------
+_LIT(KOptionName, "OptionName");
+_LIT(KOptionLevel, "OptionLevel");
CSocketGetOptionStep::CSocketGetOptionStep(CCEsockTestBase*& aEsockTest)
: CTe_EsockStepBase(aEsockTest)
@@ -1026,8 +1028,6 @@
SetTestStepName(KSocketGetOptionStep);
}
-_LIT(KOptionName, "OptionName");
-_LIT(KOptionLevel, "OptionLevel");
_LIT(KExpectedOptionText, "ExpectedOptionText");
_LIT(KExpectedOptionValue, "ExpectedOptionValue");
@@ -1073,7 +1073,7 @@
// Checks on config values
if(iParams.iValueExpected && iParams.iTextExpected)
{
- INFO_PRINTF1(_L("Can be only value of text expected. Not both"));
+ INFO_PRINTF1(_L("Can be only value or text expected. Not both"));
return KErrCorrupt;
}
@@ -1140,7 +1140,127 @@
return TestStepResult();
}
+// Set options
+//------------
+CSocketSetOptionStep::CSocketSetOptionStep(CCEsockTestBase*& aEsockTest)
+: CTe_EsockStepBase(aEsockTest)
+ {
+ SetTestStepName(KSocketSetOptionStep);
+ }
+
+_LIT(KOptionToSetText, "OptionToSetText");
+_LIT(KOptionToSetValue, "OptionToSetValue");
+
+TInt CSocketSetOptionStep::ConfigureFromIni()
+ {
+ // Reset the parameters and read in necessary fields
+ iParams.Reset();
+
+ // Socket to apply it to
+ if((GetStringFromConfig(iSection, KTe_SocketName, iParams.iSocketName) != 1)
+ || (iParams.iSocketName.Length() == 0))
+ {
+ INFO_PRINTF3(KErrString_MissingConfigFileField, &iSection, &KTe_SocketName);
+ return KErrNotFound;
+ }
+
+ // Option "name"
+ if (GetIntFromConfig(iSection, KOptionName, iParams.iOptionName) != 1)
+ {
+ INFO_PRINTF3(KErrString_MissingConfigFileField, &iSection, &KOptionName);
+ return KErrNotFound;
+ }
+
+ // Option level
+ if (GetIntFromConfig(iSection, KOptionLevel, iParams.iOptionLevel) != 1)
+ {
+ INFO_PRINTF1(_L("Option level not specified: defaulting to KLevelUnspecified"));
+ iParams.iOptionLevel = KLevelUnspecified;
+ }
+
+ // Input text to be set
+ if(GetStringFromConfig(iSection, KOptionToSetText, iParams.iOptionToSetText) == 1)
+ {
+ iParams.iTextSet = ETrue;
+ }
+
+ // Input value to be set
+ if(GetIntFromConfig(iSection, KOptionToSetValue, iParams.iOptionToSetValue) == 1)
+ {
+ iParams.iValueSet = ETrue;
+ }
+
+ // Checks on config values
+ if(iParams.iValueSet && iParams.iTextSet)
+ {
+ INFO_PRINTF1(_L("Can be only value or text expected. Not both"));
+ return KErrCorrupt;
+ }
+
+ if(!iParams.iValueSet && !iParams.iTextSet)
+ {
+ INFO_PRINTF1(_L("Must have value or text expected."));
+ return KErrCorrupt;
+ }
+
+ // All ok if we got this far
+ return KErrNone;
+ }
+
+TVerdict CSocketSetOptionStep::doSingleTestStep()
+ {
+ TRequestStatus requestStatus;
+
+ TBuf8<256> inputBuffer;
+ inputBuffer.Copy(iParams.iOptionToSetText);
+ TInt inputValue = iParams.iOptionToSetValue;
+ TInt error;
+
+ if(iParams.iTextSet)
+ {
+ error = iEsockTest->SetOptSocket(iParams, inputBuffer);
+ }
+ else
+ {
+ error = iEsockTest->SetOptSocket(iParams, inputValue);
+ }
+
+ if (error != KErrNone)
+ {
+ INFO_PRINTF3(_L("Socket set option error. socket:%S, error:%d"), &iParams.iSocketName, error);
+ SetTestStepError(error);
+ return EFail;
+ }
+
+ if(iParams.iTextSet)
+ {
+ // Convert the output to wide chars
+ TBuf<256> inputConvertedToWideChars;
+ CnvUtfConverter::ConvertToUnicodeFromUtf8(inputConvertedToWideChars, inputBuffer);
+
+ // Log what was returned
+ INFO_PRINTF2(_L("Socket set with opt text. value:%S"), &inputConvertedToWideChars);
+ INFO_PRINTF2(_L("Text set by user. value:%S"), &iParams.iOptionToSetText);
+
+ // Validate the output with that expected
+ TVerdict verdict = (inputConvertedToWideChars == iParams.iOptionToSetText) ? EPass : EFail;
+ SetTestStepResult(verdict);
+ }
+ else
+ {
+ // Log what was returned
+ INFO_PRINTF2(_L("Socket returned get opt value. value:%d"), inputValue);
+ INFO_PRINTF2(_L("Value set by user. value:%d"), iParams.iOptionToSetValue);
+
+ // Validate the output with that expected
+ TVerdict verdict = (inputValue == iParams.iOptionToSetValue) ? EPass : EFail;
+ SetTestStepResult(verdict);
+ }
+
+ // Return the result
+ return TestStepResult();
+ }
// Socket protocol description
//----------------------------
--- a/datacommsserver/esockserver/test/TE_EsockTestSteps/src/Te_esockteststepsSuiteServer.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_EsockTestSteps/src/Te_esockteststepsSuiteServer.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -406,6 +406,7 @@
NEW_ESOCK_TESTSTEP(SendReceiveIoctlStep)
NEW_ESOCK_TESTSTEP(SocketProtocolDescriptionStep)
NEW_ESOCK_TESTSTEP(SocketGetOptionStep)
+ NEW_ESOCK_TESTSTEP(SocketSetOptionStep)
// Socket server
NEW_ESOCK_TESTSTEP(SocketServerNumProtocolsStep)
--- a/datacommsserver/esockserver/test/TE_RConnection/configs/ContentionManagement/CM_GT0429_00.txt Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RConnection/configs/ContentionManagement/CM_GT0429_00.txt Thu Jan 07 13:34:53 2010 +0200
@@ -15,7 +15,7 @@
# ContextConfigGPRS = <TProtocolType>, <TGSNAddress>, <TProtocolAddress>, <PdpDataCompression>, <TAnonymousAccess>, <TUseEdge>
# ProtocolConfigOption = <Authentication Protocol>, <Username>, <Password>, <Challenge>,
# <Response>, <PrimaryDNS>, <SecondaryDNS>, <TUint iId>
-SetContextConfigGPRS= 0,Test,,0, 2, 0, 0,RasUser,,,,,,0
+SetContextConfigGPRS = 0,Test,,0,2,0,1,RasUser,,,,,,1
# TRel99ContextConfig = <TName iContextName>, <TUint iActivatePause>, <TUint iActivateErrorCode>, <TUint iDeactivatePause>,
# <TUint iDeactivateErrorCode>, <TUint iDeletionPause>, <TUint iDeletionErrorCode> <TBool iConnectToNtRas>
--- a/datacommsserver/esockserver/test/TE_RConnection/configs/ContentionManagement/CM_GT0429_01.txt Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RConnection/configs/ContentionManagement/CM_GT0429_01.txt Thu Jan 07 13:34:53 2010 +0200
@@ -15,7 +15,7 @@
# ContextConfigGPRS = <TProtocolType>, <TGSNAddress>, <TProtocolAddress>, <PdpDataCompression>, <TAnonymousAccess>, <TUseEdge>
# ProtocolConfigOption = <Authentication Protocol>, <Username>, <Password>, <Challenge>,
# <Response>, <PrimaryDNS>, <SecondaryDNS>, <TUint iId>
-SetContextConfigGPRS= 0,Test,,0, 2, 0, 0,RasUser,,,,,,0
+SetContextConfigGPRS = 0,Test,,0,2,0,1,RasUser,,,,,,1
# TRel99ContextConfig = <TName iContextName>, <TUint iActivatePause>, <TUint iActivateErrorCode>, <TUint iDeactivatePause>,
# <TUint iDeactivateErrorCode>, <TUint iDeletionPause>, <TUint iDeletionErrorCode> <TBool iConnectToNtRas>
--- a/datacommsserver/esockserver/test/TE_RConnection/configs/ContentionManagement/CM_GT0429_05.txt Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RConnection/configs/ContentionManagement/CM_GT0429_05.txt Thu Jan 07 13:34:53 2010 +0200
@@ -15,7 +15,7 @@
# ContextConfigGPRS = <TProtocolType>, <TGSNAddress>, <TProtocolAddress>, <PdpDataCompression>, <TAnonymousAccess>, <TUseEdge>
# ProtocolConfigOption = <Authentication Protocol>, <Username>, <Password>, <Challenge>,
# <Response>, <PrimaryDNS>, <SecondaryDNS>, <TUint iId>
-SetContextConfigGPRS= 0,Test,,0, 2, 0, 0,RasUser,,,,,,0
+SetContextConfigGPRS = 0,Test,,0,2,0,1,RasUser,,,,,,1
# TRel99ContextConfig = <TName iContextName>, <TUint iActivatePause>, <TUint iActivateErrorCode>, <TUint iDeactivatePause>,
# <TUint iDeactivateErrorCode>, <TUint iDeletionPause>, <TUint iDeletionErrorCode> <TBool iConnectToNtRas>
--- a/datacommsserver/esockserver/test/TE_RConnection/configs/ContentionManagement/config_001.txt Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RConnection/configs/ContentionManagement/config_001.txt Thu Jan 07 13:34:53 2010 +0200
@@ -15,7 +15,7 @@
# ContextConfigGPRS = <TProtocolType>, <TGSNAddress>, <TProtocolAddress>, <PdpDataCompression>, <TAnonymousAccess>, <TUseEdge>
# ProtocolConfigOption = <Authentication Protocol>, <Username>, <Password>, <Challenge>,
# <Response>, <PrimaryDNS>, <SecondaryDNS>, <TUint iId>
-SetContextConfigGPRS= 0,Test,,0, 2, 0, 0,RasUser,,,,,,0
+SetContextConfigGPRS = 0,Test,,0,2,0,1,RasUser,,,,,,1
# TRel99ContextConfig = <TName iContextName>, <TUint iActivatePause>, <TUint iActivateErrorCode>, <TUint iDeactivatePause>,
# <TUint iDeactivateErrorCode>, <TUint iDeletionPause>, <TUint iDeletionErrorCode> <TBool iConnectToNtRas>
--- a/datacommsserver/esockserver/test/TE_RConnection/configs/ContentionManagement/config_004.txt Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RConnection/configs/ContentionManagement/config_004.txt Thu Jan 07 13:34:53 2010 +0200
@@ -15,7 +15,7 @@
# ContextConfigGPRS = <TProtocolType>, <TGSNAddress>, <TProtocolAddress>, <PdpDataCompression>, <TAnonymousAccess>, <TUseEdge>
# ProtocolConfigOption = <Authentication Protocol>, <Username>, <Password>, <Challenge>,
# <Response>, <PrimaryDNS>, <SecondaryDNS>, <TUint iId>
-SetContextConfigGPRS= 0,Test,,0, 2, 0, 0,RasUser,,,,,,0
+SetContextConfigGPRS = 0,Test,,0,2,0,1,RasUser,,,,,,1
# TRel99ContextConfig = <TName iContextName>, <TUint iActivatePause>, <TUint iActivateErrorCode>, <TUint iDeactivatePause>,
# <TUint iDeactivateErrorCode>, <TUint iDeletionPause>, <TUint iDeletionErrorCode> <TBool iConnectToNtRas>
--- a/datacommsserver/esockserver/test/TE_RConnection/configs/ContentionManagement/config_015.txt Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RConnection/configs/ContentionManagement/config_015.txt Thu Jan 07 13:34:53 2010 +0200
@@ -15,7 +15,7 @@
# ContextConfigGPRS = <TProtocolType>, <TGSNAddress>, <TProtocolAddress>, <PdpDataCompression>, <TAnonymousAccess>, <TUseEdge>
# ProtocolConfigOption = <Authentication Protocol>, <Username>, <Password>, <Challenge>,
# <Response>, <PrimaryDNS>, <SecondaryDNS>, <TUint iId>
-SetContextConfigGPRS= 0,Test,,0, 2, 0, 0,RasUser,,,,,,0
+SetContextConfigGPRS = 0,Test,,0,2,0,1,RasUser,,,,,,1
# TRel99ContextConfig = <TName iContextName>, <TUint iActivatePause>, <TUint iActivateErrorCode>, <TUint iDeactivatePause>,
# <TUint iDeactivateErrorCode>, <TUint iDeletionPause>, <TUint iDeletionErrorCode> <TBool iConnectToNtRas>
--- a/datacommsserver/esockserver/test/TE_RConnectionServ/configs/CIT_mixedap_config.txt Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RConnectionServ/configs/CIT_mixedap_config.txt Thu Jan 07 13:34:53 2010 +0200
@@ -14,7 +14,8 @@
# ContextConfigGPRS = <TProtocolType>, <TGSNAddress>, <TProtocolAddress>, <PdpDataCompression>, <TAnonymousAccess>, <TUseEdge>
# ProtocolConfigOption = <Authentication Protocol>, <Username>, <Password>, <Challenge>,
# <Response>, <PrimaryDNS>, <SecondaryDNS>, <TUint iId>
-SetContextConfigGPRS= 0,Test,,0, 2, 0, 0,RasUser,,,,,,0
+SetContextConfigGPRS = 0,Test,,0,2,0,1,RasUser,,,,,,1
+
# TRel99ContextConfig = <TName iContextName>, <TUint iActivatePause>, <TUint iActivateErrorCode>, <TUint iDeactivatePause>,
# <TUint iDeactivateErrorCode>, <TUint iDeletionPause>, <TUint iDeletionErrorCode> <TBool iConnectToNtRas>
--- a/datacommsserver/esockserver/test/TE_RConnectionServ/configs/CIT_pppavail_config.txt Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RConnectionServ/configs/CIT_pppavail_config.txt Thu Jan 07 13:34:53 2010 +0200
@@ -14,7 +14,7 @@
# ContextConfigGPRS = <TProtocolType>, <TGSNAddress>, <TProtocolAddress>, <PdpDataCompression>, <TAnonymousAccess>, <TUseEdge>
# ProtocolConfigOption = <Authentication Protocol>, <Username>, <Password>, <Challenge>,
# <Response>, <PrimaryDNS>, <SecondaryDNS>, <TUint iId>
-SetContextConfigGPRS= 0,Test,,0, 2, 0, 0,RasUser,,,,,,0
+SetContextConfigGPRS = 0,Test,,0,2,0,1,RasUser,,,,,,1
# TRel99ContextConfig = <TName iContextName>, <TUint iActivatePause>, <TUint iActivateErrorCode>, <TUint iDeactivatePause>,
# <TUint iDeactivateErrorCode>, <TUint iDeletionPause>, <TUint iDeletionErrorCode> <TBool iConnectToNtRas>
--- a/datacommsserver/esockserver/test/TE_RConnectionSuite/config/rconnectioncmm_test456_config.txt Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RConnectionSuite/config/rconnectioncmm_test456_config.txt Thu Jan 07 13:34:53 2010 +0200
@@ -14,7 +14,7 @@
# ContextConfigGPRS = <TProtocolType>, <TGSNAddress>, <TProtocolAddress>, <PdpDataCompression>, <TAnonymousAccess>, <TUseEdge>
# ProtocolConfigOption = <Authentication Protocol>, <Username>, <Password>, <Challenge>,
# <Response>, <PrimaryDNS>, <SecondaryDNS>, <TUint iId>
-SetContextConfigGPRS= 0,Test,,0, 2, 0, 0,RasUser,,,,,,0
+SetContextConfigGPRS= 0,Test,,0, 2, 0, 1,RasUser,,,,,,1
# TRel99ContextConfig = <TName iContextName>, <TUint iActivatePause>, <TUint iActivateErrorCode>, <TUint iDeactivatePause>,
# <TUint iDeactivateErrorCode>, <TUint iDeletionPause>, <TUint iDeletionErrorCode> <TBool iConnectToNtRas>
--- a/datacommsserver/esockserver/test/TE_RConnectionSuite/config/te_rconnectionallinterfacenot_Connection_Tests.script Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RConnectionSuite/config/te_rconnectionallinterfacenot_Connection_Tests.script Thu Jan 07 13:34:53 2010 +0200
@@ -111,3 +111,11 @@
END_TESTCASE COMINF-ESOCK-RConnectionSuite-AllInterfaceNot-0109
+START_TESTCASE COMINF-ESOCK-RConnectionSuite-AllInterfaceNot-0111
+//! @SYMTestCaseID COMINF-ESOCK-RConnectionSuite-AllInterfaceNot-0111
+
+heap_mark
+run_test_step 500, TE_RConnectionSuite Test319 c:\rconnectiontest.ini
+heap_markend
+test_complete
+END_TESTCASE COMINF-ESOCK-RConnectionSuite-AllInterfaceNot-0111
--- a/datacommsserver/esockserver/test/TE_RConnectionSuite/config/te_rconnectioncmmtests_NonConnection.script Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RConnectionSuite/config/te_rconnectioncmmtests_NonConnection.script Thu Jan 07 13:34:53 2010 +0200
@@ -241,6 +241,38 @@
#test_complete
//END_TESTCASE COMINF-ESOCK-RConnectionSuite-CMM-0621
+START_TESTCASE COMINF-ESOCK-RConnectionSuite-CMM-0622
+//! @SYMTestCaseID COMINF-ESOCK-RConnectionSuite-CMM-0622
+//!@SYMTestCaseDesc Test correct progresses arrive at the correct times
+//!@SYMPREQ PREQ399
+//!@SYMAPI
+//RConnection::Progress()
+//RConnection::ProgressNotification()
+//!@SYMTestPriority Critical
+//!@SYMTestActions
+// Open conn1
+// Request progress on conn1
+// Check progress (Should be KConnectionUninitialised)
+// Request progress notification on conn1
+// Start conn1
+// Check progress (Should be KStartingSelection)
+// Stop conn1
+// Open conn1
+// Request progress on conn1
+// Check progress (Should be KConnectionUninitialised)
+// Request progress notification on conn1 for when conn1 gets KFinishedSelection progress
+// Start conn1
+// Check progress (Should be KFinishedSelection)
+// Stop conn1
+//
+//!@SYMTestType CIT
+//!@SYMTestExpectedResults All progresses are as expected
+
+heap_mark
+run_test_step 100, TE_RConnectionSuite Test319 c:\rconnectiontest.ini
+heap_markend
+test_complete
+END_TESTCASE COMINF-ESOCK-RConnectionSuite-CMM-0622
run_script z:\TestData\scripts\te_esock_test_unloadesockForced.script
--- a/datacommsserver/esockserver/test/TE_RConnectionSuite/inc/TE_AllInterfaceNotification.h Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RConnectionSuite/inc/TE_AllInterfaceNotification.h Thu Jan 07 13:34:53 2010 +0200
@@ -153,11 +153,5 @@
};
-class TE_RConnectionTest319 : public TE_RConnectionStep
-{
-public:
- virtual enum TVerdict doTestStepL();
-
-};
#endif // TS_ALLINTERFACENOTIFICATION_H
--- a/datacommsserver/esockserver/test/TE_RConnectionSuite/inc/TE_RConnectionCMM.h Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RConnectionSuite/inc/TE_RConnectionCMM.h Thu Jan 07 13:34:53 2010 +0200
@@ -861,5 +861,12 @@
virtual enum TVerdict doTestStepL ();
};
+class TE_RConnectionTest319 : public TE_RConnectionStep
+{
+public:
+ virtual enum TVerdict doTestStepL();
+
+};
+
#endif // TE_RConnectionCMM_H
--- a/datacommsserver/esockserver/test/TE_RConnectionSuite/src/TE_AllInterfaceNotification.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RConnectionSuite/src/TE_AllInterfaceNotification.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -1628,66 +1628,3 @@
return TestStepResult();
} // TE_RConnectionTest318
-/******************************************************************************
- *
- * Test 319
- *
- * To test progress
- *
- *****************************************************************************/
-
-// To test progress
-enum TVerdict TE_RConnectionTest319::doTestStepL(void)
-{
- RSocketServ ss;
- RConnection conn1;
-
- TRequestStatus tStartConn;
-
- TInt nErr = OpenSocketServer( ss );
- TESTEL(KErrNone == nErr, nErr);
- CleanupClosePushL(ss);
-
- nErr = conn1.Open( ss );
- TESTEL( nErr == KErrNone, nErr );
- CleanupClosePushL(conn1);
-
- TNifProgress tProg;
- conn1.Progress( tProg );
- TESTEL( tProg.iError == KErrNone && tProg.iStage == 0, tProg.iError );
-
- TNifProgressBuf tNifProgressBuf;
- conn1.ProgressNotification( tNifProgressBuf, tStartConn, KConnProgressDefault );
- nErr = conn1.Start();
- TESTEL( nErr == KErrNone, nErr );
- User::WaitForRequest( tStartConn );
- TESTEL( tStartConn.Int() == KErrNone, tStartConn.Int() );
- TESTEL( tNifProgressBuf().iStage == KStartingSelection, tNifProgressBuf().iStage );
-
- //close conn1
- conn1.Stop();
- CleanupStack::PopAndDestroy();
-
- nErr = conn1.Open( ss );
- TESTEL( nErr == KErrNone, nErr );
- CleanupClosePushL(conn1);
-
- conn1.Progress( tProg );
- TESTEL( tProg.iError == KErrNone && tProg.iStage == 0, tProg.iError );
- //wait for particular guy
- conn1.ProgressNotification( tNifProgressBuf, tStartConn, KFinishedSelection );
- nErr = conn1.Start();
- TESTEL( nErr == KErrNone, nErr );
- User::WaitForRequest( tStartConn );
- TESTEL( tStartConn.Int() == KErrNone, tStartConn.Int() );
- TESTEL( tNifProgressBuf().iStage == KFinishedSelection, tNifProgressBuf().iStage );
-
- //close conn1
- conn1.Stop();
- CleanupStack::PopAndDestroy();
-
- //close ss
- CleanupStack::PopAndDestroy();
- return TestStepResult();
-} // TE_RConnectionTest319
-
--- a/datacommsserver/esockserver/test/TE_RConnectionSuite/src/TE_RConnectionCMM.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RConnectionSuite/src/TE_RConnectionCMM.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -7202,5 +7202,72 @@
} // TE_RConnectionTest480
+/******************************************************************************
+ *
+ * Test 319
+ *
+ * To test progress
+ *
+ *****************************************************************************/
+
+// To test progress
+enum TVerdict TE_RConnectionTest319::doTestStepL(void)
+{
+ RSocketServ ss;
+ RConnection conn1;
+
+ TRequestStatus tStartConn;
+
+ TInt nErr = OpenSocketServer( ss );
+ TESTEL(KErrNone == nErr, nErr);
+ CleanupClosePushL(ss);
+
+ nErr = conn1.Open( ss );
+ TESTEL( nErr == KErrNone, nErr );
+ CleanupClosePushL(conn1);
+
+ TNifProgress tProg;
+ conn1.Progress( tProg );
+ TESTEL( tProg.iError == KErrNone && tProg.iStage == 0, tProg.iError );
+
+ TNifProgressBuf tNifProgressBuf;
+ conn1.ProgressNotification( tNifProgressBuf, tStartConn, KConnProgressDefault );
+
+ nErr = StartConnectionWithOverrides(conn1, iDummyNifIap);
+
+ TESTEL( nErr == KErrNone, nErr );
+ User::WaitForRequest( tStartConn );
+ TESTEL( tStartConn.Int() == KErrNone, tStartConn.Int() );
+ TESTEL( tNifProgressBuf().iStage == KStartingSelection, tNifProgressBuf().iStage );
+
+ //close conn1
+ conn1.Stop();
+ CleanupStack::PopAndDestroy();
+
+ nErr = conn1.Open( ss );
+ TESTEL( nErr == KErrNone, nErr );
+ CleanupClosePushL(conn1);
+
+ conn1.Progress( tProg );
+ TESTEL( tProg.iError == KErrNone && tProg.iStage == 0, tProg.iError );
+ //wait for particular guy
+ conn1.ProgressNotification( tNifProgressBuf, tStartConn, KFinishedSelection );
+ nErr = StartConnectionWithOverrides(conn1, iDummyNifIap);
+
+ TESTEL( nErr == KErrNone, nErr );
+ User::WaitForRequest( tStartConn );
+ TESTEL( tStartConn.Int() == KErrNone, tStartConn.Int() );
+ TESTEL( tNifProgressBuf().iStage == KFinishedSelection, tNifProgressBuf().iStage );
+
+ //close conn1
+ conn1.Stop();
+ CleanupStack::PopAndDestroy();
+
+ //close ss
+ CleanupStack::PopAndDestroy();
+ return TestStepResult();
+} // TE_RConnectionTest319
+
+
// EOF TE_RConnectionCMM.cpp
--- a/datacommsserver/esockserver/test/TE_RSubconnection/configs/te_RSubConnectionCase28.txt Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RSubconnection/configs/te_RSubConnectionCase28.txt Thu Jan 07 13:34:53 2010 +0200
@@ -14,7 +14,7 @@
# ContextConfigGPRS = <TProtocolType>, <TGSNAddress>, <TProtocolAddress>, <PdpDataCompression>, <TAnonymousAccess>, <TUseEdge>
# ProtocolConfigOption = <Authentication Protocol>, <Username>, <Password>, <Challenge>,
# <Response>, <PrimaryDNS>, <SecondaryDNS>, <TUint iId>
-SetContextConfigGPRS= 0,Test,,0, 2, 0, 0,RasUser,,,,,,0
+SetContextConfigGPRS = 0,Test,,0,2,0,1,RasUser,,,,,,1
# TRel99ContextConfig = <TName iContextName>, <TUint iActivatePause>, <TUint iActivateErrorCode>, <TUint iDeactivatePause>,
# <TUint iDeactivateErrorCode>, <TUint iDeletionPause>, <TUint iDeletionErrorCode> <TBool iConnectToNtRas>
--- a/datacommsserver/esockserver/test/TE_RSubconnection/configs/te_RSubConnection_simtsy.txt Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/TE_RSubconnection/configs/te_RSubConnection_simtsy.txt Thu Jan 07 13:34:53 2010 +0200
@@ -12,7 +12,8 @@
# ContextConfigGPRS = <TProtocolType>, <TGSNAddress>, <TProtocolAddress>, <PdpDataCompression>, <TAnonymousAccess>, <TUseEdge>
# ProtocolConfigOption = <Authentication Protocol>, <Username>, <Password>, <Challenge>,
# <Response>, <PrimaryDNS>, <SecondaryDNS>, <TUint iId>
-SetContextConfigGPRS= 0,Test,,0, 2, 0, 0,RasUser,,,,,,0
+SetContextConfigGPRS = 0,Test,,0,2,0,1,RasUser,,,,,,1
+
# TRel99ContextConfig = <TName iContextName>, <TUint iActivatePause>, <TUint iActivateErrorCode>, <TUint iDeactivatePause>,
# <TUint iDeactivateErrorCode>, <TUint iDeletionPause>, <TUint iDeletionErrorCode> <TBool iConnectToNtRas>
--- a/datacommsserver/esockserver/test/providers/dummy/inc/dummypr_mcprpubsubsubscriber.h Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/providers/dummy/inc/dummypr_mcprpubsubsubscriber.h Thu Jan 07 13:34:53 2010 +0200
@@ -1,9 +1,9 @@
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
-// under the terms of the License "Symbian Foundation License v1.0"
+// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
-// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
--- a/datacommsserver/esockserver/test/providers/dummy/inc/dummypr_metaconnprov.h Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/providers/dummy/inc/dummypr_metaconnprov.h Thu Jan 07 13:34:53 2010 +0200
@@ -1,9 +1,9 @@
// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
-// under the terms of the License "Symbian Foundation License v1.0"
+// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
-// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
--- a/datacommsserver/esockserver/test/providers/dummy/src/dummypr_mcprpubsubsubscriber.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/providers/dummy/src/dummypr_mcprpubsubsubscriber.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -1,9 +1,9 @@
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
-// under the terms of the License "Symbian Foundation License v1.0"
+// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
-// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
@@ -70,7 +70,7 @@
iProperty.Close();
}
-///////////////////////////////////////////////////////////////////////////////
+//
CMCPrPubSubAvailability* CMCPrPubSubAvailability::NewL(const ESock::CMetaConnectionProviderBase& aProvBase, TUint aStopCode)
{
@@ -134,9 +134,11 @@
__CFLOG_VAR((KDummyMCprTag, KDummyMCprSubTag, _L8("CMCPrPubSubAvailability subscribed value now %d"),value));
__ASSERT_DEBUG(!iAvailabilityActivity.IsNull(), User::Panic(KSpecAssert_DummyPrStopSubsc, 1)); //maybe a bit defensive, but this is test code after all. The test changes availability when nobody is listenning; Surely test is wrong?
+ RClientInterface::OpenPostMessageClose(Id(), iAvailabilityActivity,
+ TCFAvailabilityControlClient::TAvailabilityNotification(value).CRef());
}
-///////////////////////////////////////////////////////////////////////////////
+//
CMCPrPubSubStopTrigger* CMCPrPubSubStopTrigger::NewL(const ESock::CMetaConnectionProviderBase& aProvBase, TUint aStopCode)
{
--- a/datacommsserver/esockserver/test/providers/dummy/src/dummypr_metaconnprov.cpp Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/test/providers/dummy/src/dummypr_metaconnprov.cpp Thu Jan 07 13:34:53 2010 +0200
@@ -1,9 +1,9 @@
// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
-// under the terms of the License "Symbian Foundation License v1.0"
+// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
-// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.