|
1 /* |
|
2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: IKE socket connection |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "ikeconnection.h" |
|
20 #include "datatransfer.h" |
|
21 #include "localaddressresolver.h" |
|
22 #include "ikedebug.h" |
|
23 #include "ikesocketassert.h" |
|
24 |
|
25 // ======== MEMBER FUNCTIONS ======== |
|
26 |
|
27 // --------------------------------------------------------------------------- |
|
28 // Two-phased constructor. |
|
29 // --------------------------------------------------------------------------- |
|
30 // |
|
31 CIkeConnection* CIkeConnection::NewL( MIkeDebug& aDebug ) |
|
32 { |
|
33 CIkeConnection* self = new (ELeave) CIkeConnection( aDebug ); |
|
34 CleanupStack::PushL(self); |
|
35 self->ConstructL(); |
|
36 CleanupStack::Pop(self); |
|
37 return self; |
|
38 } |
|
39 |
|
40 // --------------------------------------------------------------------------- |
|
41 // Destructor. |
|
42 // --------------------------------------------------------------------------- |
|
43 // |
|
44 CIkeConnection::~CIkeConnection() |
|
45 { |
|
46 DEBUG_LOG1( _L("CIkeConnection::~CIkeConnection this=0x%x"), this ); |
|
47 |
|
48 if ( iDataTransfer ) |
|
49 { |
|
50 iDataTransfer->CloseSockets(); |
|
51 } |
|
52 |
|
53 DoCancelResolveFQDNAddress(); |
|
54 DoCancelStartConnection(); |
|
55 |
|
56 delete iLocalAddressResolver; |
|
57 delete iDataTransfer; |
|
58 delete iLinkObserver; |
|
59 |
|
60 iConnection.Close(); |
|
61 iSocketServer.Close(); |
|
62 } |
|
63 |
|
64 // --------------------------------------------------------------------------- |
|
65 // Constructor. |
|
66 // --------------------------------------------------------------------------- |
|
67 // |
|
68 CIkeConnection::CIkeConnection( MIkeDebug& aDebug ) |
|
69 : CIkeConnectionInterface( EPriorityStandard ), |
|
70 iState( EIdle ), |
|
71 iExtendedPrefs(), |
|
72 iDebug( aDebug ) |
|
73 { |
|
74 CActiveScheduler::Add( this ); // Added to the Active Scheduler |
|
75 } |
|
76 |
|
77 // --------------------------------------------------------------------------- |
|
78 // Second phase construction. |
|
79 // --------------------------------------------------------------------------- |
|
80 // |
|
81 void CIkeConnection::ConstructL() |
|
82 { |
|
83 DEBUG_LOG1( _L("CIkeConnection::ConstructL, this=0x%x"), this ); |
|
84 |
|
85 User::LeaveIfError( iSocketServer.Connect() ); |
|
86 iLocalAddressResolver = CLocalAddressResolver::NewL( iSocketServer, |
|
87 iConnection, |
|
88 iDebug ); |
|
89 iDataTransfer = CDataTransfer::NewL( iSocketServer, |
|
90 iConnection, |
|
91 *iLocalAddressResolver, |
|
92 *this, |
|
93 iDebug ); |
|
94 iLinkObserver = CConnObserver::NewL( iConnection, |
|
95 *this, |
|
96 iDebug ); |
|
97 } |
|
98 |
|
99 // --------------------------------------------------------------------------- |
|
100 // Opens data interface. |
|
101 // --------------------------------------------------------------------------- |
|
102 // |
|
103 MIkeDataInterface& CIkeConnection::OpenDataInterfaceL( const TIkeMajorVersion aIkeMajorVersion, |
|
104 const TIpVersion aIpVersion ) |
|
105 { |
|
106 IKESOCKET_ASSERT( aIpVersion == EIPv4 || aIpVersion == EIPv6 ); |
|
107 DEBUG_LOG2( _L("CIkeConnection::OpenDataInterfaceL, IKE version=%d, IP version=%d"), |
|
108 aIkeMajorVersion, aIpVersion ); |
|
109 |
|
110 // Store IP version. |
|
111 iIpVersion = aIpVersion; |
|
112 |
|
113 // Get local IP address. |
|
114 User::LeaveIfError( iLocalAddressResolver->RefreshLocalAddresses() ); |
|
115 TBool hasIPAddr = iLocalAddressResolver->HasIPAddr( aIpVersion ); |
|
116 if ( !hasIPAddr ) |
|
117 { |
|
118 User::Leave( KErrNotFound ); |
|
119 } |
|
120 TInetAddr localIp = iLocalAddressResolver->IPAddr( aIpVersion ); |
|
121 |
|
122 // Open sockets. |
|
123 User::LeaveIfError( iDataTransfer->OpenSockets( localIp ) ); |
|
124 |
|
125 // Set IKE major version. |
|
126 iDataTransfer->SetIkeMajorVersion( aIkeMajorVersion ); |
|
127 |
|
128 // Set IP version |
|
129 iDataTransfer->SetIpVersion( aIpVersion ); |
|
130 |
|
131 DEBUG_LOG( _L("Data interface open.") ); |
|
132 |
|
133 // Return data interface. |
|
134 return *iDataTransfer; |
|
135 } |
|
136 |
|
137 // --------------------------------------------------------------------------- |
|
138 // Starts connection. |
|
139 // --------------------------------------------------------------------------- |
|
140 // |
|
141 void CIkeConnection::StartConnection( const TUint32 aIapId, |
|
142 const TUint32 aSnapId, |
|
143 TRequestStatus& aStatus, |
|
144 const TBool aForcedRoaming ) |
|
145 { |
|
146 IKESOCKET_ASSERT( iState == EIdle ); |
|
147 IKESOCKET_ASSERT( iClientStatus == NULL ); |
|
148 |
|
149 DEBUG_LOG3( _L("CIkeConnection::StartConnection, IAP id=%d, SNAP id=%d, forced roaming=%d"), |
|
150 aIapId, aSnapId, aForcedRoaming ); |
|
151 |
|
152 iState = EConnecting; |
|
153 |
|
154 iClientStatus = &aStatus; |
|
155 *iClientStatus = KRequestPending; |
|
156 iIapId = aIapId; |
|
157 iSnapId = aSnapId; |
|
158 |
|
159 TInt err( iConnection.Open( iSocketServer ) ); |
|
160 |
|
161 if ( err == KErrNone ) |
|
162 { |
|
163 // Start connection. |
|
164 if ( iSnapId ) // SNAP |
|
165 { |
|
166 TRAP( err, CreateSnapPreferencesL( iSnapId, |
|
167 aForcedRoaming ) ); |
|
168 if ( err == KErrNone ) |
|
169 { |
|
170 iConnection.Start( iConnPrefList, iStatus ); |
|
171 } |
|
172 } |
|
173 else // IAP |
|
174 { |
|
175 // Create preference overrides. |
|
176 iPrefs.SetDialogPreference( ECommDbDialogPrefDoNotPrompt ); |
|
177 iPrefs.SetIapId( iIapId ); |
|
178 iConnection.Start( iPrefs, iStatus ); |
|
179 } |
|
180 } |
|
181 |
|
182 if ( err != KErrNone ) |
|
183 { |
|
184 TRequestStatus* ownStatus = &iStatus; |
|
185 *ownStatus = KRequestPending; |
|
186 SetActive(); |
|
187 |
|
188 User::RequestComplete( ownStatus, err ); |
|
189 return; |
|
190 } |
|
191 |
|
192 SetActive(); |
|
193 } |
|
194 |
|
195 // --------------------------------------------------------------------------- |
|
196 // Cancels connection starting. |
|
197 // --------------------------------------------------------------------------- |
|
198 // |
|
199 void CIkeConnection::CancelStartConnection() |
|
200 { |
|
201 DEBUG_LOG( _L("CIkeConnection::CancelStartConnection") ); |
|
202 |
|
203 DoCancelStartConnection(); |
|
204 } |
|
205 |
|
206 // --------------------------------------------------------------------------- |
|
207 // Stops connection. |
|
208 // --------------------------------------------------------------------------- |
|
209 // |
|
210 void CIkeConnection::StopConnection() |
|
211 { |
|
212 IKESOCKET_ASSERT( iLinkObserver ); |
|
213 IKESOCKET_ASSERT( iDataTransfer ); |
|
214 |
|
215 DEBUG_LOG( _L("CIkeConnection::StopConnection") ); |
|
216 |
|
217 iLinkObserver->CancelNotify(); |
|
218 |
|
219 CancelResolveFQDNAddress(); |
|
220 CancelStartConnection(); |
|
221 |
|
222 iDataTransfer->CloseSockets(); |
|
223 iConnection.Close(); |
|
224 |
|
225 iState = EIdle; |
|
226 } |
|
227 |
|
228 // --------------------------------------------------------------------------- |
|
229 // Resolves FQDN address. |
|
230 // --------------------------------------------------------------------------- |
|
231 // |
|
232 void CIkeConnection::ResolveFQDNAddress( const TDesC& aFQDN, |
|
233 TNameEntry& aNameEntry, |
|
234 TRequestStatus& aStatus ) |
|
235 { |
|
236 IKESOCKET_ASSERT( iState == EConnected ); |
|
237 DEBUG_LOG1( _L("CIkeConnection::ResolveAddress, aFQDN=%S"), &aFQDN ); |
|
238 |
|
239 iState = EResolvingFQDN; |
|
240 |
|
241 iClientStatus = &aStatus; |
|
242 *iClientStatus = KRequestPending; |
|
243 |
|
244 TInt err = iResolver.Open( iSocketServer, |
|
245 KAfInet, |
|
246 KProtocolInetUdp, |
|
247 iConnection ); |
|
248 |
|
249 if ( err ) |
|
250 { |
|
251 TRequestStatus* ownStatus = &iStatus; |
|
252 *ownStatus = KRequestPending; |
|
253 SetActive(); |
|
254 |
|
255 User::RequestComplete( ownStatus, err ); |
|
256 return; |
|
257 } |
|
258 |
|
259 iResolver.GetByName( aFQDN, aNameEntry, iStatus ); |
|
260 SetActive(); |
|
261 } |
|
262 |
|
263 // --------------------------------------------------------------------------- |
|
264 // Cancels FQDN address resolving. |
|
265 // --------------------------------------------------------------------------- |
|
266 // |
|
267 void CIkeConnection::CancelResolveFQDNAddress() |
|
268 { |
|
269 DEBUG_LOG( _L("CIkeConnection::CancelResolveFQDNAddress") ); |
|
270 |
|
271 DoCancelResolveFQDNAddress(); |
|
272 } |
|
273 |
|
274 // --------------------------------------------------------------------------- |
|
275 // Request notification about disconnection. |
|
276 // --------------------------------------------------------------------------- |
|
277 // |
|
278 void CIkeConnection::NotifyDisconnect( TRequestStatus& aStatus ) |
|
279 { |
|
280 IKESOCKET_ASSERT( iClientStatusNotifyDisconnect == NULL ); |
|
281 DEBUG_LOG( _L("CIkeConnection::NotifyDisconnect") ); |
|
282 |
|
283 iClientStatusNotifyDisconnect = &aStatus; |
|
284 *iClientStatusNotifyDisconnect = KRequestPending; |
|
285 } |
|
286 |
|
287 // --------------------------------------------------------------------------- |
|
288 // Cancels disconnect notification request. |
|
289 // --------------------------------------------------------------------------- |
|
290 // |
|
291 void CIkeConnection::CancelNotifyDisconnect() |
|
292 { |
|
293 IKESOCKET_ASSERT( iClientStatusNotifyDisconnect ); |
|
294 DEBUG_LOG( _L("CIkeConnection::CancelNotifyDisconnect") ); |
|
295 |
|
296 User::RequestComplete( iClientStatusNotifyDisconnect, KErrCancel ); |
|
297 iClientStatusNotifyDisconnect = NULL; |
|
298 } |
|
299 |
|
300 // --------------------------------------------------------------------------- |
|
301 // Returns IAP id. |
|
302 // --------------------------------------------------------------------------- |
|
303 // |
|
304 TUint32 CIkeConnection::IapId() const |
|
305 { |
|
306 return iIapId; |
|
307 } |
|
308 |
|
309 // --------------------------------------------------------------------------- |
|
310 // Returns Net id. |
|
311 // --------------------------------------------------------------------------- |
|
312 // |
|
313 TUint32 CIkeConnection::NetId() const |
|
314 { |
|
315 return iNetId; |
|
316 } |
|
317 |
|
318 // --------------------------------------------------------------------------- |
|
319 // Returns SNAP id. |
|
320 // --------------------------------------------------------------------------- |
|
321 // |
|
322 TUint32 CIkeConnection::SnapId() const |
|
323 { |
|
324 return iSnapId; |
|
325 } |
|
326 |
|
327 // --------------------------------------------------------------------------- |
|
328 // Gets local IP address. |
|
329 // --------------------------------------------------------------------------- |
|
330 // |
|
331 TInt CIkeConnection::GetLocalAddress( const TIpVersion aIpVersion, |
|
332 TInetAddr& aLocalIp ) |
|
333 { |
|
334 IKESOCKET_ASSERT( aIpVersion == EIPv4 || aIpVersion == EIPv6 ); |
|
335 return iLocalAddressResolver->GetLocalAddress( aIpVersion, aLocalIp ); |
|
336 } |
|
337 |
|
338 // --------------------------------------------------------------------------- |
|
339 // Creates connection preferences for SNAP usage. Connection preferences |
|
340 // list is constructed. |
|
341 // --------------------------------------------------------------------------- |
|
342 // |
|
343 void CIkeConnection::CreateSnapPreferencesL( const TUint32 aSnapId, |
|
344 const TBool aForcedRoaming ) |
|
345 { |
|
346 CleanSnapPreferences(); |
|
347 |
|
348 iExtendedPrefs.SetSnapId( aSnapId ); |
|
349 iExtendedPrefs.SetForcedRoaming( aForcedRoaming ); |
|
350 |
|
351 iConnPrefList.AppendL( &iExtendedPrefs ); |
|
352 } |
|
353 |
|
354 // --------------------------------------------------------------------------- |
|
355 // Cleans connection preferences created for SNAP usage. |
|
356 // --------------------------------------------------------------------------- |
|
357 // |
|
358 void CIkeConnection::CleanSnapPreferences() |
|
359 { |
|
360 while( iConnPrefList.Count() > 0 ) |
|
361 { |
|
362 iConnPrefList.Remove( 0 ); |
|
363 } |
|
364 } |
|
365 |
|
366 // --------------------------------------------------------------------------- |
|
367 // Updates IAP id and NET id. |
|
368 // --------------------------------------------------------------------------- |
|
369 // |
|
370 void CIkeConnection::UpdateRealIapData() |
|
371 { |
|
372 _LIT( KIapId, "IAP\\Id" ); |
|
373 _LIT( KNetId, "IAP\\IAPNetwork" ); |
|
374 |
|
375 iConnection.GetIntSetting( KIapId, iIapId ); |
|
376 iConnection.GetIntSetting( KNetId, iNetId ); |
|
377 |
|
378 DEBUG_LOG2( _L("CIkeConnection::UpdateRealIapData, IAP id=%d, NET id=%d"), |
|
379 iIapId, iNetId ); |
|
380 } |
|
381 |
|
382 // --------------------------------------------------------------------------- |
|
383 // Handles completion of asynchronous request in EConnecting state. |
|
384 // --------------------------------------------------------------------------- |
|
385 // |
|
386 void CIkeConnection::DoStateAfterConnecting() |
|
387 { |
|
388 IKESOCKET_ASSERT( iLinkObserver ); |
|
389 IKESOCKET_ASSERT( iState == EConnecting ); |
|
390 |
|
391 CleanSnapPreferences(); |
|
392 |
|
393 TInt err( iStatus.Int() ); |
|
394 |
|
395 if ( err == KErrNone ) |
|
396 { |
|
397 // Update IAP and Net ids. |
|
398 UpdateRealIapData(); |
|
399 |
|
400 // Start observing when link is disconnected. |
|
401 iLinkObserver->NotifyDisconnect(); |
|
402 |
|
403 iState = EConnected; |
|
404 } |
|
405 else |
|
406 { |
|
407 iConnection.Close(); |
|
408 iState = EIdle; |
|
409 } |
|
410 |
|
411 User::RequestComplete( iClientStatus, err ); |
|
412 iClientStatus = NULL; |
|
413 } |
|
414 |
|
415 // --------------------------------------------------------------------------- |
|
416 // Handles completion of asynchronous request in EResolvingFQDN state. |
|
417 // --------------------------------------------------------------------------- |
|
418 // |
|
419 void CIkeConnection::DoStateAfterResolvingFQDN() |
|
420 { |
|
421 IKESOCKET_ASSERT( iState == EResolvingFQDN ); |
|
422 |
|
423 // Back to connected state. |
|
424 iState = EConnected; |
|
425 iResolver.Close(); |
|
426 |
|
427 User::RequestComplete( iClientStatus, iStatus.Int() ); |
|
428 iClientStatus = NULL; |
|
429 } |
|
430 |
|
431 // --------------------------------------------------------------------------- |
|
432 // Implements cancellation of connection starting. |
|
433 // --------------------------------------------------------------------------- |
|
434 // |
|
435 void CIkeConnection::DoCancelStartConnection() |
|
436 { |
|
437 if ( iState == EConnecting ) |
|
438 { |
|
439 IKESOCKET_ASSERT( iClientStatus ); |
|
440 |
|
441 Cancel(); |
|
442 |
|
443 iState = EIdle; |
|
444 iConnection.Close(); |
|
445 |
|
446 CleanSnapPreferences(); |
|
447 |
|
448 User::RequestComplete( iClientStatus, KErrCancel ); |
|
449 iClientStatus = NULL; |
|
450 } |
|
451 } |
|
452 |
|
453 // --------------------------------------------------------------------------- |
|
454 // Implements cancellation of FQDN address resolving. |
|
455 // --------------------------------------------------------------------------- |
|
456 // |
|
457 void CIkeConnection::DoCancelResolveFQDNAddress() |
|
458 { |
|
459 if ( iState == EResolvingFQDN ) |
|
460 { |
|
461 IKESOCKET_ASSERT( iClientStatus ); |
|
462 |
|
463 Cancel(); |
|
464 |
|
465 iState = EConnected; |
|
466 iResolver.Close(); |
|
467 |
|
468 User::RequestComplete( iClientStatus, KErrCancel ); |
|
469 iClientStatus = NULL; |
|
470 } |
|
471 } |
|
472 |
|
473 // --------------------------------------------------------------------------- |
|
474 // From CActive |
|
475 // Handles request completion event about asynchronous connection starting or |
|
476 // FQDN address resolving. |
|
477 // --------------------------------------------------------------------------- |
|
478 // |
|
479 void CIkeConnection::RunL() |
|
480 { |
|
481 DEBUG_LOG2( _L("CIkeConnection::RunL, iState=%d, iStatus=%d"), |
|
482 iState, iStatus.Int() ); |
|
483 |
|
484 switch ( iState ) |
|
485 { |
|
486 case EConnecting: |
|
487 DoStateAfterConnecting(); |
|
488 break; |
|
489 case EResolvingFQDN: |
|
490 DoStateAfterResolvingFQDN(); |
|
491 break; |
|
492 default: |
|
493 IKESOCKET_ASSERT( EFalse ); |
|
494 break; |
|
495 } |
|
496 } |
|
497 |
|
498 // --------------------------------------------------------------------------- |
|
499 // From CActive |
|
500 // Implements cancellation of asynchronous connection starting or FQDN address |
|
501 // resolving. |
|
502 // --------------------------------------------------------------------------- |
|
503 // |
|
504 void CIkeConnection::DoCancel() |
|
505 { |
|
506 DEBUG_LOG1( _L("CIkeConnection::DoCancel, iState=%d"), |
|
507 iState ); |
|
508 |
|
509 switch ( iState ) |
|
510 { |
|
511 case EConnecting: |
|
512 iConnection.Stop(); |
|
513 break; |
|
514 case EResolvingFQDN: |
|
515 iResolver.Cancel(); |
|
516 break; |
|
517 default: |
|
518 IKESOCKET_ASSERT( EFalse ); |
|
519 break; |
|
520 } |
|
521 } |
|
522 |
|
523 // --------------------------------------------------------------------------- |
|
524 // Handles notifcation about fatal data transfer error. |
|
525 // --------------------------------------------------------------------------- |
|
526 // |
|
527 void CIkeConnection::DataTransferError( const TInt aError, |
|
528 const TErrorType /*aErrorType*/ ) |
|
529 { |
|
530 DEBUG_LOG1( _L("CIkeConnection::DataTransferError, aError=%d"), |
|
531 aError ); |
|
532 |
|
533 // Disconnect link and notify client about disconnection. |
|
534 LinkDisconnected( aError ); |
|
535 } |
|
536 |
|
537 // --------------------------------------------------------------------------- |
|
538 // Handles notifcation about link disconnection. |
|
539 // --------------------------------------------------------------------------- |
|
540 // |
|
541 void CIkeConnection::LinkDisconnected( const TInt aStatus ) |
|
542 { |
|
543 // Stop connection. |
|
544 StopConnection(); |
|
545 |
|
546 if ( iClientStatusNotifyDisconnect ) |
|
547 { |
|
548 User::RequestComplete( iClientStatusNotifyDisconnect, aStatus ); |
|
549 iClientStatusNotifyDisconnect = NULL; |
|
550 } |
|
551 } |