1 // Copyright (c) 2004-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 // Implementation file for the IP SubConnection Provider |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 */ |
|
21 |
|
22 #include <e32std.h> |
|
23 #include <e32test.h> |
|
24 #include <ss_glob.h> |
|
25 #include "deft_scpr.h" |
|
26 #include "ipscprlog.h" |
|
27 #ifdef SYMBIAN_NETWORKING_UMTSR5 |
|
28 #include "MAppIdInfo.h" |
|
29 #include <networking/qos3gpp_subconparams.h> |
|
30 #include <ip_subconparams.h> |
|
31 #endif //SYMBIAN_NETWORKING_UMTSR5 |
|
32 |
|
33 #ifdef SYMBIAN_NETWORKING_UMTSR5 |
|
34 const TUint32 KSIPSecureId = 270490934; |
|
35 const TUint32 KDHCPSecureId = 270522821; |
|
36 const TUint32 KDNSSecureId = 268437634; |
|
37 #endif //SYMBIAN_NETWORKING_UMTSR5 |
|
38 |
|
39 CEmptySubConnectionProvider::~CEmptySubConnectionProvider() |
|
40 { |
|
41 __IPCPRLOG(IpCprLog::Printf(_L("~CEmptySubConnectionProvider [this=%08x]"), this)); |
|
42 if (iConnectionProvider) |
|
43 { |
|
44 iConnectionProvider->Leave(*this); |
|
45 } |
|
46 } |
|
47 |
|
48 void CEmptySubConnectionProvider::DoControlClientJoiningL(MSubConnectionControlClient& aControlClient) |
|
49 { |
|
50 (void)aControlClient; |
|
51 __IPCPRLOG(IpCprLog::Printf(_L("CEmptySubConnectionProvider [this=%08x]:\tDoControlClientJoiningL() [iControlClients.Count=%d] [aControlClient=%08x]"), this, iControlClients.Count(), &aControlClient)); |
|
52 } |
|
53 |
|
54 void CEmptySubConnectionProvider::DoControlClientLeaving(MSubConnectionControlClient& aControlClient) |
|
55 { |
|
56 (void)aControlClient; |
|
57 __IPCPRLOG(IpCprLog::Printf(_L("CEmptySubConnectionProvider [this=%08x]:\tDoControlClientLeaving() [iControlClients.Count=%d] [aControlClient=%08x]"), this, iControlClients.Count(), &aControlClient)); |
|
58 } |
|
59 |
|
60 void CEmptySubConnectionProvider::EnumerateClientsL(TUint& aCount, TDes8& aDes, CConnectionProviderBase::TEnumClients aClientType) |
|
61 { |
|
62 STypeId tid = STypeId::CreateSTypeId(KConnectionClientExtUid,EConnectionClientDesc); |
|
63 TInt max = iControlClients.Count(); |
|
64 for ( TInt n = 0; n < max; n++ ) |
|
65 { |
|
66 MConnectionClientDesc* intf = reinterpret_cast<MConnectionClientDesc*>(iControlClients[n]->FetchInterfaceInstanceL(*this,tid)); |
|
67 if ( intf ) |
|
68 { |
|
69 TConnectionProcessInfo cinfo; |
|
70 cinfo.GetInfoL(aClientType,aCount, *intf, aDes); |
|
71 } |
|
72 } |
|
73 STypeId tid2 = STypeId::CreateSTypeId(KConnectionClientExtUid,EConnectionEnumerateClients); |
|
74 max = iDataClients.Count(); |
|
75 for ( TInt n = 0; n < max; n++ ) |
|
76 { |
|
77 MConnectionEnumerateClients* intf = reinterpret_cast<MConnectionEnumerateClients*>(iDataClients[n]->FetchInterfaceInstanceL(*this,tid2)); |
|
78 if ( intf ) |
|
79 { |
|
80 intf->EnumerateClientsL(aCount,aDes,aClientType); |
|
81 } |
|
82 } |
|
83 } |
|
84 |
|
85 void CEmptySubConnectionProvider::ConnectionError(TInt /*aStage*/, TInt aError) |
|
86 {//it's comming from connection at the same level so forward it sideways |
|
87 //with an origin EConnection |
|
88 TInt max = iDataClients.Count(); |
|
89 for ( TInt n = max - 1; n >= 0; n-- ) |
|
90 { |
|
91 iDataClients[n]->SubConnectionError(*this, MSubConnectionDataClient::EConnection, aError); |
|
92 } |
|
93 } |
|
94 |
|
95 MConnectionDataClient* CEmptySubConnectionProvider::DoSelfConnectionDataClient() |
|
96 { |
|
97 return this; |
|
98 } |
|
99 |
|
100 |
|
101 // Methods to be overriden be derived subconnection provider |
|
102 void CDefaultSubConnectionProvider::DoControlClientJoiningL(MSubConnectionControlClient& aControlClient) |
|
103 { |
|
104 (void)aControlClient; |
|
105 __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider::DoControlClientJoiningL [this=%08x]"), this)); |
|
106 if (NULL != NextLayer()) |
|
107 { |
|
108 __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP exists - joined with provider"))); |
|
109 } |
|
110 else |
|
111 { |
|
112 __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP doesn't exists - not joined"))); |
|
113 } |
|
114 |
|
115 } |
|
116 |
|
117 void CDefaultSubConnectionProvider::DoDataClientJoiningL(MSubConnectionDataClient& aDataClient) |
|
118 { |
|
119 #ifdef SYMBIAN_NETWORKING_UMTSR5 |
|
120 // This piece of code is being added as per the requirements of PREQ 635 of dedicated PDP signalling |
|
121 // context. When Primary PDP Context is created Network will return back the code saying whether it |
|
122 // accepts the request to be dedicated signalling context or not. If Network decided to allow for dedicated |
|
123 // signalling context then UmtsGprs SCPR add the information into the iParameterBundle of the UmtsGprsScpr |
|
124 |
|
125 // However, if the User doesnt do RSubConnection::SetParamter(EAttachDefault), which actually the user shouldn't do |
|
126 // then we have to Get the parameter from the Next Layer, which again might or might not be UmtsGprs SubConnection Provider. |
|
127 // Nevertheless if we call SetParameter() on iNextLayer then SetParameters across all the Layers below will get called, and |
|
128 // since I knew that if any of the layer below is UmtsGprsSCpr, it will update the IMCN Signalling flag in the |
|
129 // parameter Bundle which I will pass with the SetParameter() |
|
130 |
|
131 // We Initialize this variable everytime so that it can it can point to proper next layer |
|
132 // everytime. Just a safety measure because it will anyway be initialised by the code written |
|
133 // below |
|
134 iSubConNextLayer = NULL; |
|
135 if (NULL == iNextLayer) |
|
136 { |
|
137 // Find the Next Layer , otherwise iSubConNextLayer will be NULL by default. |
|
138 CConnectionProviderBase* lowerConnectionProvider = iConnectionProvider->NextLayer(); |
|
139 if (lowerConnectionProvider) |
|
140 { |
|
141 TUint nextLayerFactoryId = lowerConnectionProvider->CanDoSubConnection(RSubConnection::EAttachToDefault); |
|
142 if (nextLayerFactoryId != 0) |
|
143 { |
|
144 TSockManData* sockManData = SockManGlobals::Get(); |
|
145 CSubConnectionFactoryContainer* subConnectionFactories = sockManData->iSubConnectionFactories; |
|
146 XSubConnectionFactoryQuery query(lowerConnectionProvider, RSubConnection::EAttachToDefault); |
|
147 iSubConNextLayer = subConnectionFactories->FindOrCreateProviderL(nextLayerFactoryId, query); |
|
148 } |
|
149 |
|
150 } |
|
151 } |
|
152 else |
|
153 { |
|
154 // We have a NextLayer, Point iSubConNextLayer to the same |
|
155 iSubConNextLayer = iNextLayer; |
|
156 } |
|
157 |
|
158 // Get The parameter Bundle for this SubConnectionProvider Instance. if Not available create one |
|
159 // and Get the parameters from the Next Lyer |
|
160 CSubConParameterBundle *tempBundle = NULL; |
|
161 if (iSubConNextLayer != NULL) |
|
162 { |
|
163 tempBundle = iParameterBundle != NULL? iParameterBundle :CSubConParameterBundle::NewL(); |
|
164 TRAP_IGNORE(iSubConNextLayer->SetParametersL(*tempBundle)); |
|
165 } |
|
166 |
|
167 // Get the family if Available |
|
168 CSubConParameterFamily *imcnFamily = tempBundle != NULL ? tempBundle->FindFamily(KSubConnContextDescrParamsFamily) : NULL; |
|
169 if (imcnFamily) |
|
170 { |
|
171 // Find the family, Look for the IMCN value, using CSubConImsExtParamSet defined in Qos3gpp |
|
172 CSubConImsExtParamSet *imcnSigParams = static_cast<CSubConImsExtParamSet*> |
|
173 (imcnFamily->FindExtensionSet(STypeId::CreateSTypeId(KSubConIPParamsUid,KSubConImsExtParamsType), |
|
174 CSubConParameterFamily::EGranted)); |
|
175 // If Family contains IMCN Signalling Parameters |
|
176 if (imcnSigParams&& imcnSigParams->GetImsSignallingIndicator()) |
|
177 { |
|
178 // Check and Delete |
|
179 if (tempBundle != iParameterBundle) |
|
180 { |
|
181 tempBundle->Close(); |
|
182 tempBundle=NULL; |
|
183 } |
|
184 // Fetch the interface from the connection provider |
|
185 STypeId typeID = STypeId::CreateSTypeId(KConnectionAppInfoInterfaceId,0); // IP Conenction provider factory Uid |
|
186 TAny* intf = iConnectionProvider->FetchInterfaceInstanceL(typeID); |
|
187 if (!intf) |
|
188 { |
|
189 // We are not able to get the AppSId so leaving |
|
190 User::Leave(KErrNotSupported); |
|
191 } |
|
192 MConnectionAppIdInfo *appIdIP = static_cast<MConnectionAppIdInfo*>(intf); |
|
193 TUint32 appSecureId = appIdIP->GetAppSecureId(); |
|
194 |
|
195 // if socket is being opened by any application other than SIP, DHCP, and DNS we need to |
|
196 // restrict the socket from being Created. |
|
197 |
|
198 |
|
199 if ( ( appSecureId==KSIPSecureId || iAppId == KSIPSecureId) || |
|
200 (appSecureId==KDHCPSecureId || iAppId == KDHCPSecureId) || |
|
201 (appSecureId==KDNSSecureId || iAppId == KDNSSecureId) ) |
|
202 { |
|
203 aDataClient.JoinComplete(*this); |
|
204 } |
|
205 else |
|
206 { |
|
207 User::Leave(KErrPermissionDenied); |
|
208 } |
|
209 } // if (imcnSigParams&& imcnSigParams->GetImsSignallingIndicator()) |
|
210 else |
|
211 { |
|
212 if (iConnectionProvider->IsLayerUp()) |
|
213 { |
|
214 aDataClient.JoinComplete(*this); |
|
215 } |
|
216 |
|
217 } |
|
218 } // if (imcnFamily) |
|
219 // Check and Delete |
|
220 if (tempBundle != iParameterBundle && tempBundle!=NULL) |
|
221 { |
|
222 tempBundle->Close(); |
|
223 } |
|
224 #else |
|
225 |
|
226 if (iConnectionProvider->IsLayerUp()) |
|
227 { |
|
228 aDataClient.JoinComplete(*this); |
|
229 } |
|
230 #endif // #ifdef SYMBIAN_NETWORKING_UMTSR5 |
|
231 |
|
232 } |
|
233 |
|
234 void CDefaultSubConnectionProvider::DoDataClientLeaving(MSubConnectionDataClient& aDataClient) |
|
235 { |
|
236 aDataClient.LeaveComplete(*this); |
|
237 } |
|
238 |
|
239 void CDefaultSubConnectionProvider::DoSourceAddressUpdate(MSubConnectionDataClient& /*aDataClient*/, const TSockAddr& /*aSource*/) |
|
240 { |
|
241 } |
|
242 |
|
243 void CDefaultSubConnectionProvider::DoDestinationAddressUpdate(MSubConnectionDataClient& /*aDataClient*/, const TSockAddr& /*aDestination*/) |
|
244 { |
|
245 } |
|
246 |
|
247 void CDefaultSubConnectionProvider::DoDataClientRouted(MSubConnectionDataClient& /*aDataClient*/, const TSockAddr& /*aSource*/, const TSockAddr& /*aDestination*/, const TDesC8& /*aConnectionInfo*/) |
|
248 { |
|
249 } |
|
250 |
|
251 #ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS |
|
252 void CDefaultSubConnectionProvider::DoParametersAboutToBeSetL(CSubConParameterBundle& aParameterBundle) |
|
253 { |
|
254 __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider::DoParametersAboutToBeSetL [this=%08x]"), this)); |
|
255 if (NULL != NextLayer()) |
|
256 { |
|
257 __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP exists - forwarding the request"))); |
|
258 iNextLayer->SetParametersL(aParameterBundle); |
|
259 } |
|
260 else |
|
261 { |
|
262 __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP doesn't exists - the request not supported"))); |
|
263 User::Leave(KErrNotSupported); |
|
264 } |
|
265 } |
|
266 |
|
267 #else |
|
268 void CDefaultSubConnectionProvider::DoParametersAboutToBeSetL(CSubConParameterBundle& /*)aParameterBundle*/) |
|
269 {//this could potentially fetch a current parameters from GuQoS and return them back as granted ones |
|
270 User::Leave(KErrNotSupported); |
|
271 } |
|
272 #endif |
|
273 |
|
274 #ifdef SYMBIAN_NETWORKING_UMTSR5 |
|
275 TInt CDefaultSubConnectionProvider::DoControl(TUint aOptionLevel, TUint /*aOptionName*/, TDes8& /*aOption*/) |
|
276 #else |
|
277 TInt CDefaultSubConnectionProvider::DoControl(TUint /*aOptionLevel*/, TUint /*aOptionName*/, TDes8& /*aOption*/) |
|
278 #endif //#ifdef SYMBIAN_NETWORKING_UMTSR5 |
|
279 { |
|
280 #ifdef SYMBIAN_NETWORKING_UMTSR5 |
|
281 //This control is used to send application secure ID of Active Connection. This Id |
|
282 //will be used to for adding socket as data client to the subconnection. |
|
283 iAppId=aOptionLevel; |
|
284 return KErrNone; |
|
285 #else |
|
286 return KErrNotSupported; |
|
287 #endif //#ifdef SYMBIAN_NETWORKING_UMTSR5 |
|
288 } |
|
289 |
|
290 void CDefaultSubConnectionProvider::DoStartL() |
|
291 { |
|
292 __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider::DoStartL [this=%08x]"), this)); |
|
293 } |
|
294 |
|
295 void CDefaultSubConnectionProvider::DoStop() |
|
296 { |
|
297 __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider::DoStop [this=%08x]"), this)); |
|
298 #ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS |
|
299 if (iNextLayer) |
|
300 { |
|
301 __IPCPRLOG(IpCprLog::Printf(_L("Leaving Lower subconnection provider"))); |
|
302 iNextLayer->Leave(*this); |
|
303 iNextLayer = NULL; |
|
304 } |
|
305 #endif |
|
306 } |
|
307 |
|
308 CSubConnectionProviderBase* CDefaultSubConnectionProvider::DoNextLayer() |
|
309 { |
|
310 #ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS |
|
311 __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider [this=%08x]:\tDoNextLayer()"), this)); |
|
312 if (NULL == iNextLayer) |
|
313 { |
|
314 CConnectionProviderBase* lowerConnectionProvider = iConnectionProvider->NextLayer(); |
|
315 if (!lowerConnectionProvider) |
|
316 { |
|
317 //This could denote the connection isn't started and perhaps should be from here, |
|
318 // but since the selection isn't separated from startup, we don't have enough |
|
319 // information to do it here. |
|
320 __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider [this=%08x]:\tDoNextLayer() Connection Provider is missing its NextLayer"), this)); |
|
321 return NULL; // No Lower layer,so leaving rhostresolver without connection. |
|
322 } |
|
323 |
|
324 TUint nextLayerFactoryId = lowerConnectionProvider->CanDoSubConnection(RSubConnection::EAttachToDefault); |
|
325 TRAP_IGNORE( |
|
326 |
|
327 if (nextLayerFactoryId != 0) |
|
328 { |
|
329 //'This' not started yet. The lower layer unknown |
|
330 //This is as much as we can delay with resolving the subconnection stack |
|
331 TSockManData* sockManData = SockManGlobals::Get(); |
|
332 CSubConnectionFactoryContainer* subConnectionFactories = sockManData->iSubConnectionFactories; |
|
333 |
|
334 XSubConnectionFactoryQuery query(lowerConnectionProvider, RSubConnection::EAttachToDefault); |
|
335 iNextLayer = subConnectionFactories->FindOrCreateProviderL(nextLayerFactoryId, query); |
|
336 } |
|
337 |
|
338 if (iNextLayer) |
|
339 { |
|
340 __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP found.. Joining"))); |
|
341 iNextLayer->JoinL(*this); |
|
342 } |
|
343 else |
|
344 { |
|
345 __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP not found.. Continuing"))); |
|
346 } |
|
347 ); |
|
348 |
|
349 } |
|
350 |
|
351 return iNextLayer; |
|
352 |
|
353 #else |
|
354 __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP not supported"))); |
|
355 return NULL; |
|
356 #endif |
|
357 //SYMBIAN_NETWORKING_3GPPDEFAULTQOS |
|
358 } |
|
359 |
|
360 CConnDataTransfer& CDefaultSubConnectionProvider::DoDataTransferL() |
|
361 { |
|
362 User::Leave(KErrNotSupported); |
|
363 //unreachable code |
|
364 return iNextLayer->DataTransferL(); |
|
365 } |
|
366 |
|
367 //MConnectionDataClient |
|
368 TAny* CDefaultSubConnectionProvider::FetchInterfaceInstanceL(CConnectionProviderBase& /*aProvider*/, const STypeId& aTid) |
|
369 { |
|
370 return (aTid == STypeId::CreateSTypeId(KConnectionClientExtUid,EConnectionEnumerateClients)) ? static_cast<MConnectionEnumerateClients*>(this) : NULL; |
|
371 } |
|
372 |
|
373 void CDefaultSubConnectionProvider::ConnectionGoingDown(CConnectionProviderBase& /*aConnProvider*/) |
|
374 { |
|
375 __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider [this=%08x]:\tConnectionGoingDown()"), this)); |
|
376 iConnectionProvider = NULL; |
|
377 DeleteMeNow(); |
|
378 } |
|
379 |
|
380 void CDefaultSubConnectionProvider::Notify(MConnectionDataClient::TNotify aNotifyType, CConnectionProviderBase* /*aConnProvider*/, TInt aError, const CConNotificationEvent* /*aConNotificationEvent*/) |
|
381 { |
|
382 int count = iControlClients.Count(); |
|
383 for (int i = count - 1; i >= 0; --i) |
|
384 { |
|
385 iControlClients[i]->SubConnectionEvent(*this, aNotifyType, aError, NULL); |
|
386 } |
|
387 if (aNotifyType == ENotifyLayerUp) |
|
388 {//complete outstanding data client joins |
|
389 TInt max = iDataClients.Count(); |
|
390 for ( TInt n = max - 1; n >= 0; n-- ) |
|
391 { |
|
392 if (aError == KErrNone) |
|
393 { |
|
394 iDataClients[n]->JoinComplete(*this); |
|
395 } |
|
396 else |
|
397 { |
|
398 iDataClients[n]->JoinFailed(*this,aError); |
|
399 } |
|
400 } |
|
401 } |
|
402 } |
|
403 |
|
404 void CDefaultSubConnectionProvider::AttachToNext(CSubConnectionProviderBase* /*aSubConnProvider*/) |
|
405 { |
|
406 } |
|
407 |
|
408 CDefaultSubConnectionProvider::~CDefaultSubConnectionProvider () |
|
409 { |
|
410 __IPCPRLOG(IpCprLog::Printf(_L("~CDefaultSubConnectionProvider [this=%08x]"), this)); |
|
411 #ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS |
|
412 if (iNextLayer) |
|
413 { |
|
414 iNextLayer->Leave (*this); |
|
415 } |
|
416 #endif |
|
417 } |
|
418 |
|
419 |
|
420 #ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS |
|
421 void CDefaultSubConnectionProvider::DoControlClientLeaving(MSubConnectionControlClient& aControlClient) |
|
422 { |
|
423 (void)aControlClient; |
|
424 __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider [this=%08x]:\tDoControlClientLeaving() [iControlClients.Count=%d] [aControlClient=%08x]"), this, iControlClients.Count(), &aControlClient)); |
|
425 |
|
426 // Note: control client count == 1 because the the client has not been removed yet |
|
427 if (iNextLayer && iControlClients.Count() == 1 && iDataClients.Count() == 0) |
|
428 { |
|
429 iNextLayer->Leave (*this); |
|
430 iNextLayer = NULL; |
|
431 } |
|
432 } |
|
433 |
|
434 void CDefaultSubConnectionProvider::SubConnectionEvent(CSubConnectionProviderBase& /*aSubConnProvider*/, MConnectionDataClient::TNotify /*aNotifyType*/, TInt /*aError*/, const CSubConNotificationEvent* aEvent) |
|
435 { |
|
436 NotifyClientEvent(*aEvent); |
|
437 } |
|
438 |
|
439 |
|
440 void CDefaultSubConnectionProvider::SubConnectionGoingDown(CSubConnectionProviderBase& /*aSubConnProvider*/) |
|
441 { |
|
442 TInt max = iControlClients.Count(); |
|
443 for ( TInt n = max - 1; n >= 0; n-- ) |
|
444 { |
|
445 iControlClients[n]->SubConnectionGoingDown(*this); |
|
446 } |
|
447 } |
|
448 |
|
449 |
|
450 void CDefaultSubConnectionProvider::LayerUp(CSubConnectionProviderBase& /*aSubConnProvider*/, TInt /*aError*/) |
|
451 { |
|
452 } |
|
453 |
|
454 void CDefaultSubConnectionProvider::IncomingConnection(CSubConnectionProviderBase* /*aSubConnProvider*/, CSubConParameterBundle* /*aParameterBundle*/, TInt /*aError*/) |
|
455 { |
|
456 } |
|
457 |
|
458 #endif |
|
459 // SYMBIAN_NETWORKING_3GPPDEFAULTQOS |
|
460 |
|