|
1 /* |
|
2 * Copyright (c) 2008 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: Server side session of KMDServer |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "ikedebug.h" |
|
20 #include "ikepolparser.h" |
|
21 #include "kmdserver.h" |
|
22 #include "kmdapi.h" |
|
23 #include "kmdserver.pan" |
|
24 |
|
25 // CLASS HEADER |
|
26 #include "kmdsession.h" |
|
27 |
|
28 // ======== MEMBER FUNCTIONS ======== |
|
29 |
|
30 // --------------------------------------------------------------------------- |
|
31 // Two-phased constructor. |
|
32 // --------------------------------------------------------------------------- |
|
33 // |
|
34 CKmdSession* CKmdSession::NewL( CKmdServer& aServer, |
|
35 MIkeDebug& aDebug ) |
|
36 { |
|
37 CKmdSession* self = new ( ELeave ) CKmdSession( aServer, aDebug ); |
|
38 return self; |
|
39 } |
|
40 |
|
41 // --------------------------------------------------------------------------- |
|
42 // Destructor. |
|
43 // --------------------------------------------------------------------------- |
|
44 // |
|
45 CKmdSession::~CKmdSession() |
|
46 { |
|
47 DEBUG_LOG( _L("CKmdSession::~CKmdSession") ); |
|
48 |
|
49 DoCancelStartConnection(); |
|
50 DoCancelActivate(); |
|
51 DoCancelResolveAddress(); |
|
52 |
|
53 iServer.KmdSessionClosed(); |
|
54 } |
|
55 |
|
56 // --------------------------------------------------------------------------- |
|
57 // Constructor. |
|
58 // --------------------------------------------------------------------------- |
|
59 // |
|
60 CKmdSession::CKmdSession( CKmdServer& aServer, |
|
61 MIkeDebug& aDebug ) |
|
62 : iServer( aServer ), |
|
63 iDebug( aDebug ) |
|
64 { |
|
65 DEBUG_LOG( _L("CKmdSession::CKmdSession") ); |
|
66 } |
|
67 |
|
68 // --------------------------------------------------------------------------- |
|
69 // From class CSession2. |
|
70 // Handles the servicing of a client request from KMD API. |
|
71 // --------------------------------------------------------------------------- |
|
72 // |
|
73 void CKmdSession::ServiceL( const RMessage2& aMessage ) |
|
74 { |
|
75 switch ( aMessage.Function() ) |
|
76 { |
|
77 case CKmdServer::KKmdStartConnection: |
|
78 { |
|
79 DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdStartConnection")); |
|
80 |
|
81 if ( iConnectionStarter != NULL ) |
|
82 { |
|
83 aMessage.Panic( KKmdPanicCategory, |
|
84 EKmdPanicRequestAlreadyPending ); |
|
85 } |
|
86 else |
|
87 { |
|
88 __ASSERT_DEBUG( iPendingStartConnection.IsNull(), |
|
89 User::Invariant() ); |
|
90 iVpnIapId = aMessage.Int0(); |
|
91 |
|
92 // Create new VPN connection object and start connection. |
|
93 CVpnConnection& vpnConnection = iServer.CreateVpnConnectionL( iVpnIapId ); |
|
94 TRAPD( err, iConnectionStarter = CConnectionStarter::NewL( vpnConnection, *this ) ); |
|
95 if ( err != KErrNone ) |
|
96 { |
|
97 iServer.DeleteVpnConnection( iVpnIapId ); |
|
98 User::Leave( err ); |
|
99 } |
|
100 iPendingStartConnection = aMessage; |
|
101 iConnectionStarter->StartRealConnection(); |
|
102 } |
|
103 break; |
|
104 } |
|
105 case CKmdServer::KKmdCancelStartConnection: |
|
106 { |
|
107 DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdCancelStartConnection")); |
|
108 |
|
109 DoCancelStartConnection(); |
|
110 aMessage.Complete( KErrNone ); |
|
111 break; |
|
112 } |
|
113 case CKmdServer::KKmdActivateAsync: |
|
114 { |
|
115 DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdActivateAsync")); |
|
116 |
|
117 if ( iActivationStarter != NULL ) |
|
118 { |
|
119 aMessage.Panic( KKmdPanicCategory, |
|
120 EKmdPanicRequestAlreadyPending ); |
|
121 } |
|
122 else |
|
123 { |
|
124 __ASSERT_DEBUG( iPendingActivate.IsNull(), |
|
125 User::Invariant() ); |
|
126 iVpnIapId = aMessage.Int0(); |
|
127 CVpnConnection* vpnConnection = NULL; |
|
128 TRAPD( err, vpnConnection = &iServer.GetVpnConnectionL( iVpnIapId ) ); |
|
129 |
|
130 if ( err != KErrNone ) |
|
131 { |
|
132 __ASSERT_DEBUG( err == KErrNotFound, User::Invariant() ); |
|
133 aMessage.Complete( KErrArgument ); |
|
134 } |
|
135 else |
|
136 { |
|
137 // Read VPN interface name. |
|
138 HBufC* vpnIfName = HBufC::NewLC( aMessage.GetDesLength( 1 ) ); |
|
139 TPtr vpnIfNameDes = vpnIfName->Des(); |
|
140 aMessage.ReadL( 1, vpnIfNameDes ); |
|
141 |
|
142 CIkeDataArray* ikeList = CIkeDataArray::NewL( 1 ); |
|
143 CleanupStack::PushL( ikeList ); |
|
144 |
|
145 // Read 8 bit IKE policy data. |
|
146 HBufC8* ikePolicy8 = HBufC8::NewLC( aMessage.GetDesLength( 2 ) ); |
|
147 TPtr8 policyDes8 = ikePolicy8->Des(); |
|
148 aMessage.ReadL( 2, policyDes8 ); |
|
149 |
|
150 // Copy read IKE policy data to 16 bit buffer. |
|
151 HBufC* ikeConf = HBufC::NewL( policyDes8.Length() ); |
|
152 TPtr ikeConfPtr = ikeConf->Des(); |
|
153 ikeConfPtr.Copy( policyDes8 ); |
|
154 CleanupStack::PopAndDestroy( ikePolicy8 ); |
|
155 CleanupStack::PushL( ikeConf ); |
|
156 |
|
157 // Parse IKE policy data. |
|
158 TIkeParser ikeParser( *ikeConf ); |
|
159 ikeParser.MainParseL( ikeList ); |
|
160 CleanupStack::PopAndDestroy( ikeConf ); |
|
161 |
|
162 // Get first IKE policy section. |
|
163 CIkeData* ikeData = NULL; |
|
164 if (ikeList->Count() > 0) |
|
165 { |
|
166 ikeData = (*ikeList)[0]; |
|
167 } |
|
168 else |
|
169 { |
|
170 User::Leave( KKmdIkePolicyFileErr ); |
|
171 } |
|
172 |
|
173 // Start negotiation. |
|
174 iActivationStarter = CActivationStarter::NewL( *vpnConnection, |
|
175 *this, |
|
176 iServer.Debug() ); |
|
177 iPendingActivate = aMessage; |
|
178 iActivationStarter->Activate( *ikeData, |
|
179 vpnIfNameDes ); |
|
180 |
|
181 CleanupStack::PopAndDestroy( ikeList ); |
|
182 CleanupStack::PopAndDestroy( vpnIfName ); |
|
183 } |
|
184 } |
|
185 break; |
|
186 } |
|
187 case CKmdServer::KKmdCancelActivateAsync: |
|
188 { |
|
189 DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdCancelActivateAsync")); |
|
190 |
|
191 DoCancelActivate(); |
|
192 aMessage.Complete( KErrNone ); |
|
193 break; |
|
194 } |
|
195 case CKmdServer::KKmdStopConnection: |
|
196 { |
|
197 DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdStopConnection")); |
|
198 |
|
199 if ( iConnectionStopper != NULL ) |
|
200 { |
|
201 aMessage.Panic( KKmdPanicCategory, |
|
202 EKmdPanicRequestAlreadyPending ); |
|
203 } |
|
204 else |
|
205 { |
|
206 __ASSERT_DEBUG( iPendingStopConnection.IsNull(), |
|
207 User::Invariant() ); |
|
208 |
|
209 TUint32 vpnIapId = aMessage.Int0(); |
|
210 TKmdStopConnection::TType type = (TKmdStopConnection::TType)aMessage.Int1(); |
|
211 |
|
212 CVpnConnection& connection = iServer.GetVpnConnectionL( vpnIapId ); |
|
213 iConnectionStopper = CConnectionStopper::NewL( connection, *this ); |
|
214 |
|
215 iPendingStopConnection = aMessage; |
|
216 iConnectionStopper->StopVpnConnection( type == TKmdStopConnection::EForced ); |
|
217 } |
|
218 break; |
|
219 } |
|
220 case CKmdServer::KKmdResolveAddress: |
|
221 { |
|
222 DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdResolveAddress")); |
|
223 |
|
224 if ( iFqdnResolver != NULL ) |
|
225 { |
|
226 aMessage.Panic( KKmdPanicCategory, |
|
227 EKmdPanicRequestAlreadyPending ); |
|
228 } |
|
229 else |
|
230 { |
|
231 __ASSERT_DEBUG( iPendingFqdnResolve.IsNull(), |
|
232 User::Invariant() ); |
|
233 iVpnIapId = aMessage.Int0(); |
|
234 CVpnConnection* vpnConnection = NULL; |
|
235 TRAPD( err, vpnConnection = &iServer.GetVpnConnectionL( iVpnIapId ) ); |
|
236 if ( err != KErrNone ) |
|
237 { |
|
238 __ASSERT_DEBUG( err == KErrNotFound, User::Invariant() ); |
|
239 aMessage.Complete( KErrArgument ); |
|
240 } |
|
241 else |
|
242 { |
|
243 HBufC* fqdn = HBufC::NewLC( aMessage.GetDesLengthL( 1 ) ); |
|
244 TPtr fqdnDes = fqdn->Des(); |
|
245 aMessage.ReadL( 1, fqdnDes ); |
|
246 |
|
247 iFqdnResolver = CFqdnResolver::NewL( *vpnConnection, *this ); |
|
248 iPendingFqdnResolve = aMessage; |
|
249 iFqdnResolver->ResolveAddress( fqdn ); |
|
250 CleanupStack::Pop( fqdn ); |
|
251 } |
|
252 } |
|
253 break; |
|
254 } |
|
255 case CKmdServer::KKmdCancelResolveAddress: |
|
256 { |
|
257 DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdCancelResolveAddress")); |
|
258 |
|
259 DoCancelResolveAddress(); |
|
260 aMessage.Complete( KErrNone ); |
|
261 break; |
|
262 } |
|
263 default: |
|
264 { |
|
265 DEBUG_LOG1(_L("CKmdSession::ServiceL, illegal command=%d"), |
|
266 aMessage.Function()); |
|
267 |
|
268 aMessage.Panic( KKmdPanicCategory, EKmdPanicIllegalCommand ); |
|
269 break; |
|
270 } |
|
271 } |
|
272 |
|
273 } |
|
274 |
|
275 // --------------------------------------------------------------------------- |
|
276 // From class MConnectionStarterCallback. |
|
277 // Notification about completion of real connection starting. |
|
278 // --------------------------------------------------------------------------- |
|
279 // |
|
280 void CKmdSession::RealConnectionStarted( TInt aStatus, |
|
281 TInt aRealIap, |
|
282 TInt aRealNetwork ) |
|
283 { |
|
284 DEBUG_LOG3(_L("Real connection started, status=%d, IAP id=%d, NET id=%d"), |
|
285 aStatus, aRealIap, aRealNetwork ); |
|
286 |
|
287 __ASSERT_DEBUG( !iPendingStartConnection.IsNull(), User::Invariant() ); |
|
288 |
|
289 delete iConnectionStarter; |
|
290 iConnectionStarter = NULL; |
|
291 |
|
292 if ( aStatus == KErrNone ) |
|
293 { |
|
294 TVpnRealConnectionParams realConfig = { aRealIap, aRealNetwork }; |
|
295 TPckg<TVpnRealConnectionParams> realConfigPckg( realConfig ); |
|
296 |
|
297 aStatus = iPendingStartConnection.Write( 1, realConfigPckg ); |
|
298 } |
|
299 iPendingStartConnection.Complete( aStatus ); |
|
300 } |
|
301 |
|
302 // --------------------------------------------------------------------------- |
|
303 // From class MConnectionStopperCallback. |
|
304 // Notification about completion of VPN connection stopping. |
|
305 // --------------------------------------------------------------------------- |
|
306 // |
|
307 void CKmdSession::VpnConnectionStopped( TInt aStatus ) |
|
308 { |
|
309 DEBUG_LOG1(_L("VPN connection stopped, status=%d"), aStatus ); |
|
310 |
|
311 __ASSERT_DEBUG( !iPendingStopConnection.IsNull(), User::Invariant() ); |
|
312 |
|
313 delete iConnectionStopper; |
|
314 iConnectionStopper = NULL; |
|
315 |
|
316 iPendingStopConnection.Complete( aStatus ); |
|
317 } |
|
318 |
|
319 // --------------------------------------------------------------------------- |
|
320 // From class MFqdnResolverCallback. |
|
321 // Notifies about completion of FQDN address resolving. |
|
322 // --------------------------------------------------------------------------- |
|
323 // |
|
324 void CKmdSession::AddressResolveCompleted( TInt aStatus, |
|
325 TNameEntry aNameEntry ) |
|
326 { |
|
327 DEBUG_LOG1(_L("FQDN address resolving completed, status=%d"), aStatus ); |
|
328 |
|
329 __ASSERT_DEBUG( !iPendingFqdnResolve.IsNull(), |
|
330 User::Invariant() ); |
|
331 |
|
332 delete iFqdnResolver; |
|
333 iFqdnResolver = NULL; |
|
334 |
|
335 if ( aStatus == KErrNone ) |
|
336 { |
|
337 aStatus = iPendingFqdnResolve.Write( 2, aNameEntry ); |
|
338 } |
|
339 |
|
340 iPendingFqdnResolve.Complete( aStatus ); |
|
341 } |
|
342 |
|
343 // --------------------------------------------------------------------------- |
|
344 // From class MActivationStarterCallback. |
|
345 // Notification about completion of activation. |
|
346 // --------------------------------------------------------------------------- |
|
347 // |
|
348 void CKmdSession::ActivationCompleted( TInt aStatus, |
|
349 const TVPNAddress& aVirtualIp ) |
|
350 { |
|
351 DEBUG_LOG1(_L("Activation completed, status=%d"), aStatus ); |
|
352 |
|
353 __ASSERT_DEBUG( !iPendingActivate.IsNull(), |
|
354 User::Invariant() ); |
|
355 |
|
356 if ( aStatus == KErrNone ) |
|
357 { |
|
358 TVPNAddressPckg addrPkcg( aVirtualIp ); |
|
359 aStatus = iPendingActivate.Write( 3, addrPkcg ); |
|
360 } |
|
361 iPendingActivate.Complete( aStatus ); |
|
362 |
|
363 delete iActivationStarter; |
|
364 iActivationStarter = NULL; |
|
365 } |
|
366 |
|
367 // --------------------------------------------------------------------------- |
|
368 // Cancels real connection starting. |
|
369 // --------------------------------------------------------------------------- |
|
370 // |
|
371 void CKmdSession::DoCancelStartConnection() |
|
372 { |
|
373 if ( iConnectionStarter ) |
|
374 { |
|
375 __ASSERT_DEBUG( !iPendingStartConnection.IsNull(), |
|
376 User::Invariant() ); |
|
377 |
|
378 delete iConnectionStarter; // Cancels ongoing connection starting. |
|
379 iConnectionStarter = NULL; |
|
380 |
|
381 iPendingStartConnection.Complete( KErrCancel ); |
|
382 |
|
383 // Delete VPN connection object. |
|
384 iServer.DeleteVpnConnection( iVpnIapId ); |
|
385 } |
|
386 } |
|
387 |
|
388 // --------------------------------------------------------------------------- |
|
389 // Cancels activating. |
|
390 // --------------------------------------------------------------------------- |
|
391 // |
|
392 void CKmdSession::DoCancelActivate() |
|
393 { |
|
394 if ( iActivationStarter ) |
|
395 { |
|
396 __ASSERT_DEBUG( !iPendingActivate.IsNull(), |
|
397 User::Invariant() ); |
|
398 |
|
399 delete iActivationStarter; // Cancels ongoing activation. |
|
400 iActivationStarter = NULL; |
|
401 |
|
402 iPendingActivate.Complete( KErrCancel ); |
|
403 } |
|
404 } |
|
405 |
|
406 // --------------------------------------------------------------------------- |
|
407 // Cancels FQDN address resolving. |
|
408 // --------------------------------------------------------------------------- |
|
409 // |
|
410 void CKmdSession::DoCancelResolveAddress() |
|
411 { |
|
412 if ( iFqdnResolver ) |
|
413 { |
|
414 __ASSERT_DEBUG( !iPendingFqdnResolve.IsNull(), |
|
415 User::Invariant() ); |
|
416 |
|
417 delete iFqdnResolver; // Cancels ongoing resolving. |
|
418 iFqdnResolver = NULL; |
|
419 |
|
420 iPendingFqdnResolve.Complete( KErrCancel ); |
|
421 } |
|
422 } |
|
423 |