|
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 // IPProto Connection Provider implementation |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 @internalComponent |
|
21 */ |
|
22 |
|
23 #include <comms-infras/ss_nodemessages.h> |
|
24 #include <comms-infras/corecpractivities.h> |
|
25 |
|
26 #include <comms-infras/ss_metaconnprov.h> |
|
27 #include <comms-infras/sockmes.h> // for ioctl ipc |
|
28 |
|
29 #include "IPProtoCprStates.h" |
|
30 #include "IPProtoMessages.h" |
|
31 #include "linkcprextensionapi.h" |
|
32 #include <comms-infras/ss_datamonitoringprovider.h> |
|
33 #include <comms-infras/ss_connlegacy.h> |
|
34 #include <nifvar.h> // KLinkLayerOpen |
|
35 #include <comms-infras/ss_nodemessages_internal.h> |
|
36 #include <comms-infras/ss_legacyinterfaces.h> |
|
37 #include <comms-infras/simpleselectorbase.h> |
|
38 #include <commsdattypesv1_1_partner.h> |
|
39 #include <es_prot_internal.h> |
|
40 |
|
41 using namespace Messages; |
|
42 using namespace MeshMachine; |
|
43 using namespace IpProtoCpr; |
|
44 using namespace ESock; |
|
45 |
|
46 DEFINE_SMELEMENT(TStoreProvision, NetStateMachine::MStateTransition, IpProtoCpr::TContext) |
|
47 void TStoreProvision::DoL() |
|
48 { |
|
49 PRStates::TStoreProvision storeProvision(iContext); |
|
50 storeProvision.DoL(); |
|
51 |
|
52 CIPProtoConnectionProvider& node = iContext.Node(); |
|
53 |
|
54 // Retrieve the idle timer values from the provisioning information bucket |
|
55 const Meta::SMetaData* extension = |
|
56 node.AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TIdleTimerValues::iUid, TIdleTimerValues::iId)); |
|
57 |
|
58 if (extension) |
|
59 { |
|
60 const TIdleTimerValues* vals = static_cast<const TIdleTimerValues*>(extension); |
|
61 node.SetTimers(vals->iShortTimer, vals->iMediumTimer, vals->iLongTimer); |
|
62 } |
|
63 |
|
64 if (!node.iNodeLocalExtensionsCreated) |
|
65 { |
|
66 node.iNodeLocalExtensions.Open(); |
|
67 |
|
68 TPacketActivity* packetActivity = new(ELeave)TPacketActivity(&iContext.Node().iPeriodActivity); |
|
69 CleanupStack::PushL(packetActivity); |
|
70 node.iNodeLocalExtensions.AppendExtensionL(packetActivity); |
|
71 CleanupStack::Pop(packetActivity); |
|
72 |
|
73 // Allocate and add the data monitoring shared memory pointers to the provisioning info |
|
74 TDataMonitoringConnProvisioningInfo* connProvisioningInfo = new (ELeave) TDataMonitoringConnProvisioningInfo(&node.iDataVolumes, &node.iThresholds); |
|
75 CleanupStack::PushL(connProvisioningInfo); |
|
76 node.iNodeLocalExtensions.AppendExtensionL(connProvisioningInfo); |
|
77 CleanupStack::Pop(connProvisioningInfo); |
|
78 |
|
79 // Allocate the data monitoring subconnection data structure. |
|
80 // |
|
81 // This used to be allocated in the SCPR, but it has been moved here to the CPR. This is because there can be |
|
82 // temporary circumstances where there is more than one SCPR present - one or more of these in a leaving |
|
83 // state and one in an active state. The access point config cannot presently hold provisioning information |
|
84 // specific to an SCPR instance, so it is allocated and managed here in the CPR as a shared entity. Only |
|
85 // one SCPR instance should be using this at a time, however. |
|
86 TDataMonitoringSubConnProvisioningInfo* subConnProvisioningInfo = new (ELeave) TDataMonitoringSubConnProvisioningInfo(NULL, NULL); |
|
87 CleanupStack::PushL(subConnProvisioningInfo); |
|
88 node.iNodeLocalExtensions.AppendExtensionL(subConnProvisioningInfo); |
|
89 CleanupStack::Pop(subConnProvisioningInfo); |
|
90 |
|
91 // The CLinkCprExtensionApi may have been added previously if this is a reconnect scenario |
|
92 // We add it again in this new override of the extensions, if the old container is fully superceded |
|
93 // it will be closed and destroyed. |
|
94 extension = CLinkCprExtensionApi::NewLC(iContext.Node()); |
|
95 node.iNodeLocalExtensions.AppendExtensionL(extension); |
|
96 CleanupStack::Pop(); // CLinkCprExtensionApi |
|
97 |
|
98 node.iNodeLocalExtensionsCreated = ETrue; |
|
99 } |
|
100 |
|
101 RMetaExtensionContainer mec; |
|
102 mec.Open(iContext.Node().AccessPointConfig()); |
|
103 CleanupClosePushL(mec); |
|
104 mec.AppendContainerL(node.iNodeLocalExtensions); |
|
105 |
|
106 iContext.Node().iAccessPointConfig.Close(); |
|
107 iContext.Node().iAccessPointConfig.Open(mec); |
|
108 CleanupStack::PopAndDestroy(&mec); |
|
109 |
|
110 // For the case that this is an update of the provisioned info we forward it to non-leaving data clients |
|
111 TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>( |
|
112 TClientType(TCFClientType::EData), |
|
113 TClientType(0, TClientType::ELeaving) |
|
114 ); |
|
115 |
|
116 for (TInt i = 0; iter[i]; i++) |
|
117 { |
|
118 iter[i]->PostMessage( |
|
119 iContext.NodeId(), |
|
120 TCFDataClient::TProvisionConfig(iContext.Node().iAccessPointConfig).CRef() |
|
121 ); |
|
122 } |
|
123 } |
|
124 |
|
125 DEFINE_SMELEMENT(TAwaitingDataMonitoringNotification, NetStateMachine::MState, IpProtoCpr::TContext) |
|
126 TBool TAwaitingDataMonitoringNotification::Accept() |
|
127 { |
|
128 return iContext.iMessage.IsMessage<TCFDataMonitoringNotification::TDataMonitoringNotification>(); |
|
129 } |
|
130 |
|
131 |
|
132 DEFINE_SMELEMENT( TAwaitingGoneDown , NetStateMachine::MState, IpProtoCpr::TContext) |
|
133 TBool TAwaitingGoneDown::Accept() |
|
134 { |
|
135 if (iContext.iMessage.IsMessage<TCFControlClient::TGoneDown>()) |
|
136 { |
|
137 iContext.Node().LinkDown(); |
|
138 } |
|
139 // return EFalse to allow further PRActivities processing |
|
140 return EFalse; |
|
141 } |
|
142 |
|
143 |
|
144 DEFINE_SMELEMENT(TProcessDataMonitoringNotification, NetStateMachine::MStateTransition, IpProtoCpr::TContext) |
|
145 void TProcessDataMonitoringNotification::DoL() |
|
146 { |
|
147 TCFDataMonitoringNotification::TDataMonitoringNotification& msg = |
|
148 message_cast<TCFDataMonitoringNotification::TDataMonitoringNotification>(iContext.iMessage); |
|
149 |
|
150 iContext.Node().DataNotificationL(msg); |
|
151 } |
|
152 |
|
153 DEFINE_SMELEMENT(TAwaitingStart, NetStateMachine::MState, IpProtoCpr::TContext) |
|
154 TBool TAwaitingStart::Accept() |
|
155 { |
|
156 CoreNetStates::TAwaitingStart state(iContext); |
|
157 if (state.Accept()) |
|
158 { |
|
159 iContext.Node().DisableTimers(); |
|
160 return ETrue; |
|
161 } |
|
162 return EFalse; |
|
163 } |
|
164 |
|
165 DEFINE_SMELEMENT(TCleanupStart, NetStateMachine::MStateTransition, IpProtoCpr::TContext) |
|
166 void TCleanupStart::DoL() |
|
167 { |
|
168 //Re-enable idle timers disabled by IpProtoCpr::TAwaitingStart |
|
169 iContext.Node().EnableTimers(); |
|
170 } |
|
171 |
|
172 DEFINE_SMELEMENT(TCheckIfLastControlClientLeaving, NetStateMachine::MStateTransition, IpProtoCpr::TContext) |
|
173 void TCheckIfLastControlClientLeaving::DoL() |
|
174 { |
|
175 CIPProtoConnectionProvider& node = iContext.Node(); |
|
176 node.ForceCheckShortTimerMode(); |
|
177 } |
|
178 |
|
179 DEFINE_SMELEMENT(TAwaitingOpenCloseRoute, NetStateMachine::MState, IpProtoCpr::TContext) |
|
180 TBool TAwaitingOpenCloseRoute::Accept() |
|
181 { |
|
182 return (iContext.iMessage.IsMessage<TCFIPProtoMessage::TOpenCloseRoute>()); |
|
183 } |
|
184 |
|
185 DEFINE_SMELEMENT(TDoOpenCloseRoute, NetStateMachine::MStateTransition, IpProtoCpr::TContext) |
|
186 void TDoOpenCloseRoute::DoL() |
|
187 { |
|
188 TCFIPProtoMessage::TOpenCloseRoute& msg = message_cast<TCFIPProtoMessage::TOpenCloseRoute>(iContext.iMessage); |
|
189 if (msg.iValue) |
|
190 iContext.Node().OpenRoute(); |
|
191 else |
|
192 iContext.Node().CloseRoute(); |
|
193 } |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 |
|
199 DEFINE_SMELEMENT(TLinkUp, NetStateMachine::MStateTransition, IpProtoCpr::TContext) |
|
200 void TLinkUp::DoL() |
|
201 { |
|
202 iContext.Node().LinkUp(); |
|
203 } |
|
204 |
|
205 DEFINE_SMELEMENT(TLinkDown, NetStateMachine::MStateTransition, IpProtoCpr::TContext) |
|
206 void TLinkDown::DoL() |
|
207 { |
|
208 iContext.Node().LinkDown(); |
|
209 } |
|
210 |
|
211 DEFINE_SMELEMENT(TStoreAndFilterDeprecatedAndForwardStateChange, NetStateMachine::MStateTransition, IpProtoCpr::TContext) |
|
212 void TStoreAndFilterDeprecatedAndForwardStateChange::DoL() |
|
213 { |
|
214 TCFMessage::TStateChange& msg = message_cast<TCFMessage::TStateChange>(iContext.iMessage); |
|
215 //Forward to control clients if there are any |
|
216 |
|
217 ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x TStateChange\tProgress: %d, Error: %d"), &iContext.Node(), msg.iStateChange.iStage, msg.iStateChange.iError) ); |
|
218 |
|
219 //We are the only node accessing this CLinkCprExtensionApi interface so we can do it safely here. |
|
220 //This is rather an exceptional situation, please keep the const_cast. |
|
221 const CLinkCprExtensionApi* linkCPR = static_cast<const CLinkCprExtensionApi*>(iContext.Node().AccessPointConfig().FindExtension(CLinkCprExtensionApi::TypeId())); |
|
222 const_cast<CLinkCprExtensionApi*>(linkCPR)->SetLastProgress(msg.iStateChange); |
|
223 |
|
224 if ((KLinkLayerOpen != msg.iStateChange.iStage) && (KLinkLayerClosed != msg.iStateChange.iStage) ) |
|
225 { |
|
226 //KLinkLayerOpen is now redundant with TCFControlClient::TGoneUp & TCFServiceProvider::TStarted |
|
227 //KLinkLayerClosed is now redundant with TCFControlClient::TGoneDown & TCFServiceProvider::TStopped |
|
228 //They have therefore been deprecated. Stack nodes are requested not to send the deprecated |
|
229 //signals anymore. If stack nodes do send the deprecated signals, the signals will be eaten here |
|
230 //because they confuse convergence and mobility layers, which may live just above. |
|
231 TInt ctrlClientCount = iContext.Node().PostToClients<TDefaultClientMatchPolicy>(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.iMessage, TClientType(TCFClientType::ECtrl)); |
|
232 if (0==ctrlClientCount) |
|
233 { //If there are no control clients any more, forward to the control provider |
|
234 iContext.Node().PostToClients<TDefaultClientMatchPolicy>(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.iMessage, TClientType(TCFClientType::ECtrlProvider)); |
|
235 } |
|
236 } |
|
237 } |
|
238 |
|
239 DEFINE_SMELEMENT(TSendStopToSelf, NetStateMachine::MStateTransition, TContext) |
|
240 void TSendStopToSelf::DoL() |
|
241 { |
|
242 iContext.iNodeActivity->PostRequestTo(iContext.NodeId(), |
|
243 TCFServiceProvider::TStop(iContext.iNodeActivity->Error()).CRef()); |
|
244 } |
|
245 |
|
246 |
|
247 DEFINE_SMELEMENT(TSendStarted, NetStateMachine::MStateTransition, TContext) |
|
248 void TSendStarted::DoL() |
|
249 { |
|
250 //Set the idle timers |
|
251 iContext.Node().EnableTimers(); |
|
252 iContext.Node().SetUsageProfile(KConnProfileMedium); |
|
253 iContext.Node().SetTimerMode(CIPProtoConnectionProvider::ETimerMedium); |
|
254 |
|
255 CoreNetStates::TSendStarted transition(iContext); |
|
256 transition.DoL(); |
|
257 } |
|
258 |
|
259 DEFINE_SMELEMENT(IpProtoCpr::TProcessDataClientStatusChange, NetStateMachine::MStateTransition, IpProtoCpr::TContext) |
|
260 void IpProtoCpr::TProcessDataClientStatusChange::DoL() |
|
261 { |
|
262 TCFControlProvider::TDataClientStatusChange& msg = message_cast<TCFControlProvider::TDataClientStatusChange>(iContext.iMessage); |
|
263 |
|
264 if(msg.iValue == TCFControlProvider::TDataClientStatusChange::EStarted) |
|
265 { |
|
266 iContext.iPeer->SetFlags(TCFClientType::EStarted); |
|
267 } |
|
268 else |
|
269 { |
|
270 iContext.iPeer->ClearFlags(TCFClientType::EStarted); |
|
271 } |
|
272 |
|
273 if(!msg.iValue && !iContext.Node().iSubConnEventDataSent) |
|
274 { // We're only interested in the provider being stopped. |
|
275 ADataMonitoringProtocolReq* dmInterface = NULL; |
|
276 iContext.Node().ReturnInterfacePtrL(dmInterface); |
|
277 |
|
278 ADataMonitoringProvider* dmProvider = static_cast<ADataMonitoringProvider*>(dmInterface); |
|
279 |
|
280 ASSERT(dmProvider); // Must always support this interface |
|
281 |
|
282 TCFMessage::TSubConnDataTransferred wholeConnMsg(KNifEMCompatibilityLayerEntireSubConnectionUid, dmProvider->DataVolumesPtr()->iSentBytes, dmProvider->DataVolumesPtr()->iReceivedBytes); |
|
283 TCFMessage::TSubConnDataTransferred defaultSubConnMsg(KNifEMCompatibilityLayerFakeSubConnectionId, dmProvider->DataVolumesPtr()->iSentBytes, dmProvider->DataVolumesPtr()->iReceivedBytes); |
|
284 |
|
285 RNodeInterface* ctrlClient = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl)); |
|
286 if(ctrlClient) |
|
287 { // Can't send this if the client's gone |
|
288 ctrlClient->PostMessage(iContext.NodeId(), wholeConnMsg); |
|
289 ctrlClient->PostMessage(iContext.NodeId(), defaultSubConnMsg); |
|
290 |
|
291 iContext.Node().iSubConnEventDataSent = ETrue; |
|
292 } |
|
293 } |
|
294 } |
|
295 |
|
296 DEFINE_SMELEMENT(TAwaitingIoctlMessage, NetStateMachine::MState, IpProtoCpr::TContext) |
|
297 TBool TAwaitingIoctlMessage::Accept() |
|
298 { |
|
299 if (iContext.iMessage.IsTypeOf(Meta::STypeId::CreateSTypeId(TCFSigLegacyRMessage2Ext::EUid, TCFSigLegacyRMessage2Ext::ETypeId))) |
|
300 { |
|
301 TCFSigLegacyRMessage2Ext& msg = static_cast<TCFSigLegacyRMessage2Ext&>(iContext.iMessage); |
|
302 if (msg.iMessage.Function() == ECNIoctl) |
|
303 { |
|
304 return ETrue; |
|
305 } |
|
306 } |
|
307 return EFalse; |
|
308 } |
|
309 |
|
310 DEFINE_SMELEMENT(TForwardToDefaultDataClient, NetStateMachine::MStateTransition, IpProtoCpr::TContext) |
|
311 void TForwardToDefaultDataClient::DoL() |
|
312 { |
|
313 ASSERT(iContext.iMessage.IsTypeOf(Meta::STypeId::CreateSTypeId(TCFSigLegacyRMessage2Ext::EUid, TCFSigLegacyRMessage2Ext::ETypeId))); |
|
314 |
|
315 RNodeInterface* dc = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData)); |
|
316 iContext.Activity()->PostRequestTo(*dc, iContext.iMessage); |
|
317 } |