|
1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // PDP SubConnection Provider implementation |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 @internalComponent |
|
21 */ |
|
22 |
|
23 #include <comms-infras/corescpractivities.h> |
|
24 #include "PDPDeftSCPR.h" |
|
25 #include "PDPSCPRStates.h" |
|
26 #include "PDPSCPRFactory.h" |
|
27 #include <comms-infras/ss_log.h> |
|
28 #include <comms-infras/commsdebugutility.h> |
|
29 #include <elements/nm_signatures.h> |
|
30 |
|
31 #if defined(__CFLOG_ACTIVE) || defined(SYMBIAN_TRACE_ENABLE) |
|
32 #define KPDPSCprTag KESockSubConnectionTag |
|
33 _LIT8(KPDPSCprSubTag, "pdpscpr"); |
|
34 #endif |
|
35 |
|
36 using namespace Messages; |
|
37 using namespace MeshMachine; |
|
38 using namespace ESock; |
|
39 using namespace NetStateMachine; |
|
40 |
|
41 |
|
42 //-========================================================= |
|
43 // |
|
44 // Activities |
|
45 // |
|
46 //-========================================================= |
|
47 |
|
48 namespace PDPDeftSCprDataClientStartActivity |
|
49 { |
|
50 typedef MeshMachine::TAcceptErrorState<CoreNetStates::TAwaitingDataClientStarted> TAwaitingDataClientStartedOrError; |
|
51 |
|
52 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStartDataClient, PDPDeftDataClientStart, TCFDataClient::TStart, PDPSCprStates::CStartActivity::NewL) |
|
53 FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientStart, PDPSCprStates::TNoTagOrAlreadyStarted) |
|
54 LAST_NODEACTIVITY_ENTRY(CoreNetStates::KAlreadyStarted, PRStates::TSendDataClientStarted) |
|
55 |
|
56 NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TCreatePrimaryPDPCtx, PDPSCprStates::TAwaitingPrimaryPDPCtxCreated, PDPSCprStates::TNoTagOrSendErrorRecoveryRequestOrError) |
|
57 NODEACTIVITY_ENTRY(PDPSCprStates::KSendErrorRecoveryRequest, PDPSCprStates::TSendErrorRecoveryRequest, MeshMachine::TAwaitingErrorRecoveryResponseOrError, PDPSCprStates::TNoTagBackwardOrErrorTag) |
|
58 THROUGH_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TFillInGrantedParamsAndImsExtParams, MeshMachine::TNoTag) |
|
59 NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TOverrideProvisionAndStartDataClient, TAwaitingDataClientStartedOrError, MeshMachine::TNoTagOrErrorTag) |
|
60 LAST_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TSendDataClientStarted) |
|
61 |
|
62 // Cleanup if error occurred |
|
63 THROUGH_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing, CoreNetStates::TNoTagOrNoDataClientsToStop) |
|
64 NODEACTIVITY_ENTRY(KNoTag, SCprStates::TStopYourFlows, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TTag<CoreNetStates::KNoDataClientsToStop>) |
|
65 THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KNoDataClientsToStop, MeshMachine::TDoNothing, PDPSCprStates::TNoTagOrProviderStopped) |
|
66 NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TDestroyPDPContext, PDPSCprStates::TAwaitingPDPContextDestroyed, MeshMachine::TTag<CoreNetStates::KProviderStopped>) |
|
67 THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, PRStates::TDestroyOrphanedDataClients, MeshMachine::TTag<CoreNetStates::KProviderStopped>) |
|
68 LAST_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, MeshMachine::TRaiseActivityError) |
|
69 NODEACTIVITY_END() |
|
70 } |
|
71 |
|
72 namespace PDPSCprNetworkStatusEventActivity |
|
73 { |
|
74 DECLARE_DEFINE_NODEACTIVITY(ECFActivityNotification, subConnStatusEvent, TPDPFSMMessages::TPDPFSMMessage) |
|
75 FIRST_NODEACTIVITY_ENTRY(PDPSCprStates::TAwaitingNetworkStatusEvent, PDPSCprStates::TNetworkStatusEventTypeTag) |
|
76 LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing) |
|
77 |
|
78 // Assume that anything other than EStatusUnattached means the network |
|
79 // is still up, so just ignore this event. |
|
80 LAST_NODEACTIVITY_ENTRY(RPacketService::EStatusAttached, MeshMachine::TDoNothing) |
|
81 LAST_NODEACTIVITY_ENTRY(RPacketService::EStatusActive, MeshMachine::TDoNothing) |
|
82 LAST_NODEACTIVITY_ENTRY(RPacketService::EStatusSuspended, MeshMachine::TDoNothing) |
|
83 |
|
84 NODEACTIVITY_ENTRY(RPacketService::EStatusUnattached, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TNoTag) |
|
85 LAST_NODEACTIVITY_ENTRY(KNoTag, SCprStates::TSendDataClientGoneDown) |
|
86 NODEACTIVITY_END() |
|
87 } |
|
88 |
|
89 namespace PDPDeftSCprGoneDownActivity |
|
90 { |
|
91 //TODO perhaps get this from a header file since its used in a number of places - see ss_subconn.cpp |
|
92 typedef MeshMachine::TAcceptErrorState<CoreNetStates::TAwaitingApplyResponse> TAwaitingApplyResponseOrError; |
|
93 |
|
94 //mandated by 3GPP TS 23.107 Annex C, the default going down needs to select a new default |
|
95 //among the non-defaults and swap the datapath. Swapping datapath is now done |
|
96 //transparently, i.e.: without the upper layer knowing (binders are kept, flows are swapped). |
|
97 //This arguably isn't pretty and could be changed to something more explicit, i.e.: |
|
98 //sending TBindToRequest to the upper layer SCPR so that it does an explit rebind. |
|
99 //[401TODO]: the swap only works for rawIp, doesn't for PPP. |
|
100 //[401TODO]: if we stick to the transpartent swap, we need to change the message |
|
101 // this scpr sends to the flow. The flow responds with a full swap |
|
102 // to TRejoin, whereas TRejoin doesn't mean swap - suggesting to |
|
103 // introduce PDP level msg: TRejoinAndSwap. |
|
104 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityGoneDown, PDPDeftSCprGoneDown, TPDPFSMMessages::TPDPFSMMessage, PDPSCprStates::CPrimaryPDPGoneDownActivity::NewL) |
|
105 FIRST_NODEACTIVITY_ENTRY(PDPSCprStates::TAwaitingPDPContextGoneDown, MeshMachine::TActiveOrNoTag<ECFActivityStartDataClient>) |
|
106 THROUGH_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, PDPSCprStates::CPrimaryPDPGoneDownActivity::TNoTagOrProviderStopped) |
|
107 THROUGH_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::CPrimaryPDPGoneDownActivity::TStoreOriginalDataClient, MeshMachine::TNoTag) |
|
108 NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::CPrimaryPDPGoneDownActivity::TRejoinDataClient, CoreNetStates::TAwaitingRejoinDataClientComplete, MeshMachine::TNoTag) |
|
109 NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::CPrimaryPDPGoneDownActivity::TApplyNewDefault, TAwaitingApplyResponseOrError, MeshMachine::TNoTag) |
|
110 THROUGH_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::CPrimaryPDPGoneDownActivity::TSwitchToNewDefault, MeshMachine::TNoTag) |
|
111 NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::CPrimaryPDPGoneDownActivity::TStopOriginalDataClient, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TNoTag) |
|
112 |
|
113 LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TClearError) |
|
114 THROUGH_NODEACTIVITY_ENTRY(KActiveTag, MeshMachine::TDoNothing, PDPSCprStates::TNoTagOrContentionTag) |
|
115 //Awaiting for contention result, do not stop the start activity. |
|
116 LAST_NODEACTIVITY_ENTRY(PDPSCprStates::KContentionTag, MeshMachine::TDoNothing) |
|
117 |
|
118 LAST_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TCancelDataClientStartInPDP) |
|
119 |
|
120 NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TTag<CoreNetStates::KProviderStopped>) |
|
121 LAST_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, PDPSCprStates::TSendGoneDown) |
|
122 NODEACTIVITY_END() |
|
123 } |
|
124 |
|
125 namespace PDPDeftSCprClientLeaveActivity |
|
126 { //This activity will wait for ECFActivityBinderRequest to complete |
|
127 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityClientLeave, PDPDeftSCprClientLeave, TNodeSignal::TNullMessageId, MeshMachine::CNodeRetryActivity::NewL) //May be waiting for both messages |
|
128 NODEACTIVITY_ENTRY(KNoTag, PRStates::TRemoveClientAndSendLeaveCompleteIfRequest, CoreStates::TAwaitingClientLeave, CoreNetStates::TNoTagBlockedByBindToAndNoClients) |
|
129 LAST_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TSendDataClientIdleIfNoSubconnsAndNoClients) |
|
130 NODEACTIVITY_END() |
|
131 } |
|
132 |
|
133 namespace PDPDeftSCprIoctlActivity |
|
134 { |
|
135 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityIoctl, PDPDeftSCprIoctl, TNodeSignal::TNullMessageId, MeshMachine::CNodeParallelMessageStoreActivityBase::NewL) |
|
136 FIRST_NODEACTIVITY_ENTRY(PDPSCprStates::TAwaitingIoctlMessage, MeshMachine::TNoTag) |
|
137 NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TRetrieveSipAddr, CoreNetStates::TAwaitingRMessage2Processed, MeshMachine::TNoTag) |
|
138 LAST_NODEACTIVITY_ENTRY(KNoTag, CoreStates::TPostToOriginators) |
|
139 NODEACTIVITY_END() |
|
140 } |
|
141 |
|
142 namespace PDPDefSCprActivities |
|
143 { |
|
144 DECLARE_DEFINE_ACTIVITY_MAP(activityMap) |
|
145 ACTIVITY_MAP_ENTRY(PDPDeftSCprDataClientStartActivity, PDPDeftDataClientStart) |
|
146 ACTIVITY_MAP_ENTRY(PDPSCprNetworkStatusEventActivity, subConnStatusEvent) |
|
147 ACTIVITY_MAP_ENTRY(PDPDeftSCprGoneDownActivity, PDPDeftSCprGoneDown) |
|
148 ACTIVITY_MAP_ENTRY(PDPDeftSCprClientLeaveActivity, PDPDeftSCprClientLeave) |
|
149 ACTIVITY_MAP_ENTRY(PDPDeftSCprIoctlActivity, PDPDeftSCprIoctl) |
|
150 ACTIVITY_MAP_END_BASE(PDPSCprActivities, activityMap) |
|
151 } |
|
152 |
|
153 //-========================================================= |
|
154 // |
|
155 // CPDPDefaultSubConnectionProvider methods |
|
156 // |
|
157 //-========================================================= |
|
158 |
|
159 CPDPDefaultSubConnectionProvider::CPDPDefaultSubConnectionProvider(ESock::CSubConnectionProviderFactoryBase& aFactory) |
|
160 : CPDPSubConnectionProvider(aFactory, PDPDefSCprActivities::activityMap::Self()) |
|
161 { |
|
162 LOG_NODE_CREATE1(KPDPSCprSubTag, CPDPDefaultSubConnectionProvider, " [factory=%08x]", &aFactory) |
|
163 __FLOG_OPEN(KCFNodeTag, KPDPSCprSubTag); |
|
164 } |
|
165 |
|
166 CPDPDefaultSubConnectionProvider::~CPDPDefaultSubConnectionProvider() |
|
167 { |
|
168 LOG_NODE_DESTROY(KPDPSCprSubTag, CPDPDefaultSubConnectionProvider) |
|
169 __FLOG_CLOSE; |
|
170 } |
|
171 |
|
172 CPDPDefaultSubConnectionProvider* CPDPDefaultSubConnectionProvider::NewL(CPDPSubConnectionProviderFactory& aFactory) |
|
173 /** |
|
174 Construct a new PDP SubConnection Provider Object |
|
175 |
|
176 @params aFactory factory that create this object |
|
177 @param aConnProvider Connection Provider associated with this object |
|
178 */ |
|
179 { |
|
180 CPDPDefaultSubConnectionProvider* ptr = new (ELeave) CPDPDefaultSubConnectionProvider(aFactory); |
|
181 CleanupStack::PushL(ptr); |
|
182 ptr->ConstructL(); |
|
183 CleanupStack::Pop(); |
|
184 return ptr; |
|
185 } |
|
186 |
|
187 void CPDPDefaultSubConnectionProvider::ConstructL() |
|
188 { |
|
189 CPDPSubConnectionProvider::ConstructL(); |
|
190 iPdpFsmInterface = new (ELeave) CPdpFsmInterface(*this); |
|
191 } |
|
192 |
|
193 void CPDPDefaultSubConnectionProvider::PdpFsmAllContextEvent(TInt aNotification, TInt /*aParam*/) |
|
194 { |
|
195 if (aNotification == KNetworkStatusEvent) |
|
196 { |
|
197 TPDPFSMMessages::TPDPFSMMessage statusMsg(KNetworkStatusEvent, KErrNone); |
|
198 TRAP_IGNORE(ReceivedL(TNodeId(Id()), TNodeCtxId(0, Id()), statusMsg)); //TODO - use trap assert? |
|
199 } |
|
200 } |
|
201 |
|
202 void CPDPDefaultSubConnectionProvider::LinkUp() |
|
203 { |
|
204 if (iLinkUps++ == 0) |
|
205 { |
|
206 TCFMessage::TStateChange msg(Elements::TStateChange(KLinkLayerOpen, KErrNone)); |
|
207 //Forward to control clients if there are any |
|
208 TInt ctrlClientCount = PostToClients<TDefaultClientMatchPolicy>(Id(), msg, TClientType(TCFClientType::ECtrl)); |
|
209 if (0==ctrlClientCount) |
|
210 { //If there are no control clients any more, forward to the control provider |
|
211 PostToClients<TDefaultClientMatchPolicy>(Id(), msg, TClientType(TCFClientType::ECtrlProvider)); |
|
212 } |
|
213 } |
|
214 } |
|
215 |
|
216 void CPDPDefaultSubConnectionProvider::LinkDown(TInt aCause) |
|
217 { |
|
218 if (++iLinkDowns-iLinkUps == 0 || iLinkUps == 0) |
|
219 { |
|
220 ControlProvider()->PostMessage(Id(), |
|
221 TCFMessage::TStateChange(Elements::TStateChange(KLinkLayerClosed, aCause)).CRef()); |
|
222 } |
|
223 SendDataClientIdleIfNoSubconnsAndNoClientsL(); |
|
224 } |
|
225 |
|
226 void CPDPDefaultSubConnectionProvider::SendDataClientIdleIfNoSubconnsAndNoClientsL() |
|
227 { |
|
228 // linkDowns is called more places than linkup, so it may in fact be higher, would be nice if something was |
|
229 // done in the future to make iLinkDowns and iLinkUps are symettrical |
|
230 if (iLinkDowns-iLinkUps >= 0 || iLinkUps == 0) |
|
231 { |
|
232 if (GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl|TCFClientType::EAux))==NULL |
|
233 && GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EActive)) == NULL) |
|
234 { |
|
235 RNodeInterface* cp = ControlProvider(); |
|
236 if (cp) |
|
237 { //If there is no Control Provider we probably are an MCPR/Tier Manager/etc |
|
238 cp->PostMessage(Id(), TCFControlProvider::TIdle().CRef()); |
|
239 } |
|
240 return; |
|
241 } |
|
242 |
|
243 RNodeInterface* cc = GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl)); |
|
244 if (cc==NULL) |
|
245 { |
|
246 TClientIter<TDefaultClientMatchPolicy> dciter = GetClientIter<TDefaultClientMatchPolicy>( |
|
247 TClientType( |
|
248 TCFClientType::EData, |
|
249 TCFClientType::EActive |
|
250 |TCFClientType::EActivating |
|
251 |TCFClientType::EStarted |
|
252 |TCFClientType::EStarting |
|
253 |TCFClientType::ELeaving |
|
254 ) |
|
255 ); |
|
256 |
|
257 TInt i = 0; |
|
258 RNodeInterface* dc; |
|
259 while ((dc = dciter[i++]) != NULL) |
|
260 { |
|
261 dc->PostMessage(Id(), TCFControlProvider::TIdle().CRef()); |
|
262 } |
|
263 } |
|
264 } |
|
265 } |