|
1 // Copyright (c) 2003-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 // Implements generic base for NIFMAN side of configuration daemon |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file NIFConfigurationControl.cpp |
|
20 @internalTechnology |
|
21 */ |
|
22 |
|
23 #include "networkconfigextensionbase.h" |
|
24 #include <comms-infras/nifif.h> |
|
25 #include <comms-infras/ca_startserver.h> |
|
26 #include <cdbcols.h> |
|
27 #include <comms-infras/commsdebugutility.h> |
|
28 |
|
29 |
|
30 #ifdef _DEBUG |
|
31 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module |
|
32 // (if it could happen through user error then you should give it an explicit, documented, category + code) |
|
33 _LIT(KSpecAssert_NifManNetCfgExtn, "NifManNetCfgExtn"); |
|
34 #endif |
|
35 |
|
36 _LIT(KIAPId, "IAP\\Id"); |
|
37 _LIT(KIAPNetwork, "IAP\\IAPNetwork"); |
|
38 |
|
39 |
|
40 /** |
|
41 ADeletionNotifier |
|
42 */ |
|
43 ADeletionNotifier::~ADeletionNotifier() |
|
44 { |
|
45 iDeletionListener->NotifyDeletionL(this); |
|
46 } |
|
47 |
|
48 /** |
|
49 ADeferredDeletion |
|
50 */ |
|
51 void ADeferredDeletion::ListenForObjectDeletionL(ADeletionNotifier */*aDelete*/) |
|
52 { |
|
53 iDeletionObjectCount++; |
|
54 } |
|
55 |
|
56 EXPORT_C void ADeferredDeletion::DeleteThis() |
|
57 { |
|
58 iDeleteWhenAllObjectsDeleted = ETrue; |
|
59 if (iDeletionObjectCount == 0) |
|
60 { |
|
61 delete this; |
|
62 } |
|
63 } |
|
64 |
|
65 EXPORT_C void ADeferredDeletion::NotifyDeletionL(ADeletionNotifier */*aDelete*/) |
|
66 { |
|
67 iDeletionObjectCount--; |
|
68 if (iDeleteWhenAllObjectsDeleted && iDeletionObjectCount == 0) |
|
69 { |
|
70 DeleteThis(); |
|
71 } |
|
72 } |
|
73 |
|
74 NONSHARABLE_CLASS(CAsynchDaemonCancel) : public CActive, public ADeletionNotifier |
|
75 { |
|
76 public: |
|
77 CAsynchDaemonCancel(ADeferredDeletion* aDeletionListener) : |
|
78 CActive(EPriorityStandard), ADeletionNotifier(aDeletionListener) |
|
79 { |
|
80 } |
|
81 |
|
82 void AsyncDelete(); |
|
83 |
|
84 void CancelControl(RConfigDaemon& aConfigDaemon, TBool aDeleteOnCompletion); |
|
85 void CancelControl(RConfigDaemon& aConfigDaemon, TInt aOpMask, TBool aDeleteOnCompletion); |
|
86 |
|
87 protected: |
|
88 virtual void RunL(); |
|
89 virtual void DoCancel(); |
|
90 |
|
91 protected: |
|
92 TBool iDeleteOnCompletion; |
|
93 }; |
|
94 |
|
95 NONSHARABLE_CLASS(CNifDaemonProgress) : public CActive, public ADeletionNotifier, public ADeferredDeletion |
|
96 /** |
|
97 * Active object class used by CNetworkConfigExtensionBase to maintain a persistent |
|
98 * ProgressNotification call against the daemon. Delete this object only using the |
|
99 * AsyncDelete method. |
|
100 * |
|
101 * @internalComponent |
|
102 */ |
|
103 { |
|
104 public: |
|
105 static CNifDaemonProgress* NewL(RConfigDaemon& aConfigDaemon, CNetworkConfigExtensionBase* aProgressDest, ADeferredDeletion* aDeletionListener); |
|
106 void ProgressNotification(); |
|
107 void AsyncDelete(); |
|
108 void DeleteThis(); |
|
109 void CancelControl(); |
|
110 |
|
111 protected: |
|
112 void RunL(); |
|
113 void DoCancel(); |
|
114 |
|
115 // This is protectde so that you MUST use AsyncDelete. |
|
116 virtual ~CNifDaemonProgress() {}; |
|
117 |
|
118 private: |
|
119 |
|
120 void ConstructL(); |
|
121 CNifDaemonProgress(RConfigDaemon& aConfigDaemon, CNetworkConfigExtensionBase* aProgressDest, ADeferredDeletion* aDeletionListener); |
|
122 /** Reference to the configuration daemon interface. */ |
|
123 RConfigDaemon& iConfigDaemon; |
|
124 /** Used to asynchrounously cancel any outstanding request on iConfigDaemon so that esock is never blocked. */ |
|
125 CAsynchDaemonCancel* iAsynchDaemonCancel; |
|
126 /** The target for progress notifications. */ |
|
127 CNetworkConfigExtensionBase* iProgressDest; |
|
128 /** Stores the progress notification. */ |
|
129 TDaemonProgressBuf iProgressBuf; |
|
130 /** If ETrue, the object should delete itself when the outstanding request completes. */ |
|
131 TBool iDeleteOnCompletion; |
|
132 }; |
|
133 |
|
134 void CAsynchDaemonCancel::AsyncDelete() |
|
135 /** |
|
136 * Delete the instance of CAsynchDaemonCancel safely. |
|
137 * |
|
138 * @internalComponent |
|
139 */ |
|
140 { |
|
141 if (IsActive()) |
|
142 iDeleteOnCompletion = ETrue; |
|
143 else |
|
144 delete this; |
|
145 } |
|
146 |
|
147 void CAsynchDaemonCancel::DoCancel() |
|
148 {//nothing to do |
|
149 } |
|
150 |
|
151 void CAsynchDaemonCancel::CancelControl(RConfigDaemon& aConfigDaemon, TBool aDeleteOnCompletion) |
|
152 { |
|
153 if (!IsActive()) |
|
154 { |
|
155 __ASSERT_DEBUG(!IsAdded(), User::Panic(KSpecAssert_NifManNetCfgExtn, 1)); |
|
156 CActiveScheduler::Add(this); |
|
157 aConfigDaemon.Cancel(iStatus); |
|
158 SetActive(); |
|
159 } |
|
160 iDeleteOnCompletion = aDeleteOnCompletion; |
|
161 } |
|
162 |
|
163 void CAsynchDaemonCancel::CancelControl(RConfigDaemon& aConfigDaemon, TInt aOpMask, TBool aDeleteOnCompletion) |
|
164 /** |
|
165 * CancelControl - Asynchronously cancels the last server request according to aOpMask. |
|
166 * |
|
167 * @internalComponent |
|
168 */ |
|
169 { |
|
170 if (!IsActive()) |
|
171 { |
|
172 __ASSERT_DEBUG(!IsAdded(), User::Panic(KSpecAssert_NifManNetCfgExtn, 2)); |
|
173 CActiveScheduler::Add(this); |
|
174 aConfigDaemon.Cancel(aOpMask,iStatus); |
|
175 SetActive(); |
|
176 } |
|
177 iDeleteOnCompletion = aDeleteOnCompletion; |
|
178 } |
|
179 |
|
180 void CAsynchDaemonCancel::RunL() |
|
181 { |
|
182 if ( iDeleteOnCompletion ) |
|
183 { |
|
184 delete this; |
|
185 } |
|
186 else |
|
187 { |
|
188 Deque(); |
|
189 } |
|
190 } |
|
191 |
|
192 CNifDaemonProgress* CNifDaemonProgress::NewL(RConfigDaemon& aConfigDaemon, CNetworkConfigExtensionBase* aProgressDest, ADeferredDeletion* aDeletionListener) |
|
193 /** |
|
194 * Standard NewL for CNifDaemonProgress. |
|
195 * |
|
196 * @internalComponent |
|
197 * |
|
198 * @param aConfigDaemon Daemon client to be used. |
|
199 * @param aProgressDest Destination for progress notifications. |
|
200 * @leave KErrNoMemory if there is insufficient heap. |
|
201 */ |
|
202 { |
|
203 CNifDaemonProgress* pDaemonProgress = new(ELeave)CNifDaemonProgress(aConfigDaemon, aProgressDest, aDeletionListener); |
|
204 CleanupStack::PushL(pDaemonProgress); |
|
205 pDaemonProgress->ConstructL(); |
|
206 CleanupStack::Pop(pDaemonProgress); |
|
207 return pDaemonProgress; |
|
208 } |
|
209 |
|
210 void CNifDaemonProgress::DeleteThis() |
|
211 { |
|
212 if (iAsynchDaemonCancel) |
|
213 { |
|
214 iAsynchDaemonCancel->AsyncDelete(); |
|
215 iAsynchDaemonCancel = NULL; |
|
216 } |
|
217 ADeferredDeletion::DeleteThis(); |
|
218 } |
|
219 |
|
220 void CNifDaemonProgress::ConstructL() |
|
221 /** |
|
222 * Standard ConstructL for CNifDaemonProgress. |
|
223 * |
|
224 * @internalComponent |
|
225 * |
|
226 * @leave KErrNoMemory if there is insufficient heap. |
|
227 */ |
|
228 { |
|
229 iAsynchDaemonCancel = new(ELeave)CAsynchDaemonCancel(this); |
|
230 } |
|
231 |
|
232 CNifDaemonProgress::CNifDaemonProgress( |
|
233 RConfigDaemon& aConfigDaemon, |
|
234 CNetworkConfigExtensionBase* aProgressDest, |
|
235 ADeferredDeletion* aDeletionListener) : |
|
236 CActive(EPriorityStandard), |
|
237 ADeletionNotifier(aDeletionListener), |
|
238 iConfigDaemon(aConfigDaemon), |
|
239 iAsynchDaemonCancel(NULL), |
|
240 iProgressDest(aProgressDest), |
|
241 iDeleteOnCompletion(EFalse) |
|
242 /** |
|
243 * Construct the progress active object. Adds the active object to the scheduler and |
|
244 * issues the asynchronous call. |
|
245 * |
|
246 * @internalComponent |
|
247 * |
|
248 * @param aConfigDaemon Daemon client to be used. |
|
249 * @param aProgressDest Destination for progress notifications. |
|
250 */ |
|
251 { |
|
252 CActiveScheduler::Add(this); |
|
253 ProgressNotification(); |
|
254 } |
|
255 |
|
256 void CNifDaemonProgress::ProgressNotification() |
|
257 /** |
|
258 * Issues the asynchronous progress notification request. |
|
259 * |
|
260 * @internalComponent |
|
261 */ |
|
262 { |
|
263 iConfigDaemon.ProgressNotification(iProgressBuf, iStatus); |
|
264 SetActive(); |
|
265 } |
|
266 |
|
267 void CNifDaemonProgress::RunL() |
|
268 /** |
|
269 * Indicates that a progress notification was received. |
|
270 * The progress info will be found in iProgressBuf. |
|
271 * |
|
272 * @internalComponent |
|
273 */ |
|
274 { |
|
275 if (iDeleteOnCompletion) |
|
276 { |
|
277 // if iDeleteOnCompletion is true, we are to delete ourselves |
|
278 __FLOG_STATIC0(KLogSubSysNifman, KLogTagCsDaemon, _L("CNifDaemonProgress::RunL - Deleting ourselves.")); |
|
279 DeleteThis(); |
|
280 } |
|
281 else if (iStatus.Int() == KErrNone) |
|
282 { |
|
283 // We successfully got a progress notification. Pass it |
|
284 // on the the target and re-issue the request. |
|
285 __FLOG_STATIC1(KLogSubSysNifman, KLogTagCsDaemon, _L("CNifDaemonProgress::RunL - Successfully received progress notification %d. Re-issuing request."),iProgressBuf().iStage); |
|
286 iProgressDest->DoOnDaemonProgress(iProgressBuf().iStage, iProgressBuf().iError); |
|
287 ProgressNotification(); |
|
288 } |
|
289 else if (iStatus.Int() == KErrNotReady) |
|
290 { |
|
291 // The daemon is starting-up. Re-issue the request. |
|
292 __FLOG_STATIC0(KLogSubSysNifman, KLogTagCsDaemon, _L("CNifDaemonProgress::RunL - Progress notification. Waiting for server to start.")); |
|
293 ProgressNotification(); |
|
294 } |
|
295 else |
|
296 { |
|
297 // We failed to get a progress notification. |
|
298 // The daemon either does not support this request, |
|
299 // has exited or has died. Do not issue another request. |
|
300 // We'll get into a tight loop if we do. |
|
301 __FLOG_STATIC1(KLogSubSysNifman, KLogTagCsDaemon, _L("CNifDaemonProgress::RunL - Failed to get progress notification from daemon. The error was %d"),iStatus.Int()); |
|
302 } |
|
303 } |
|
304 |
|
305 void CNifDaemonProgress::AsyncDelete() |
|
306 /** |
|
307 * Cancels any outstanding progress notification and optionally |
|
308 * the instance of CNifDaemonProgress asynchronously to avoid |
|
309 * potential deadlock in Esock. |
|
310 * |
|
311 * @internalComponent |
|
312 */ |
|
313 { |
|
314 if (IsActive()) |
|
315 { |
|
316 __FLOG_STATIC0(KLogSubSysNifman, KLogTagCsDaemon, _L("CNifDaemonProgress::AsyncDelete - Waiting for CancelControl to complete")); |
|
317 iDeleteOnCompletion = ETrue; |
|
318 CancelControl(); |
|
319 } |
|
320 else |
|
321 { |
|
322 DeleteThis(); |
|
323 } |
|
324 } |
|
325 |
|
326 void CNifDaemonProgress::CancelControl() |
|
327 /** |
|
328 * Cancels any outstanding progress asynchronously to avoid |
|
329 * potential deadlock in Esock. |
|
330 * |
|
331 * @internalComponent |
|
332 */ |
|
333 { |
|
334 if (IsActive()) |
|
335 { |
|
336 iAsynchDaemonCancel->CancelControl(iConfigDaemon, KConfigDaemonOpMaskProgress, iDeleteOnCompletion); |
|
337 if (iDeleteOnCompletion) |
|
338 iAsynchDaemonCancel = NULL; |
|
339 } |
|
340 } |
|
341 |
|
342 void CNifDaemonProgress::DoCancel() |
|
343 /** |
|
344 * Standard active object DoCancel. |
|
345 * |
|
346 * @internalComponent |
|
347 */ |
|
348 { |
|
349 // DoCancel() is only used by Cancel(), which is can not be |
|
350 // used as it will block the ESOCK thread. |
|
351 __ASSERT_DEBUG(0, User::Panic(KSpecAssert_NifManNetCfgExtn, 3)); |
|
352 } |
|
353 |
|
354 CNetworkConfigExtensionBase* CNetworkConfigExtensionBase::NewL( TAny* aMNifIfNotify ) |
|
355 { |
|
356 MNifIfNotify* nifIfNotify = reinterpret_cast<MNifIfNotify*>(aMNifIfNotify); |
|
357 CNetworkConfigExtensionBase* pDaemon = new(ELeave)CNetworkConfigExtensionBase( *nifIfNotify ); |
|
358 CleanupStack::PushL(pDaemon); |
|
359 pDaemon->ConstructL(); |
|
360 CleanupStack::Pop(pDaemon); |
|
361 return pDaemon; |
|
362 } |
|
363 |
|
364 EXPORT_C void CNetworkConfigExtensionBase::ConstructL() |
|
365 { |
|
366 __FLOG_STATIC0(KLogSubSysNifman, KLogTagCsDaemon, _L("CNetworkConfigExtensionBase::ConstructL")); |
|
367 iAsynchDaemonCancel = new(ELeave)CAsynchDaemonCancel(this); |
|
368 } |
|
369 |
|
370 EXPORT_C void CNetworkConfigExtensionBase::ConfigureNetworkL() |
|
371 /** |
|
372 ConfigureNetworkL - starts a daemon and issues configuration request |
|
373 @internalTechnology |
|
374 @version 0.02 |
|
375 **/ |
|
376 { |
|
377 __FLOG_STATIC0(KLogSubSysNifman, KLogTagCsDaemon, _L("CNetworkConfigExtensionBase::ConfigureNetworkL")); |
|
378 //it could access directly CNifAgentRef::ConnectionInfo but i don't want the class be |
|
379 //CNifAgentRef dependent |
|
380 __ASSERT_DEBUG(iMessage.IsNull(), User::Panic(KSpecAssert_NifManNetCfgExtn, 4)); |
|
381 |
|
382 User::LeaveIfError(iNifIfNotify->ReadInt(KIAPId(), iConnectionInfoBuf().iIapId)); |
|
383 User::LeaveIfError(iNifIfNotify->ReadInt(KIAPNetwork(), iConnectionInfoBuf().iNetId)); |
|
384 //this is the same read as in CNifConfigurationControl::NewL we do the read rather than storing the |
|
385 //server name since the db access should really provide an efficient access to the settings |
|
386 //already selected by NETCON |
|
387 TBuf<KCommsDbSvrMaxFieldLength> serverName; /*100 bytes if unicode*/ |
|
388 User::LeaveIfError(iNifIfNotify->ReadDes(TPtrC(SERVICE_CONFIG_DAEMON_NAME), serverName)); |
|
389 // safe to pass stack var here, as its copied down the track... |
|
390 |
|
391 // For security reasons, ensure that the server name has the "!" prefix - only protected |
|
392 // servers should be involved with Network Configuration. |
|
393 |
|
394 _LIT(KExclamationMark, "!"); |
|
395 if (serverName.Left(1).Compare(KExclamationMark()) != 0) |
|
396 serverName.Insert(0,KExclamationMark()); |
|
397 |
|
398 __ASSERT_DEBUG(!ipStartServer, User::Panic(KSpecAssert_NifManNetCfgExtn, 5)); |
|
399 DoOnGenericProgress(KConfigDaemonLoading, KErrNone); |
|
400 ipStartServer = new(ELeave)CStartServer(iConfigDaemon, iConfigDaemon.Version(), 10); |
|
401 ipStartServer->Connect(serverName, iStatus); |
|
402 SetActive(); |
|
403 } |
|
404 |
|
405 EXPORT_C void CNetworkConfigExtensionBase::LinkLayerDown() |
|
406 /** |
|
407 * Generates an EConfigDaemonLinkLayerDown request. Used to inform the |
|
408 * daemon that link-layer renegotiation has started. |
|
409 * |
|
410 * @internalComponent |
|
411 */ |
|
412 { |
|
413 if (iSuccessfullyCreatedDaemon) |
|
414 iConfigDaemon.LinkLayerDown(); |
|
415 } |
|
416 |
|
417 EXPORT_C void CNetworkConfigExtensionBase::LinkLayerUp() |
|
418 /** |
|
419 * Generates an EConfigDaemonLinkLayerUp request. Used to inform the |
|
420 * daemon that link-layer renegotiation has completed. |
|
421 * |
|
422 * @internalComponent |
|
423 */ |
|
424 { |
|
425 if (iSuccessfullyCreatedDaemon) |
|
426 iConfigDaemon.LinkLayerUp(); |
|
427 } |
|
428 |
|
429 EXPORT_C void CNetworkConfigExtensionBase::Deregister( |
|
430 TInt aCause) |
|
431 /** |
|
432 * Generates a deregistration request. |
|
433 * |
|
434 * @internalComponent |
|
435 * |
|
436 * @param aCause Specifies what caused the deregistration request (idle timer or Stop call) |
|
437 */ |
|
438 { |
|
439 if (IsActive()) |
|
440 { |
|
441 // if a deregistration request isn't queued up, queue one up |
|
442 if (!iDeregisterOnCompletionOfRequest) |
|
443 { |
|
444 iDeregisterOnCompletionOfRequest = ETrue; |
|
445 iDeregistrationCauseCode = aCause; |
|
446 } |
|
447 } |
|
448 else if (!iSuccessfullyCreatedDaemon) |
|
449 { |
|
450 // note that there is no longer a queued deregistration |
|
451 // request |
|
452 iDeregisterOnCompletionOfRequest = EFalse; |
|
453 // fake the behaviour of the daemon and report |
|
454 // KErrNotFound to be compatible with the previous |
|
455 // behaviour expected by the DHCP tests - KErrNotFound |
|
456 // as in the daemon "was not found" |
|
457 DoOnGenericProgress(KConfigDaemonStartingDeregistration, KErrNone); |
|
458 DoOnGenericProgress(KConfigDaemonFinishedDeregistrationStop, KErrNotFound); |
|
459 } |
|
460 else |
|
461 { |
|
462 // note that there is no longer a queued deregistration |
|
463 // request |
|
464 iDeregisterOnCompletionOfRequest = EFalse; |
|
465 // progress notification before the operation |
|
466 DoOnGenericProgress(KConfigDaemonStartingDeregistration, KErrNone); |
|
467 // ask the daemon to deregister |
|
468 iConfigDaemon.Deregister(aCause, &iDesDeregActionStatus, iStatus); |
|
469 SetActive(); |
|
470 } |
|
471 } |
|
472 |
|
473 EXPORT_C void CNetworkConfigExtensionBase::SendIoctlMessageL(const ESock::RLegacyResponseMsg& aMessage) |
|
474 /** |
|
475 * SendIoctlMessageL forwards Ioctl request to the daemon and activates the AO to wait for response |
|
476 * |
|
477 @internalTechnology |
|
478 @version 0.02 |
|
479 @param aMessage[in] a message to be processed (it's the caller's resposibility to forward just Ioctl |
|
480 * messages) |
|
481 **/ |
|
482 { |
|
483 __FLOG_STATIC0(KLogSubSysNifman, KLogTagCsDaemon, _L("CNetworkConfigExtensionBase::SendIoctlMessageL")); |
|
484 if (static_cast<TUint>(aMessage.Int0()) != KCOLConfiguration) |
|
485 { |
|
486 User::Leave(KErrNotSupported); |
|
487 } |
|
488 else |
|
489 { |
|
490 if (!IsActive()) |
|
491 { |
|
492 TDes8* ptr = NULL; |
|
493 // may not always have a buffer to read... |
|
494 if (aMessage.Ptr2()) |
|
495 { |
|
496 |
|
497 delete iIoBuf; |
|
498 iIoBuf = NULL; |
|
499 TInt maxLength = aMessage.GetDesMaxLengthL(2); |
|
500 iIoBuf=HBufC8::NewMaxL(maxLength); |
|
501 iIoPtr.Set(iIoBuf->Des()); |
|
502 aMessage.ReadL(2, iIoPtr); |
|
503 |
|
504 TInt length = aMessage.GetDesLength(2); |
|
505 if (length<1) //length could be -ve due to error return from GetDesLength |
|
506 { |
|
507 iIoPtr.SetLength(maxLength); |
|
508 } |
|
509 else |
|
510 { |
|
511 iIoPtr.SetLength(length); |
|
512 } |
|
513 ptr = &iIoPtr; |
|
514 } |
|
515 //store msg after ReadDescriptorL which could leave |
|
516 iMessage = aMessage; |
|
517 iConfigDaemon.Ioctl(aMessage.Int0(), aMessage.Int1(), iStatus, ptr); |
|
518 SetActive(); |
|
519 } |
|
520 else |
|
521 { |
|
522 User::Leave(KErrInUse); |
|
523 } |
|
524 } |
|
525 } |
|
526 |
|
527 EXPORT_C void CNetworkConfigExtensionBase::AsyncDelete() |
|
528 /** |
|
529 Provide a clever method for deletion and |
|
530 asynchronously cancelling any outstanding event |
|
531 so as to avoid any problems of deadlock |
|
532 **/ |
|
533 { |
|
534 if (IsActive()) //are we waiting? |
|
535 { |
|
536 //yes |
|
537 // complete any blocked client message immediately - no sense in keeping them hanging on and in a session close |
|
538 // case the dealer may race us to this |
|
539 if (!iMessage.IsNull()) |
|
540 { |
|
541 iMessage.Complete(KErrCancel); |
|
542 } |
|
543 iDeleteOnCompletion = ETrue; |
|
544 CancelControl(); |
|
545 // Zero our reference to the NIFMAN CNifAgentRef as it can be destroyed |
|
546 // ahead of us (this problem manifests itself during cycles of connection |
|
547 // start immediately followed by connection stop). |
|
548 iNifIfNotify = NULL; |
|
549 } |
|
550 else |
|
551 { |
|
552 DeleteThis(); |
|
553 } |
|
554 } |
|
555 |
|
556 EXPORT_C void CNetworkConfigExtensionBase::CancelControl() |
|
557 /** |
|
558 CancelControl - cancels request asynchronously to avoid deadlock |
|
559 @internalAll |
|
560 @version 0.01 |
|
561 **/ |
|
562 { |
|
563 if (IsActive()) //are we waiting? |
|
564 { |
|
565 //yes |
|
566 if (ipStartServer) |
|
567 { |
|
568 ipStartServer->Cancel(); //it'll set an error code to KErrCancel meaning that |
|
569 //the requests will complete with KErrCancel |
|
570 } |
|
571 else |
|
572 { |
|
573 if(iLastGenericProgressStage != KConfigDaemonStartingDeregistration) |
|
574 { |
|
575 iAsynchDaemonCancel->CancelControl(iConfigDaemon, iDeleteOnCompletion); |
|
576 if ( iDeleteOnCompletion ) |
|
577 { |
|
578 iAsynchDaemonCancel = NULL; |
|
579 } |
|
580 } |
|
581 } |
|
582 //the RunL method will be called on the original request cancellation |
|
583 } |
|
584 } |
|
585 |
|
586 EXPORT_C void CNetworkConfigExtensionBase::DoCancel() |
|
587 /** |
|
588 DoCancel - cancels current request |
|
589 @internalTechnology |
|
590 @version 0.01 |
|
591 @see CActive::DoCancel |
|
592 **/ |
|
593 { |
|
594 __ASSERT_DEBUG(0, User::Panic(KSpecAssert_NifManNetCfgExtn, 6)); //we shouldn't ever get here, would block NIFMAN/ESOCK thread |
|
595 } |
|
596 |
|
597 EXPORT_C void CNetworkConfigExtensionBase::RunL() |
|
598 /** |
|
599 RunL - called when request completes |
|
600 @internalTechnology |
|
601 @version 0.03 |
|
602 @see CActive::RunL |
|
603 **/ |
|
604 { |
|
605 //__FLOG_STATIC0(KLogSubSysNifman, KLogTagCsDaemon, _L("CNetworkConfigExtensionBase::RunL")); |
|
606 |
|
607 if (iDeleteOnCompletion) |
|
608 { |
|
609 // if iDeleteOnCompletion is true, we are to delete ourselves |
|
610 |
|
611 // if there was an outstanding IOCTL request, complete the message |
|
612 if (!iMessage.IsNull()) |
|
613 { |
|
614 // client request completion |
|
615 const TAny* ptr = iMessage.Ptr2(); |
|
616 if (ptr) |
|
617 { |
|
618 __ASSERT_DEBUG(iIoBuf, User::Panic(KSpecAssert_NifManNetCfgExtn, 7)); |
|
619 iMessage.WriteL(2, *iIoBuf); |
|
620 delete iIoBuf; //no longer needed |
|
621 iIoBuf = NULL; |
|
622 } |
|
623 iMessage.Complete(iStatus.Int()); |
|
624 } |
|
625 |
|
626 __ASSERT_DEBUG(!ipStartServer || !ipStartServer->IsActive(), User::Panic(KSpecAssert_NifManNetCfgExtn, 8)); |
|
627 delete ipStartServer; //no needed any more |
|
628 ipStartServer = NULL; |
|
629 DeleteThis(); |
|
630 // ********************************************* |
|
631 // CAREFUL... don't do anything after this point |
|
632 // because this object has been deleted |
|
633 // ********************************************* |
|
634 } |
|
635 else if (ipStartServer) |
|
636 { |
|
637 // the daemon server was created (or the creation failed) |
|
638 |
|
639 // if ipStartServer is not null, then the server has just been |
|
640 // started |
|
641 delete ipStartServer; //no needed any more |
|
642 ipStartServer = NULL; |
|
643 if (iStatus.Int() == KErrNone) |
|
644 { |
|
645 // record the fact that the daemon was successfully |
|
646 // launched |
|
647 iSuccessfullyCreatedDaemon = ETrue; |
|
648 // signal that the daemon was loaded successfully |
|
649 DoOnGenericProgress(KConfigDaemonLoaded, KErrNone); |
|
650 // create progress instance - this registers for daemon progress notifications |
|
651 iDaemonProgress = CNifDaemonProgress::NewL(iConfigDaemon, this, this); |
|
652 // signal before the Configure method is called |
|
653 DoOnGenericProgress(KConfigDaemonStartingRegistration, KErrNone); |
|
654 //complete connection |
|
655 iConfigDaemon.Configure(iConnectionInfoBuf, iStatus); |
|
656 SetActive(); |
|
657 //wait for the Configure to complete |
|
658 } |
|
659 else |
|
660 { |
|
661 //we're done with en error |
|
662 iNifIfNotify->IfProgress(KLinkLayerOpen, iStatus.Int()); |
|
663 } |
|
664 } |
|
665 else if (!iMessage.IsNull()) |
|
666 { |
|
667 // the ioctl request completed |
|
668 |
|
669 // complete the message |
|
670 const TAny* ptr = iMessage.Ptr2(); |
|
671 if (ptr) |
|
672 { |
|
673 __ASSERT_DEBUG(iIoBuf, User::Panic(KSpecAssert_NifManNetCfgExtn, 9)); |
|
674 iMessage.WriteL(2, *iIoBuf); |
|
675 delete iIoBuf; //no longer needed |
|
676 iIoBuf = NULL; |
|
677 } |
|
678 iMessage.Complete(iStatus.Int()); |
|
679 |
|
680 // start to deregister if we happen to have one queued |
|
681 if (iDeregisterOnCompletionOfRequest) |
|
682 Deregister(iDeregistrationCauseCode); |
|
683 } |
|
684 else if (iLastGenericProgressStage == KConfigDaemonStartingRegistration) |
|
685 { |
|
686 // the configure call completed |
|
687 |
|
688 // signal the completed Configure call |
|
689 DoOnGenericProgress(KConfigDaemonFinishedRegistration, iStatus.Int()); |
|
690 //no user request => must be configuration completion => signal it up |
|
691 iNifIfNotify->IfProgress(KLinkLayerOpen, iStatus.Int()); |
|
692 // start to deregister if we happen to have one queued |
|
693 if (iDeregisterOnCompletionOfRequest) |
|
694 Deregister(iDeregistrationCauseCode); |
|
695 } |
|
696 else if (iLastGenericProgressStage == KConfigDaemonStartingDeregistration) |
|
697 { |
|
698 // the deregistration request completed |
|
699 |
|
700 // if any error occurred, we should assume stop |
|
701 // is the desired result |
|
702 if (iStatus.Int() != KErrNone) |
|
703 iDeregActionStatus = EConfigDaemonDeregisterActionStop; |
|
704 // if the daemon doesn't support deregistration, |
|
705 // we act as if everything succeeded |
|
706 if (iStatus.Int() == KErrNotSupported) |
|
707 iStatus = KErrNone; |
|
708 // handle the result |
|
709 switch (iDeregActionStatus) |
|
710 { |
|
711 case EConfigDaemonDeregisterActionStop: |
|
712 // progress notification - note that this specific |
|
713 // notification will delete this object |
|
714 DoOnGenericProgress(KConfigDaemonFinishedDeregistrationStop, iStatus.Int()); |
|
715 // ***************************************************** |
|
716 // CAREFUL... don't do anything after this point because |
|
717 // this object has been deleted as a result of this |
|
718 // progress notification |
|
719 // ***************************************************** |
|
720 break; |
|
721 case EConfigDaemonDeregisterActionPreserve: |
|
722 // progress notification |
|
723 DoOnGenericProgress(KConfigDaemonFinishedDeregistrationPreserve, iStatus.Int()); |
|
724 // start to deregister if we happen to have one queued |
|
725 if (iDeregisterOnCompletionOfRequest) |
|
726 Deregister(iDeregistrationCauseCode); |
|
727 break; |
|
728 default: |
|
729 User::Leave(KErrNotSupported); |
|
730 break; |
|
731 } |
|
732 } |
|
733 else |
|
734 { |
|
735 // should never get here. |
|
736 __ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_NifManNetCfgExtn, 10)); |
|
737 } |
|
738 // ******************************************** |
|
739 // CAREFUL... consider the possible deletion of |
|
740 // this object in the code above before adding |
|
741 // anything down here |
|
742 // ******************************************** |
|
743 } |
|
744 |
|
745 EXPORT_C TInt CNetworkConfigExtensionBase::RunError(TInt aError) |
|
746 {//see CNetworkConfigExtensionBase::RunL the only case it can leave is when iMessage is valid |
|
747 if (!iMessage.IsNull()) |
|
748 { |
|
749 iMessage.Complete(aError); |
|
750 } |
|
751 return KErrNone; |
|
752 } |
|
753 |
|
754 EXPORT_C void CNetworkConfigExtensionBase::DeleteThis() |
|
755 { |
|
756 // delete safely the progress request |
|
757 if (iDaemonProgress) |
|
758 { |
|
759 iDaemonProgress->AsyncDelete(); |
|
760 iDaemonProgress = NULL; |
|
761 } |
|
762 |
|
763 // delete safely the cancel request |
|
764 if (iAsynchDaemonCancel) |
|
765 { |
|
766 iAsynchDaemonCancel->AsyncDelete(); |
|
767 iAsynchDaemonCancel = NULL; |
|
768 } |
|
769 |
|
770 ADeferredDeletion::DeleteThis(); |
|
771 /* iDeleteWhenAllObjectsDeleted = ETrue; |
|
772 if (iDeletionObjectCount == 0) |
|
773 { |
|
774 delete this; |
|
775 }*/ |
|
776 } |
|
777 |
|
778 EXPORT_C CNetworkConfigExtensionBase::~CNetworkConfigExtensionBase() |
|
779 /** |
|
780 ~CNetworkConfigExtensionBase - destructor |
|
781 @internalTechnology |
|
782 @version 0.02 |
|
783 **/ |
|
784 { |
|
785 // complete any outstanding messages |
|
786 if (!iMessage.IsNull()) |
|
787 { |
|
788 //client request completion - no point to write any data back to client here |
|
789 iMessage.Complete(KErrCancel); |
|
790 } |
|
791 __ASSERT_DEBUG(!ipStartServer, User::Panic(KSpecAssert_NifManNetCfgExtn, 11)); |
|
792 |
|
793 // unload the daemon |
|
794 DoOnGenericProgress(KConfigDaemonUnloading, KErrNone); |
|
795 iConfigDaemon.Close(); |
|
796 DoOnGenericProgress(KConfigDaemonUnloaded, KErrNone); |
|
797 |
|
798 delete iIoBuf; |
|
799 } |
|
800 |
|
801 EXPORT_C void CNetworkConfigExtensionBase::EventNotification(TNetworkAdaptorEventType /*aEventType*/, TUint /*aEvent*/, const TDesC8& /*aEventData*/, TAny* /*aSource*/) |
|
802 /** |
|
803 Notification - does nothing. Needs to be implemented by deriving class to achieve functionality. |
|
804 @internalTechnology |
|
805 @version 0.01 |
|
806 **/ |
|
807 {} |
|
808 |
|
809 void CNetworkConfigExtensionBase::DoOnDaemonProgress(TInt aStage, TInt aError) |
|
810 /** |
|
811 * Called by CNifDaemonProgress when it receives a progress notification. |
|
812 * Passes the notification to CNifAgentRef. |
|
813 * |
|
814 * @internalComponent |
|
815 * |
|
816 * @param aStage Progress stage reported by the daemon |
|
817 * @param aError Error code associated with the stage |
|
818 */ |
|
819 { |
|
820 if (iNifIfNotify) // see comment in AsyncDelete() |
|
821 { |
|
822 iNifIfNotify->IfProgress(aStage, aError); |
|
823 } |
|
824 } |
|
825 |
|
826 void CNetworkConfigExtensionBase::DoOnGenericProgress(TInt aStage, TInt aError) |
|
827 /** |
|
828 * Called to generate the cs_daemon generic progress notifications. |
|
829 * |
|
830 * @internalComponent |
|
831 * |
|
832 * @param aStage Generic progress stage |
|
833 * @param aError Error code associated with the stage |
|
834 */ |
|
835 { |
|
836 iLastGenericProgressStage = aStage; |
|
837 if (iNifIfNotify) // see comment in AsyncDelete() |
|
838 { |
|
839 iNifIfNotify->IfProgress(aStage, aError); |
|
840 } |
|
841 } |
|
842 |