|
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 // |
|
15 |
|
16 #include <bluetooth/logger.h> |
|
17 #include <bt_sock.h> |
|
18 #include <comms-infras/nifif.h> // should be removed once KCOGetAgentEMIPtr is defined in nifagt.h |
|
19 #include <elements/nm_interfaces.h> |
|
20 #include "panagtlog.h" |
|
21 #include "panagt.h" |
|
22 #include "panagtremdev.h" |
|
23 #include "panagtstates.h" |
|
24 #include "panlocalsdphelper.h" |
|
25 #include <comms-infras/nifagt_internal.h> |
|
26 #include <panctrl.h> |
|
27 #include <btextnotifierspartner.h> |
|
28 |
|
29 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
30 #include "panprovisioninfo.h" |
|
31 #include "panmessages.h" |
|
32 |
|
33 #ifdef ESOCK_EXTLOG_ACTIVE |
|
34 _LIT8(KPanAgtSubTag, "panagt"); |
|
35 #endif |
|
36 |
|
37 #endif |
|
38 // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
39 |
|
40 #ifdef __FLOG_ACTIVE |
|
41 _LIT8(KLogComponent, LOG_COMPONENT_PAN_AGENT); |
|
42 #endif |
|
43 |
|
44 using namespace PanAgent; |
|
45 using namespace Messages; |
|
46 |
|
47 extern "C" EXPORT_C CNifAgentFactory* NewAgentFactoryL() |
|
48 /** |
|
49 Pan agent factory |
|
50 */ |
|
51 { |
|
52 return new(ELeave) CPanAgentFactory(); |
|
53 } |
|
54 |
|
55 // |
|
56 // PAN agent factory |
|
57 // |
|
58 |
|
59 void CPanAgentFactory::InstallL() |
|
60 /** |
|
61 * Perform any agent factory initialisation |
|
62 */ |
|
63 { |
|
64 LOG_FUNC |
|
65 } |
|
66 |
|
67 CNifAgentBase* CPanAgentFactory::NewAgentL(const TDesC& /*aName*/) |
|
68 /** |
|
69 * Create a new PAN agent |
|
70 */ |
|
71 { |
|
72 LOG_FUNC |
|
73 return CPanAgent::NewL(); |
|
74 } |
|
75 |
|
76 TInt CPanAgentFactory::Info(TNifAgentInfo& aInfo, TInt /*aIndex*/) const |
|
77 /** |
|
78 * Retrieve information about this agent |
|
79 * @param aInfo |
|
80 * @param aIndex |
|
81 */ |
|
82 { |
|
83 LOG_FUNC |
|
84 aInfo.iName = KPanAgentName; |
|
85 aInfo.iVersion = TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber); |
|
86 return KErrNone; |
|
87 } |
|
88 |
|
89 // |
|
90 // PAN agent |
|
91 // |
|
92 |
|
93 CPanAgent* CPanAgent::NewL() |
|
94 /** |
|
95 Return a newly constuct PAN agent |
|
96 */ |
|
97 { |
|
98 LOG_STATIC_FUNC |
|
99 CPanAgent* self = new(ELeave) CPanAgent(); |
|
100 CleanupStack::PushL(self); |
|
101 self->ConstructL(); |
|
102 CleanupStack::Pop(self); |
|
103 return(self); |
|
104 } |
|
105 |
|
106 CPanAgent::CPanAgent() |
|
107 /** |
|
108 Do nothing |
|
109 */ |
|
110 { |
|
111 CONNECT_LOGGER |
|
112 LOG_FUNC |
|
113 |
|
114 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
115 NM_LOG_NODE_CREATE(KPanAgtSubTag, CPanAgent); |
|
116 #endif |
|
117 } |
|
118 |
|
119 void CPanAgent::ConstructL() |
|
120 /** |
|
121 |
|
122 */ |
|
123 { |
|
124 LOG_FUNC |
|
125 CAgentBase::ConstructL(); |
|
126 |
|
127 iDeviceSelector = new (ELeave) CPanRemoteDeviceSelector(*this, *iDatabase); |
|
128 |
|
129 iInitiateDisconnectCallback = new (ELeave) CAsyncCallBack(KPanAgtAoPriority); |
|
130 |
|
131 TCallBack initiateDisconnectCallback(InitiateDisconnectCb, this); |
|
132 iInitiateDisconnectCallback->Set(initiateDisconnectCallback); |
|
133 |
|
134 // Create local SDP helper instance. |
|
135 iPanLocalSdpRegistrar = CPanHelperLocalSdpRegistrar::NewL(); |
|
136 |
|
137 iState = CPanAgtStateUninitialised::NewL(*this); |
|
138 iShutdownState = CPanAgtStateShutdown::NewL(*this); |
|
139 |
|
140 //If CPanCoexistenceConnectionController::NewL leaves, PAN still can be started as usual |
|
141 TRAP_IGNORE(iPanCoexistenceConnectionController = CPanCoexistenceConnectionController::NewL(*this)); |
|
142 __ASSERT_DEBUG(iPanCoexistenceConnectionController, PanAgentPanic(ECreatePanCoexistenceConnectionControllerFailed)); |
|
143 |
|
144 |
|
145 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
146 // Register with comms transport to be able to receive our |
|
147 // custom PAN/BNEP messages |
|
148 TPanMessage::RegisterL(); |
|
149 #endif |
|
150 } |
|
151 |
|
152 CPanAgent::~CPanAgent() |
|
153 /** |
|
154 Tidy up after ourselves |
|
155 */ |
|
156 { |
|
157 LOG_FUNC |
|
158 |
|
159 __ASSERT_DEBUG(Devices().Count()==0, PanAgentPanic(EPanAgentDeletedWithDevicesStillAttached)); |
|
160 |
|
161 delete iPanLocalSdpRegistrar; |
|
162 |
|
163 iRemoteDevices.ResetAndDestroy(); |
|
164 |
|
165 if (iShutdownState != iState) |
|
166 { |
|
167 // something strange happened here, shutdown state not the last used state |
|
168 __ASSERT_DEBUG(EFalse, PanAgentPanic(EShutdownStateNotLastState)); |
|
169 |
|
170 delete iShutdownState; |
|
171 iShutdownState = NULL; |
|
172 } |
|
173 |
|
174 delete iState; |
|
175 iState = NULL; |
|
176 |
|
177 if(iDeviceSelector) |
|
178 { |
|
179 iDeviceSelector->Cancel(); |
|
180 delete iDeviceSelector; |
|
181 iDeviceSelector = NULL; |
|
182 } |
|
183 |
|
184 if(iPanCoexistenceConnectionController) |
|
185 { |
|
186 delete iPanCoexistenceConnectionController; |
|
187 iPanCoexistenceConnectionController = NULL; |
|
188 } |
|
189 |
|
190 if(iIncomingConnectionListener) // if we haven't deleted it already... |
|
191 { |
|
192 // make sure we stopped it |
|
193 __ASSERT_DEBUG(!(iIncomingConnectionListener->IsActive()), PanAgentPanic(EIncomingConnectionListenerStillActiveAtShutdown)); |
|
194 iIncomingConnectionListener->Cancel(); // recover in release builds |
|
195 delete iIncomingConnectionListener; |
|
196 iIncomingConnectionListener = NULL; |
|
197 } |
|
198 |
|
199 iInitiateDisconnectCallback->Cancel(); |
|
200 delete iInitiateDisconnectCallback; |
|
201 iInitiateDisconnectCallback = NULL; |
|
202 |
|
203 delete iDeviceSelector; |
|
204 iDeviceSelector = NULL; |
|
205 |
|
206 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
207 // De-register with the comms transport |
|
208 TPanMessage::DeRegister(); |
|
209 NM_LOG_NODE_DESTROY(KPanAgtSubTag, CPanAgent); |
|
210 #endif |
|
211 CLOSE_LOGGER |
|
212 } |
|
213 |
|
214 void CPanAgent::Connect(TAgentConnectType aType) |
|
215 /** |
|
216 Start the connection in an appropriate mode, depending on the settings in commdb |
|
217 */ |
|
218 { |
|
219 LOG_FUNC |
|
220 LOG1(_L("CPanAgent::Connect(TAgentConnectType[%d])"), aType); |
|
221 |
|
222 //The IAP must be incoming if we get a reconnect |
|
223 if(aType==EAgentStartDialIn || aType==EAgentReconnect) |
|
224 { |
|
225 SetSuppressOutgoing(); |
|
226 } |
|
227 |
|
228 iError = KErrNone; // make sure iError is reset before entering ConnectComplete |
|
229 iState->Connect(); |
|
230 } |
|
231 |
|
232 void CPanAgent::Connect(TAgentConnectType aType, CStoreableOverrideSettings* aOverrideSettings) |
|
233 /** |
|
234 Pass the override settings to base class, and perform a normal start |
|
235 */ |
|
236 { |
|
237 LOG_FUNC |
|
238 LOG1(_L("CPanAgent::Connect(TAgentConnectType[%d] + CStoreableOverrideSettings)"), aType); |
|
239 |
|
240 TRAPD(err, SetOverridesL(aOverrideSettings)); |
|
241 if(err) // if we can't store the overrides, then tell nifman and abort the connect |
|
242 { |
|
243 iError = err; |
|
244 iState->Connect(); |
|
245 return; |
|
246 } |
|
247 Connect(aType); |
|
248 } |
|
249 |
|
250 void CPanAgent::CancelConnect() |
|
251 /** |
|
252 Cancel the ServiceStarted callback - this will prevent the agent starting |
|
253 */ |
|
254 { |
|
255 LOG_FUNC |
|
256 iState->CancelConnect(); |
|
257 } |
|
258 |
|
259 void CPanAgent::ServiceStarted() |
|
260 /** |
|
261 @note We can't handle any error conditions here, as nifman doesn't allow us to signal them until |
|
262 we call ConnectComplete |
|
263 */ |
|
264 { |
|
265 LOG_FUNC |
|
266 __ASSERT_ALWAYS(iNotify, PanAgentPanic(ENullNifmanNotifyPointer)); |
|
267 LOG1(_L("CPanAgent: Service started with error %d"), iError); |
|
268 iNotify->ServiceStarted(); // trigger loading of nif and packet driver |
|
269 } |
|
270 |
|
271 void CPanAgent::ConnectComplete() |
|
272 /** |
|
273 Get the BNEP control interface handle, and create the initial state |
|
274 */ |
|
275 { |
|
276 LOG_FUNC |
|
277 __ASSERT_ALWAYS(iNotify, PanAgentPanic(ENullNifmanNotifyPointer)); |
|
278 LOG1(_L("CPanAgent: entered ConnectComplete with error %d"), iError); |
|
279 |
|
280 if(!iError) // if everything's OK, then get the handle to the BNEP control interface |
|
281 { |
|
282 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
283 CPanProvisionInfo* provisionInfo=NULL; |
|
284 iError = iNotify->Notification((TAgentToNifEventType)EPanAgentToNifGetPanProvisionInfo, static_cast<TAny*>(&provisionInfo)); |
|
285 |
|
286 // If this assert fails check your commdb. It probably means that a non-399 commdb |
|
287 // has been imported and is using the basic Ethernet MCPR rather than the Pan |
|
288 // Ethernet MCPR |
|
289 __ASSERT_ALWAYS(provisionInfo && provisionInfo->BnepConnectionMgr() != Messages::TNodeId::NullId(), PanAgentPanic(ENullBnepConnectionManager)); |
|
290 iBnepConnectionManager = provisionInfo->BnepConnectionMgr(); |
|
291 |
|
292 #else |
|
293 // !SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
294 |
|
295 // Get the handle to the nif's connection manager |
|
296 LOG(_L("CPanAgent: Getting handle to BNEP control interface...")); |
|
297 TBnepConnectionManager bnepConnectionManager; |
|
298 iError = iNotify->Notification((TAgentToNifEventType)EPanAgentToNifGetConnectionManager, static_cast<TAny*>(&bnepConnectionManager)); |
|
299 if(iError == KErrNone) |
|
300 { |
|
301 iBnepConnectionManager = bnepConnectionManager.iBnepConnectionManager; |
|
302 __ASSERT_ALWAYS(iBnepConnectionManager, PanAgentPanic(ENullBnepConnectionManager)); |
|
303 } |
|
304 #endif |
|
305 // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
306 } |
|
307 |
|
308 if (iError == KErrNone) |
|
309 { |
|
310 LOG(_L("CPanAgent: ...got handle successfully")); |
|
311 delete iState; |
|
312 iState = NULL; |
|
313 CPanAgtStateBase* initialState = NULL; |
|
314 TRAP(iError, initialState = CPanAgentStateInitialising::NewL(*this)); |
|
315 if(!iError) |
|
316 { |
|
317 SetState(*initialState); // this may set iError if there is a problem during initialising |
|
318 } |
|
319 } |
|
320 |
|
321 if(iError) |
|
322 { |
|
323 iNotify->AgentProgress(EPanAgtIdle, iError); |
|
324 } |
|
325 else |
|
326 { |
|
327 iNifmanConnected = ETrue; |
|
328 iNotify->AgentProgress(EPanAgtConnected, KErrNone); |
|
329 } |
|
330 |
|
331 LOG1(_L("CPanAgent: calling nifman ConnectComplete with error %d)"), iError); |
|
332 iNotify->ConnectComplete(iError); |
|
333 } |
|
334 |
|
335 void CPanAgent::Reconnect() |
|
336 /** |
|
337 Reset state and asynchronously send reconnect complete back, if |
|
338 the IAP is incoming |
|
339 */ |
|
340 { |
|
341 LOG_FUNC |
|
342 if(AllowIncoming()) |
|
343 { |
|
344 delete iState; |
|
345 iState = NULL; |
|
346 CPanAgtStateBase* reconState = NULL; |
|
347 TRAP(iError, reconState= CPanAgtStateReconnect::NewL(*this)); |
|
348 if(!iError) |
|
349 { |
|
350 SetState(*reconState); |
|
351 } |
|
352 } |
|
353 } |
|
354 |
|
355 void CPanAgent::ReconnectComplete(TInt aErr) |
|
356 { |
|
357 LOG_FUNC |
|
358 iNotify->ReconnectComplete(aErr); |
|
359 } |
|
360 |
|
361 void CPanAgent::CancelReconnect() |
|
362 /** |
|
363 |
|
364 */ |
|
365 { |
|
366 LOG_FUNC |
|
367 iState->CancelReconnect(); |
|
368 } |
|
369 |
|
370 void CPanAgent::InitiateDisconnect() |
|
371 /** |
|
372 Perform an agent initiated disconnect |
|
373 @note Any code in the agent that wants to trigger a disconnect should call RequestDisconnect(), |
|
374 which will call this method via an async callback. |
|
375 @note This call will loop back into the agent because nifman will call the Disconnect() method itself. |
|
376 */ |
|
377 { |
|
378 LOG_FUNC |
|
379 __ASSERT_DEBUG(iNifmanConnected, PanAgentPanic(EAttemptToDisconnectBeforeConnectComplete)); |
|
380 LOG1(_L("CPanAgent: InitiateDisconnect with error %d"), iError); |
|
381 |
|
382 iNotify->AgentProgress(EPanAgtDisconnecting, iError); |
|
383 iNotify->AgentEvent(EAgentOriginatedConnectionCommand, EAgentConnectionCommandStop, TPckg<TInt>(KErrDisconnected)); |
|
384 } |
|
385 |
|
386 void CPanAgent::Disconnect(TInt aReason) |
|
387 /** |
|
388 Disconnect called from nifman (this can be triggered by the idle timers, the client, or us |
|
389 requesting a disconnect using RequestDisconnect()). |
|
390 This method will cause us to go to the shutdown state in the role state machine, which will |
|
391 shut everything else down (ie. the remote device state machines). |
|
392 @note This is the one case where a state transition can occur that is not triggered by a state |
|
393 itself (because two of the three reasons for this method being called are events external to |
|
394 PAN agent, and those events turn up here first, and are not passed to a state; instead they |
|
395 trigger the state transition directly) |
|
396 */ |
|
397 { |
|
398 LOG_FUNC |
|
399 LOG1(_L("CPanAgent: Disconnect with error %d"), aReason); |
|
400 |
|
401 iError = aReason; |
|
402 |
|
403 // now make shutdown the active state |
|
404 delete iState; // we have to do this now, otherwise we lose the pointer |
|
405 iState = NULL; // to prevent any mistakes being made... |
|
406 SetState(*iShutdownState); // shutdown is complete when ShutdownComplete() is called by the shutdown state |
|
407 } |
|
408 |
|
409 void CPanAgent::FullShutdownComplete() |
|
410 /** |
|
411 Once all devices have reported to the shutdown state that they are disconnected, this method |
|
412 is called and the agent can disconnect |
|
413 */ |
|
414 { |
|
415 LOG_FUNC |
|
416 LOG(_L("CPanAgent: Shutdown complete, signalling nifman with DisconnectComplete()")); |
|
417 |
|
418 // then tell nifman we've disconnected |
|
419 iNotify->AgentProgress(EPanAgtDisconnected, KErrNone); |
|
420 iNifmanConnected = EFalse; |
|
421 iNotify->DisconnectComplete(); |
|
422 } |
|
423 |
|
424 TInt CPanAgent::InitiateDisconnectCb(TAny* aThisPtr) |
|
425 /** |
|
426 Initiate disconnect callback static method |
|
427 */ |
|
428 { |
|
429 LOG_STATIC_FUNC |
|
430 __ASSERT_DEBUG(aThisPtr, PanAgentPanic(ENullTAnyPointer)); |
|
431 |
|
432 CPanAgent* self = static_cast<CPanAgent*>(aThisPtr); |
|
433 self->InitiateDisconnect(); |
|
434 return KErrNone; |
|
435 } |
|
436 |
|
437 void CPanAgent::Info(TNifAgentInfo& aInfo) const |
|
438 /** |
|
439 * Information about this Agent |
|
440 * |
|
441 * @param aInfo on return contains information about the agent |
|
442 */ |
|
443 { |
|
444 LOG_FUNC |
|
445 aInfo.iName = KPanAgentName; |
|
446 aInfo.iName.AppendFormat(_L("-AgentFactory[0x%08x]"), this); |
|
447 aInfo.iVersion = TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); |
|
448 } |
|
449 |
|
450 TInt CPanAgent::Control(TUint aOptionLevel, TUint aOptionName, TDes8& aOption) |
|
451 /** |
|
452 Various agent specific options |
|
453 */ |
|
454 { |
|
455 LOG_FUNC |
|
456 if(aOptionLevel==KCOLAgent) |
|
457 { |
|
458 TBool listUplinkAccessDev = EFalse; |
|
459 |
|
460 switch(aOptionName) |
|
461 { |
|
462 case KCOGetAgentEMIPtr: // agent extended management interface getter |
|
463 { |
|
464 if(aOption.Length()!=sizeof(MNifAgentExtendedManagementInterface*)) |
|
465 { |
|
466 return KErrArgument; |
|
467 } |
|
468 aOption = TPckg<MNifAgentExtendedManagementInterface*>(this); |
|
469 return KErrNone; |
|
470 } |
|
471 |
|
472 case KCOAgentNotifyClientAttach: |
|
473 { |
|
474 TRAPD(err, SetupOutgoingConnectionsL()); //<@note This ignores the value of the iSuppressOutgoing flag and triggers the outgoing connections directly |
|
475 // as the outgoing connection suppression is only intended to be used when the agent is first told to Connect() |
|
476 // and not when the 2nd and subsequent clients attach to this connection |
|
477 return err; |
|
478 } |
|
479 |
|
480 case KCOAgentPanConnectDevice: |
|
481 { |
|
482 if(aOption.Length() != KBTDevAddrSize) |
|
483 { |
|
484 return KErrArgument; |
|
485 } |
|
486 |
|
487 TBTDevAddr remoteDeviceAddress(aOption); |
|
488 TRAPD(err, CreateNewConnectionForOutgoingL(remoteDeviceAddress)); |
|
489 return err; |
|
490 } |
|
491 |
|
492 case KCOAgentPanDisconnectDevice: |
|
493 { |
|
494 if(aOption.Length() != KBTDevAddrSize) |
|
495 { |
|
496 return KErrArgument; |
|
497 } |
|
498 |
|
499 TBTDevAddr remoteDeviceAddress(aOption); |
|
500 CPanRemoteDeviceStateMachine* remoteDevice = FindRemoteDeviceByAddress(remoteDeviceAddress); |
|
501 if(remoteDevice) |
|
502 { |
|
503 remoteDevice->Disconnect(); |
|
504 } |
|
505 else |
|
506 { |
|
507 return KErrNotFound; |
|
508 } |
|
509 |
|
510 return KErrNone; |
|
511 } |
|
512 |
|
513 case KCOAgentPanEnumerateUplinkAccessDevices: |
|
514 { |
|
515 //set the listing uplink access devices boolean to ETrue |
|
516 listUplinkAccessDev = ETrue; |
|
517 //the following code will branch based on the value of listUplinkAccessDev |
|
518 //fall through |
|
519 } |
|
520 |
|
521 case KCOAgentPanEnumerateDevices: |
|
522 { |
|
523 // Because the array passed to us here may be smaller than the number of active links |
|
524 // at this point, we shall return as much as possible in the array. |
|
525 |
|
526 // Also if the array has enough space for more addresses than we currently have, the |
|
527 // descriptor size will be changed to reflect reality. |
|
528 |
|
529 aOption.Zero(); |
|
530 |
|
531 TInt maxDevices = Min ( iRemoteDevices.Count(), |
|
532 aOption.MaxLength() / sizeof(TBTDevAddr)); |
|
533 |
|
534 TInt currentDevice = 0; |
|
535 TInt devicesStored = 0; // We only enumerate fully connected devices, so we need a separate counter |
|
536 |
|
537 while ((currentDevice < iRemoteDevices.Count()) && (devicesStored < maxDevices)) |
|
538 { |
|
539 TRemoteDeviceState state = iRemoteDevices[currentDevice]->GetState(); |
|
540 |
|
541 if(!listUplinkAccessDev && state != EIdle && state != EDisconnecting || |
|
542 iRemoteDevices[currentDevice]->UplinkAccessAllowed()) |
|
543 { |
|
544 TBTDevAddr devAddr = iRemoteDevices[currentDevice]->DevAddr(); |
|
545 TPckg<TBTDevAddr> pckg(devAddr); |
|
546 aOption.Append(pckg); |
|
547 devicesStored++; |
|
548 } |
|
549 |
|
550 currentDevice++; |
|
551 } |
|
552 |
|
553 return KErrNone; |
|
554 } |
|
555 |
|
556 default: |
|
557 { |
|
558 return KErrNotSupported; |
|
559 } |
|
560 } |
|
561 } |
|
562 return KErrNotSupported; |
|
563 } |
|
564 |
|
565 TInt CPanAgent::Notification(TNifToAgentEventType /*aEvent*/, TAny* /*aInfo*/) |
|
566 /** |
|
567 |
|
568 */ |
|
569 { |
|
570 LOG_FUNC |
|
571 return KErrNotSupported; |
|
572 } |
|
573 |
|
574 TInt CPanAgent::GetExcessData(TDes8& /*aDes*/) |
|
575 /** |
|
576 Unused in PAN profile |
|
577 */ |
|
578 { |
|
579 LOG_FUNC |
|
580 return KErrNotSupported; |
|
581 } |
|
582 |
|
583 TInt CPanAgent::IncomingConnectionReceived() |
|
584 /** |
|
585 Don't need to support this - it's for an older nif/agent model where incoming and outgoing connections can't be supported at the same time. This isn't the case in PAN profile. |
|
586 */ |
|
587 { |
|
588 LOG_FUNC |
|
589 return KErrNotSupported; |
|
590 } |
|
591 |
|
592 void CPanAgent::GetLastError(TInt& aError) |
|
593 { |
|
594 LOG_FUNC |
|
595 aError = KErrNotSupported; |
|
596 } |
|
597 |
|
598 TBool CPanAgent::IsReconnect() const |
|
599 { |
|
600 LOG_FUNC |
|
601 //Return false for now because it hasn't been used. We will only expose this information from |
|
602 //statemachine when there is a good reason. |
|
603 __DEBUGGER(); |
|
604 return EFalse; |
|
605 } |
|
606 |
|
607 void CPanAgent::MpccoPanCoexistenceConnectionUpdated(TIPBearerCoexistenceStatus aStatus) |
|
608 { |
|
609 LOG_FUNC |
|
610 |
|
611 switch (aStatus) |
|
612 { |
|
613 case ENoneIsActive: |
|
614 { |
|
615 // We will not register the sdp and open listen socket in shutdown state |
|
616 // Also check that we are not already listening |
|
617 if (iShutdownState != iState && !IsIncomingConnectionListenerEnabled()) |
|
618 { |
|
619 TRAPD(err, iState->StartListenerL()); |
|
620 if(err) |
|
621 { |
|
622 LOG1(_L("CPanAgent: MpccoPanCoexistenceConnectionUpdated open listener left with %d, shutting down all connections"), err); |
|
623 // If open listener failed, request to disconnect |
|
624 RequestDisconnect(err); |
|
625 } |
|
626 } |
|
627 } |
|
628 break; |
|
629 |
|
630 case ERndisIsActive: |
|
631 // Close listener and unregister SDP record since RNDIS is active |
|
632 iState->StopListener(); |
|
633 break; |
|
634 |
|
635 case EBTPanIsActive: |
|
636 // It maybe some funny things happened here |
|
637 __ASSERT_DEBUG(EFalse, PanAgentPanic(EIPBearerCoexistancePropertyShouldnotBePanIsActive)); |
|
638 break; |
|
639 |
|
640 default: |
|
641 __ASSERT_DEBUG(EFalse, PanAgentPanic(EInvalidIPBearerCoexistanceProperty)); |
|
642 break; |
|
643 } |
|
644 } |
|
645 // |
|
646 // PAN agent accessor methods |
|
647 // |
|
648 |
|
649 RPointerArray<CPanRemoteDeviceStateMachine>& CPanAgent::Devices() |
|
650 /** |
|
651 Return a handle to the connection array |
|
652 @return A reference to the device array held by the state machine |
|
653 */ |
|
654 { |
|
655 LOG_FUNC |
|
656 return(iRemoteDevices); |
|
657 } |
|
658 |
|
659 const RPointerArray<CPanRemoteDeviceStateMachine>& CPanAgent::Devices() const |
|
660 /** |
|
661 Return a const handle to the connection array |
|
662 @return A const reference to the device array held by the state machine |
|
663 */ |
|
664 { |
|
665 LOG_FUNC |
|
666 return(iRemoteDevices); |
|
667 } |
|
668 |
|
669 TBluetoothPanRole& CPanAgent::FixedLocalRole() |
|
670 /** |
|
671 Return a handle to the fixed local role field |
|
672 @return A reference to the fixed local role field in the state machine |
|
673 */ |
|
674 { |
|
675 LOG_FUNC |
|
676 return(iFixedLocalRole); |
|
677 } |
|
678 |
|
679 TBluetoothPanRole& CPanAgent::FixedRemoteRole() |
|
680 /** |
|
681 Return a handle to the fixed remote role field |
|
682 @return A reference to the fixed remote role field in the state machine |
|
683 */ |
|
684 { |
|
685 LOG_FUNC |
|
686 return(iFixedRemoteRole); |
|
687 } |
|
688 |
|
689 CCommsDbAccess& CPanAgent::Database() |
|
690 /** |
|
691 Return a handle to commdb |
|
692 @return A handle to commdb, with overrides masking the appropriate fields |
|
693 */ |
|
694 { |
|
695 LOG_FUNC |
|
696 __ASSERT_ALWAYS(iDatabase, PanAgentPanic(ENullCommdbHandle)); |
|
697 |
|
698 return(*iDatabase); |
|
699 } |
|
700 |
|
701 CPanHelperLocalSdpRegistrar& CPanAgent::PanLocalSdpRegistrar() |
|
702 /** |
|
703 |
|
704 */ |
|
705 { |
|
706 LOG_FUNC |
|
707 return *iPanLocalSdpRegistrar; |
|
708 } |
|
709 |
|
710 TInt CPanAgent::IapId() |
|
711 /** |
|
712 Return the IAP ID of this connection |
|
713 */ |
|
714 { |
|
715 LOG_FUNC |
|
716 TUint32 iapId = 0; // initialise to zero to keep VC6 compiler happy... |
|
717 TRAPD(err, Database().GetIntL(TPtrC(IAP), TPtrC(COMMDB_ID), iapId)); |
|
718 if(err) |
|
719 { |
|
720 LOG1(_L("CPanAgent: could not retrieve IAP ID, error %d"), err); |
|
721 return err; |
|
722 } |
|
723 else |
|
724 { |
|
725 return iapId; |
|
726 } |
|
727 } |
|
728 |
|
729 TBool CPanAgent::SuppressOutgoing() const |
|
730 /** |
|
731 Find out if outgoing connections are suppressed |
|
732 */ |
|
733 { |
|
734 LOG_FUNC |
|
735 return(iSuppressOutgoing); |
|
736 } |
|
737 |
|
738 |
|
739 // |
|
740 // PAN agent do-er methods |
|
741 // |
|
742 |
|
743 void CPanAgent::SetSuppressOutgoing() |
|
744 /** |
|
745 Suppress outgoing connections |
|
746 */ |
|
747 { |
|
748 LOG_FUNC |
|
749 iSuppressOutgoing = ETrue; |
|
750 } |
|
751 |
|
752 void CPanAgent::ResetSuppressOutgoing() |
|
753 /** |
|
754 Stop outgoing connections being suppressed |
|
755 */ |
|
756 { |
|
757 LOG_FUNC |
|
758 iSuppressOutgoing = EFalse; |
|
759 } |
|
760 |
|
761 void CPanAgent::SendProgress(TInt aProgress, TInt aError) |
|
762 /** |
|
763 Send progress values to nifman |
|
764 NOTE nifman will ditch duplicate notifications, same progress, same error |
|
765 We can't change this so to avoid this for connection and disconnection progress notifications |
|
766 we will send a role notification after the connect/disconnect |
|
767 */ |
|
768 { |
|
769 LOG_FUNC |
|
770 __ASSERT_ALWAYS(iNotify, PanAgentPanic(ENullNifmanNotifyPointer)); |
|
771 |
|
772 LOG2(_L("CPanAgent: sending progress value to connection; stage %d, error %d"), aProgress, aError); |
|
773 iNotify->AgentProgress(aProgress, aError); |
|
774 |
|
775 switch (aProgress) |
|
776 { |
|
777 case EPanAgtInitialising: |
|
778 { |
|
779 LOG(_L("CPanAgent: Progress value EPanAgtInitialising")); |
|
780 break; |
|
781 } |
|
782 case EPanAgtConnected: |
|
783 { |
|
784 LOG(_L("CPanAgent: Progress value EPanAgtConnected")); |
|
785 break; |
|
786 } |
|
787 case EPanAgtIdle: |
|
788 { |
|
789 LOG(_L("CPanAgent: Progress value EPanAgtIdle")); |
|
790 break; |
|
791 } |
|
792 case EPanAgtListening: |
|
793 { |
|
794 LOG(_L("CPanAgent: Progress value EPanAgtListening")); |
|
795 break; |
|
796 } |
|
797 case EPanAgtURole: |
|
798 { |
|
799 // DANGER Don't EVER put StateSendRoleNotification in here - endless loop |
|
800 LOG(_L("CPanAgent: Progress value EPanAgtURole")); |
|
801 break; |
|
802 } |
|
803 case EPanAgtGnRole: |
|
804 { |
|
805 // DANGER Don't EVER put StateSendRoleNotification in here - endless loop |
|
806 LOG(_L("CPanAgent: Progress value EPanAgtGnRole")); |
|
807 break; |
|
808 } |
|
809 case EPanAgtNapRole: |
|
810 { |
|
811 // DANGER Don't EVER put StateSendRoleNotification in here - endless loop |
|
812 LOG(_L("CPanAgent: Progress value EPanAgtNapRole")); |
|
813 break; |
|
814 } |
|
815 case EPanAgtConnectedNewDevice: |
|
816 { |
|
817 LOG(_L("CPanAgent: Progress value EPanAgtConnectedNewDevice")); |
|
818 // Get the state to send a role notification if its in a sensible state |
|
819 // This has 2 beneficial effects. |
|
820 // a) We send the role to the layers above so they know |
|
821 // b) We never have the situation where we are sending 2 connects or 2 disconnects |
|
822 // one after the other, this stops comms filtering the notification out |
|
823 iState->StateSendRoleNotification(); |
|
824 |
|
825 break; |
|
826 } |
|
827 case EPanAgtDisconnectedDevice: |
|
828 { |
|
829 LOG(_L("CPanAgent: Progress value EPanAgtDisconnectedDevice")); |
|
830 // Get the state to send a role notification if its in a sensible state |
|
831 // This has 2 beneficial effects. |
|
832 // a) We send the role to the layers above so they know |
|
833 // b) We never have the situation where we are sending 2 connects or 2 disconnects |
|
834 // one after the other, this stops comms filtering the notification out |
|
835 iState->StateSendRoleNotification(); |
|
836 |
|
837 break; |
|
838 } |
|
839 case EPanAgtReconfiguringPiconet: |
|
840 { |
|
841 LOG(_L("CPanAgent: Progress value EPanAgtReconfiguringPiconet")); |
|
842 break; |
|
843 } |
|
844 case EPanAgtUplinkRequired: |
|
845 { |
|
846 LOG(_L("CPanAgent: Progress value EPanAgtUplinkRequired")); |
|
847 break; |
|
848 } |
|
849 case EPanAgtUplinkNotRequired: |
|
850 { |
|
851 LOG(_L("CPanAgent: Progress value EPanAgtUplinkNotRequired")); |
|
852 break; |
|
853 } |
|
854 case EPanAgtDisconnecting: |
|
855 { |
|
856 LOG(_L("CPanAgent: Progress value EPanAgtDisconnecting")); |
|
857 break; |
|
858 } |
|
859 case EPanAgtDisconnected: |
|
860 { |
|
861 LOG(_L("CPanAgent: Progress value EPanAgtDisconnected")); |
|
862 break; |
|
863 } |
|
864 case EPanAgtNoResourceForPanConnection: |
|
865 { |
|
866 LOG(_L("CPanAgent: Progress value EPanAgtNoResourceForPanConnection")); |
|
867 // We are lack of the network resource to setup the PAN connection, mainly caused by the RNDIS which |
|
868 // is already occupied the IP resource |
|
869 break; |
|
870 } |
|
871 default: |
|
872 { |
|
873 LOG(_L("CPanAgent: Progress value UNKNOWN")); |
|
874 break; |
|
875 } |
|
876 } |
|
877 |
|
878 LOG(_L("CPanAgent: <<Progress SENT")); |
|
879 } |
|
880 |
|
881 |
|
882 TInt CPanAgent::StartIncomingConnectionListener() |
|
883 /** |
|
884 Start the incoming connection listener |
|
885 @return KErrNone if successful; otherwise one of the Symbian standard error codes |
|
886 */ |
|
887 { |
|
888 LOG_FUNC |
|
889 TInt rerr = KErrNone; |
|
890 if(!iIncomingConnectionListener) |
|
891 { |
|
892 TRAP(rerr, iIncomingConnectionListener = CPanIncomingConnectionListener::NewL(*this)); |
|
893 } |
|
894 return rerr; |
|
895 } |
|
896 |
|
897 void CPanAgent::CloseIncomingConnectionListener() |
|
898 /** |
|
899 Stop and delete the incoming connection listener |
|
900 */ |
|
901 { |
|
902 LOG_FUNC |
|
903 if(!iIncomingConnectionListener) // if the incoming connection listener isn't active, then return immediately |
|
904 { |
|
905 return; |
|
906 } |
|
907 |
|
908 iIncomingConnectionListener->Cancel(); // cancel outstanding accept |
|
909 delete iIncomingConnectionListener; |
|
910 iIncomingConnectionListener = NULL; |
|
911 } |
|
912 |
|
913 void CPanAgent::SetupOutgoingConnectionsL() |
|
914 /** |
|
915 Begin the process of setting up any outgoing connections that we need |
|
916 */ |
|
917 { |
|
918 LOG_FUNC |
|
919 __ASSERT_ALWAYS(iDeviceSelector, PanAgentPanic(ENullDeviceSelector)); |
|
920 |
|
921 LOG(_L("Agent: Asked to bring new device(s) into the PAN")); |
|
922 if (iRemoteDevices.Count()) |
|
923 { |
|
924 TBluetoothPanRole remoteRole = iRemoteDevices[0]->RemoteRole(); |
|
925 if (remoteRole == EPanRoleNap) |
|
926 { |
|
927 LOG(_L("Agent: Already connected to a NAP, aborting.")); |
|
928 return; |
|
929 } |
|
930 } |
|
931 |
|
932 // start the process of connecting any remote devices |
|
933 iDeviceSelector->PerformRemoteDeviceSelectionL(); |
|
934 } |
|
935 |
|
936 // |
|
937 // PAN agent getter methods |
|
938 // |
|
939 |
|
940 TBool CPanAgent::IsIncomingConnectionListenerEnabled() const |
|
941 /** |
|
942 Is the incoming connection listener active? |
|
943 @return Whether the listener is active or not |
|
944 */ |
|
945 { |
|
946 LOG_FUNC |
|
947 return (iIncomingConnectionListener ? ETrue : EFalse); |
|
948 } |
|
949 |
|
950 TBool CPanAgent::IsPromptingUserForDeviceSelection() const |
|
951 /** |
|
952 Is the user being shown the device selection notifier? |
|
953 */ |
|
954 { |
|
955 LOG_FUNC |
|
956 return (iDeviceSelector ? iDeviceSelector->IsPrompting() : EFalse); |
|
957 } |
|
958 |
|
959 TBool CPanAgent::IsUAllowedByFixedLocalRole() const |
|
960 /** |
|
961 Is U role allowed by settings in commdb? |
|
962 */ |
|
963 { |
|
964 LOG_FUNC |
|
965 return ((iFixedLocalRole==EPanRoleUnknown) || (iFixedLocalRole==EPanRoleU)); |
|
966 } |
|
967 |
|
968 TBool CPanAgent::IsGnAllowedByFixedLocalRole() const |
|
969 /** |
|
970 Is GN role allowed by settings in commdb? |
|
971 */ |
|
972 { |
|
973 LOG_FUNC |
|
974 return ((iFixedLocalRole==EPanRoleUnknown) || (iFixedLocalRole==EPanRoleGn)); |
|
975 } |
|
976 |
|
977 TBool CPanAgent::IsNapAllowedByFixedLocalRole() const |
|
978 /** |
|
979 Is NAP role allowed by settings in commdb? |
|
980 @note For now, because we don't support NAP, we're just going to return false here |
|
981 */ |
|
982 { |
|
983 LOG_FUNC |
|
984 return EFalse; |
|
985 } |
|
986 |
|
987 // |
|
988 // PAN agent setter methods |
|
989 // |
|
990 |
|
991 void CPanAgent::SetState(CPanAgtStateBase& aState) |
|
992 /** |
|
993 Set the current state in the state machine |
|
994 */ |
|
995 { |
|
996 LOG_FUNC |
|
997 iState = &aState; |
|
998 TRAPD(err, iState->OnEntryL()); |
|
999 if(err) |
|
1000 { |
|
1001 LOG1(_L("CPanAgent: OnEntry to a state left with %d, shutting down all connections"), err); |
|
1002 RequestDisconnect(err); |
|
1003 } |
|
1004 } |
|
1005 |
|
1006 // |
|
1007 // Connection creator methods |
|
1008 // |
|
1009 |
|
1010 void CPanAgent::CreateNewConnectionFromIncomingL(RInternalSocket& aConnectedSocket) |
|
1011 /** |
|
1012 Create a new connection from an incoming socket |
|
1013 @note All the role negotiation for this new connection is handled by the PAN remote connection class |
|
1014 @param aConnectedSocket A connected L2CAP socket, ready for hand off to BNEP |
|
1015 @return KErrNone if successful; otherwise one of the Symbian standard error codes |
|
1016 */ |
|
1017 { |
|
1018 LOG_FUNC |
|
1019 __ASSERT_ALWAYS(iDatabase, PanAgentPanic(ENullCommdbHandle)); |
|
1020 |
|
1021 TBTSockAddr sockAddr; |
|
1022 aConnectedSocket.RemoteName(sockAddr); |
|
1023 CheckDeviceIsNotAlreadyAttachedL(sockAddr.BTAddr()); |
|
1024 CPanRemoteDeviceStateMachine* newRemDev = CPanRemoteDeviceStateMachine::NewL(aConnectedSocket, *this, *iDatabase); |
|
1025 CleanupStack::PushL(newRemDev); |
|
1026 User::LeaveIfError(iRemoteDevices.Append(newRemDev)); |
|
1027 CleanupStack::Pop(newRemDev); |
|
1028 } |
|
1029 |
|
1030 void CPanAgent::CreateNewConnectionForOutgoingL(const TBTDevAddr& aRemDevAddr) |
|
1031 /** |
|
1032 Create a new connection to a remote device |
|
1033 @note Can be called from outgoing connection creator, or from Control() call |
|
1034 @param aRemDevAddr The address of the remote device to connect to |
|
1035 */ |
|
1036 { |
|
1037 LOG_FUNC |
|
1038 |
|
1039 // Check that a new PAN connection can be established at this time. |
|
1040 TInt err = TryToCreateNewPanConnection(); |
|
1041 |
|
1042 if (err != KErrNone) |
|
1043 { |
|
1044 LOG1(_L("CPanAgent::CreateNewConnectionForOutgoingL - TryToCreateNewPanConnection returns %d"), err); |
|
1045 |
|
1046 // No resource is available and send a progress notification |
|
1047 SendProgress(EPanAgtNoResourceForPanConnection, err); |
|
1048 User::Leave(err); |
|
1049 } |
|
1050 |
|
1051 CheckDeviceIsNotAlreadyAttachedL(aRemDevAddr); |
|
1052 CPanRemoteDeviceStateMachine* newRemDev = CPanRemoteDeviceStateMachine::NewL(aRemDevAddr, *this, *iDatabase); |
|
1053 CleanupStack::PushL(newRemDev); |
|
1054 User::LeaveIfError(iRemoteDevices.Append(newRemDev)); |
|
1055 CleanupStack::Pop(newRemDev); |
|
1056 } |
|
1057 |
|
1058 TInt CPanAgent::DeviceSelectionError(TInt aErr) |
|
1059 /** |
|
1060 There has been an error during remote device selection |
|
1061 @note This might break if the first device from set of devices causes an error, but the rest |
|
1062 would start correctly if given a chance. However, it's unlikely - any error affecting one device |
|
1063 is likely to affect them all |
|
1064 */ |
|
1065 { |
|
1066 LOG_FUNC |
|
1067 LOG1(_L("CPanAgent: outgoing connection starter signalled error %d..."), aErr); |
|
1068 // should this be passed on to the state? |
|
1069 // Maybe, it depends on how complicated we want to make the logic - currently states |
|
1070 // have very limited knowledge of the connection starter (only in the state base class) - |
|
1071 // perhaps we should keep it that way? |
|
1072 if(iRemoteDevices.Count()) // there are other devices in the array, so carry on |
|
1073 { |
|
1074 LOG(_L("CPanAgent: ...devices in array, ignoring error")); |
|
1075 return KErrNone; |
|
1076 } |
|
1077 else // no other devices in the array, so check we're not listening, then shutdown |
|
1078 { |
|
1079 if(IsIncomingConnectionListenerEnabled()) // do nothing |
|
1080 { |
|
1081 LOG(_L("CPanAgent: ...no devices in array, but incoming connection listener active, ignoring error")); |
|
1082 return KErrNone; |
|
1083 } |
|
1084 else |
|
1085 { |
|
1086 LOG(_L("CPanAgent: ...no devices in array and no incoming connection listener active, shutting down")); |
|
1087 RequestDisconnect(aErr); |
|
1088 return KErrDisconnected; |
|
1089 } |
|
1090 } |
|
1091 } |
|
1092 |
|
1093 // |
|
1094 // Methods handled by each state |
|
1095 // |
|
1096 |
|
1097 |
|
1098 TInt CPanAgent::InitiateOutgoingConnection(TBluetoothPanRole& aLocalRole, TBluetoothPanRole& aRemoteRole, TPanDeviceWorthTryingRolesList& aWorthTryingRemoteRoles) |
|
1099 { |
|
1100 LOG_FUNC |
|
1101 __ASSERT_ALWAYS(iState, PanAgentPanic(ENoState)); |
|
1102 |
|
1103 TRAPD(err, iState->InitiateOutgoingConnectionL(aLocalRole, aRemoteRole, aWorthTryingRemoteRoles)); |
|
1104 return err; |
|
1105 } |
|
1106 |
|
1107 TInt CPanAgent::PerformLocalRoleChangeRequest(TBluetoothPanRole& aLocalRole, TBluetoothPanRole& aRemoteRole) |
|
1108 { |
|
1109 LOG_FUNC |
|
1110 __ASSERT_ALWAYS(iState, PanAgentPanic(ENoState)); |
|
1111 |
|
1112 TRAPD(err, iState->PerformLocalRoleChangeRequestL(aLocalRole, aRemoteRole)); |
|
1113 return err; |
|
1114 } |
|
1115 |
|
1116 TInt CPanAgent::RoleChangeRequestFromPeer(TBluetoothPanRole aLocalRole, TBluetoothPanRole aRemoteRole) |
|
1117 { |
|
1118 LOG_FUNC |
|
1119 __ASSERT_ALWAYS(iState, PanAgentPanic(ENoState)); |
|
1120 |
|
1121 TInt ret = iState->IsRoleRequestValid(aLocalRole, aRemoteRole); |
|
1122 if(ret == KErrNone) |
|
1123 { |
|
1124 // Check that the local service requested is currently supported. |
|
1125 if((iNapEnabled && aLocalRole == EPanRoleGn) || |
|
1126 (!iNapEnabled && aLocalRole == EPanRoleNap) ) |
|
1127 { |
|
1128 ret = KErrInvalidOrUnacceptableRoleCombination; |
|
1129 } |
|
1130 // Check that the request is permitted by the fixed roles |
|
1131 else if((FixedLocalRole() != EPanRoleUnknown && |
|
1132 FixedLocalRole() != aLocalRole) || |
|
1133 (FixedRemoteRole() != EPanRoleUnknown && |
|
1134 FixedRemoteRole() != aRemoteRole)) |
|
1135 { |
|
1136 ret = KErrInvalidOrUnacceptableRoleCombination; |
|
1137 } |
|
1138 else |
|
1139 { |
|
1140 // Check that the connection can co-exist with current connections and that the |
|
1141 // state machine can accept the conection at this time. |
|
1142 TRAP(ret, iState->RoleChangeRequestFromPeerL(aLocalRole)); |
|
1143 } |
|
1144 } |
|
1145 return ret; |
|
1146 } |
|
1147 |
|
1148 TInt CPanAgent::IncomingConnectionFromPeer(TBluetoothPanRole aLocalRole, TBluetoothPanRole aRemoteRole) |
|
1149 { |
|
1150 LOG_FUNC |
|
1151 __ASSERT_ALWAYS(iState, PanAgentPanic(ENoState)); |
|
1152 |
|
1153 // Check that a new PAN connection can be established at this time. |
|
1154 TInt ret = TryToCreateNewPanConnection(); |
|
1155 |
|
1156 if (ret != KErrNone) |
|
1157 { |
|
1158 LOG1(_L("CPanAgent::IncomingConnectionFromPeer - TryToCreateNewPanConnection returns %d"), ret); |
|
1159 |
|
1160 // No resource is available and send a progress notification |
|
1161 SendProgress(EPanAgtNoResourceForPanConnection, ret); |
|
1162 } |
|
1163 else |
|
1164 { |
|
1165 ret = iState->IsRoleRequestValid(aLocalRole, aRemoteRole); |
|
1166 |
|
1167 if(ret == KErrNone) |
|
1168 { |
|
1169 // Check that the local service requested is currently supported. |
|
1170 if((iNapEnabled && aLocalRole == EPanRoleGn) || |
|
1171 (!iNapEnabled && aLocalRole == EPanRoleNap) ) |
|
1172 { |
|
1173 ret = KErrInvalidOrUnacceptableRoleCombination; |
|
1174 } |
|
1175 // Check that the request is permitted by the fixed roles |
|
1176 else if((FixedLocalRole() != EPanRoleUnknown && |
|
1177 FixedLocalRole() != aLocalRole) || |
|
1178 (FixedRemoteRole() != EPanRoleUnknown && |
|
1179 FixedRemoteRole() != aLocalRole)) |
|
1180 { |
|
1181 ret = KErrInvalidOrUnacceptableRoleCombination; |
|
1182 } |
|
1183 else |
|
1184 { |
|
1185 // Check that the connection can co-exist with current connections and that the |
|
1186 // state machine can accept the conection at this time. |
|
1187 TRAP(ret, iState->IncomingConnectionFromPeerL(aLocalRole)); |
|
1188 } |
|
1189 } |
|
1190 } |
|
1191 return ret; |
|
1192 } |
|
1193 |
|
1194 void CPanAgent::DeviceActive(CPanRemoteDeviceStateMachine& aNewConnection) |
|
1195 /** |
|
1196 Indicates that the given device has transitioned to the active state |
|
1197 */ |
|
1198 { |
|
1199 LOG_FUNC |
|
1200 __ASSERT_ALWAYS(iState, PanAgentPanic(ENoState)); |
|
1201 |
|
1202 TRAPD(err, iState->DeviceActiveL(aNewConnection)); |
|
1203 if(err) |
|
1204 { |
|
1205 LOG1(_L("CPanAgent: DeviceActive left with %d"), err); |
|
1206 RequestDisconnect(err); |
|
1207 } |
|
1208 else |
|
1209 { |
|
1210 // If this is a new device that has become active send a progress notification. |
|
1211 if(!aNewConnection.NewConnectedDeviceProgressSent()) |
|
1212 { |
|
1213 SendProgress(EPanAgtConnectedNewDevice, KErrNone); |
|
1214 aNewConnection.SetNewConnectedDeviceProgressSent(ETrue); |
|
1215 } |
|
1216 |
|
1217 // Check to see if an uplink access progress notification needs to be sent |
|
1218 SendUplinkAccessRequiredProgressNotification(); |
|
1219 } |
|
1220 iDeviceSelector->Reset(); |
|
1221 } |
|
1222 |
|
1223 void CPanAgent::DeviceRoleChangeFailed(CPanRemoteDeviceStateMachine& aDevice) |
|
1224 /** |
|
1225 Indicates that the given device failed to change role |
|
1226 @pre The device has been in the active state and is now renegotiating roles |
|
1227 */ |
|
1228 { |
|
1229 LOG_FUNC |
|
1230 __ASSERT_ALWAYS(iState, PanAgentPanic(ENoState)); |
|
1231 |
|
1232 TRAPD(err, iState->DeviceRoleChangeFailedL(aDevice)); |
|
1233 if(err) |
|
1234 { |
|
1235 LOG1(_L("CPanAgent: DeviceRoleChangeFailed left with %d"), err); |
|
1236 RequestDisconnect(err); |
|
1237 } |
|
1238 } |
|
1239 |
|
1240 void CPanAgent::DeviceDisconnected(CPanRemoteDeviceStateMachine& aDevice) |
|
1241 /** |
|
1242 Indicates that the remote device has disconnected, and should be deleted from the device array |
|
1243 */ |
|
1244 { |
|
1245 LOG_FUNC |
|
1246 __ASSERT_ALWAYS(iState, PanAgentPanic(ENoState)); |
|
1247 |
|
1248 #ifdef __FLOG_ACTIVE |
|
1249 TBuf<KMaxBtAddrSize> devaddr; |
|
1250 aDevice.DevAddr().GetReadable(devaddr, KNullDesC, KBtAddrSeparator, KNullDesC); |
|
1251 LOG1(_L("Remote device %S disconnected"), &devaddr); |
|
1252 #endif |
|
1253 |
|
1254 if(aDevice.NewConnectedDeviceProgressSent()) |
|
1255 { |
|
1256 SendProgress(EPanAgtDisconnectedDevice, KErrNone); |
|
1257 aDevice.SetNewConnectedDeviceProgressSent(EFalse); |
|
1258 } |
|
1259 |
|
1260 // Check if any remaining active devices require the uplink. |
|
1261 SendUplinkAccessRequiredProgressNotification(); |
|
1262 |
|
1263 TRAPD(err, iState->DeviceDisconnectedL(aDevice)); // if this leaves, then shutdown everything |
|
1264 |
|
1265 //check if there are more devices we want to connect to |
|
1266 TInt errNewConnection = KErrNone; |
|
1267 while (iDeviceSelector->HasMoreDevices()) |
|
1268 { |
|
1269 LOG(_L("More devices available, trying to establish connection")); |
|
1270 TRAP(errNewConnection, iDeviceSelector->CreateNextConnectionL()); |
|
1271 if (errNewConnection == KErrNone ) |
|
1272 { |
|
1273 LOG(_L("Created new connection to next available device")); |
|
1274 return; |
|
1275 } |
|
1276 else |
|
1277 { |
|
1278 LOG1(_L("Failed to create new connection, error=%d"), errNewConnection); |
|
1279 } |
|
1280 } |
|
1281 |
|
1282 if( err != KErrNone || errNewConnection != KErrNone ) |
|
1283 { |
|
1284 LOG(_L("...no more active devices, shutting down")); |
|
1285 RequestDisconnect(err); |
|
1286 } |
|
1287 } |
|
1288 |
|
1289 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
1290 /** |
|
1291 Return pointer to the main BNEP connection manager class |
|
1292 */ |
|
1293 const Messages::TNodeId& CPanAgent::BnepConnectionManager() |
|
1294 { |
|
1295 LOG_FUNC |
|
1296 return iBnepConnectionManager; |
|
1297 } |
|
1298 |
|
1299 /** |
|
1300 Restarts the incoming connection listener when it has been waiting |
|
1301 for a response from BNEP |
|
1302 */ |
|
1303 void CPanAgent::RestartIncomingConnectionListener(TInt aError) |
|
1304 { |
|
1305 LOG_FUNC |
|
1306 iIncomingConnectionListener->RestartIncomingConnectionListener(aError); |
|
1307 } |
|
1308 |
|
1309 void CPanAgent::SetRetryConnect(CPanRemoteDeviceStateMachine& /*aDevice*/) |
|
1310 { |
|
1311 LOG_FUNC |
|
1312 CPanAgtStateBase* nextState = NULL; |
|
1313 TInt err = KErrNone; |
|
1314 TRAP(err, nextState = CPanAgtStateIdle::NewL(*this)); |
|
1315 if(err != KErrNone) |
|
1316 { |
|
1317 if(iShutdownState) |
|
1318 { |
|
1319 SetState(*iShutdownState); |
|
1320 } |
|
1321 return; |
|
1322 } |
|
1323 |
|
1324 CPanAgtStatePaused* pausedState = NULL; |
|
1325 TRAP(err, |
|
1326 CleanupStack::PushL(nextState); |
|
1327 pausedState = CPanAgtStatePaused::NewL(*this, *nextState); |
|
1328 CleanupStack::Pop(); |
|
1329 ); |
|
1330 |
|
1331 if (err != KErrNone) |
|
1332 { |
|
1333 if(iShutdownState) |
|
1334 { |
|
1335 SetState(*iShutdownState); |
|
1336 } |
|
1337 return; |
|
1338 } |
|
1339 |
|
1340 delete iState; |
|
1341 SetState(*pausedState); |
|
1342 |
|
1343 // Only if all the above worked do we send the message to BNEP |
|
1344 TPanMessage::TSetRetryConnect msg; |
|
1345 RClientInterface::OpenPostMessageClose(Id(),BnepConnectionManager(),msg); |
|
1346 } |
|
1347 |
|
1348 #else |
|
1349 // !SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
1350 |
|
1351 /** |
|
1352 Return pointer to the main BNEP connection manager class |
|
1353 */ |
|
1354 MBnepConnectionManager& CPanAgent::BnepConnectionManager() |
|
1355 { |
|
1356 LOG_FUNC |
|
1357 __ASSERT_ALWAYS(iBnepConnectionManager, PanAgentPanic(ENullBnepConnectionManager)); |
|
1358 |
|
1359 return(*iBnepConnectionManager); |
|
1360 } |
|
1361 |
|
1362 void CPanAgent::SetRetryConnect(CPanRemoteDeviceStateMachine& /*aDevice*/) |
|
1363 { |
|
1364 LOG_FUNC |
|
1365 iBnepConnectionManager->SetRetryConnect(); |
|
1366 |
|
1367 CPanAgtStateBase* nextState = NULL; |
|
1368 TRAPD(err, nextState = CPanAgtStateIdle::NewL(*this)); |
|
1369 if(err == KErrNone) |
|
1370 { |
|
1371 delete iState; |
|
1372 SetState(*nextState); |
|
1373 } |
|
1374 else |
|
1375 { |
|
1376 if(iShutdownState) |
|
1377 { |
|
1378 SetState(*iShutdownState); |
|
1379 } |
|
1380 } |
|
1381 } |
|
1382 #endif |
|
1383 // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
1384 |
|
1385 |
|
1386 |
|
1387 void CPanAgent::CloseExistingConnectionWithUplinkAccess() |
|
1388 { |
|
1389 LOG_FUNC |
|
1390 TInt count = iRemoteDevices.Count(); |
|
1391 for(TInt i=0;i<count;i++) |
|
1392 { |
|
1393 if(iRemoteDevices[i]->UplinkAccessAllowed()) |
|
1394 { |
|
1395 // Close this connection. |
|
1396 iRemoteDevices[i]->Disconnect(); |
|
1397 break; |
|
1398 } |
|
1399 } |
|
1400 } |
|
1401 |
|
1402 void CPanAgent::GetExistingConnections(TPanConnectionList& aPanConnectionList) |
|
1403 { |
|
1404 LOG_FUNC |
|
1405 TBool localRoleSet = EFalse; |
|
1406 TInt count = iRemoteDevices.Count(); |
|
1407 for(TInt i=0;i<count;i++) |
|
1408 { |
|
1409 if(iRemoteDevices[i]->GetState() == EActive) |
|
1410 { |
|
1411 if(!localRoleSet) |
|
1412 { |
|
1413 // Set the local role. |
|
1414 aPanConnectionList.SetCurrentLocalRole(TUUID(iRemoteDevices[i]->LocalRole())); |
|
1415 localRoleSet = ETrue; |
|
1416 } |
|
1417 |
|
1418 TBTDevAddr deviceAddr = iRemoteDevices[i]->DevAddr(); |
|
1419 TPanConnection requestedConn(deviceAddr, iRemoteDevices[i]->UplinkAccessAllowed()); |
|
1420 |
|
1421 TRAPD(err, aPanConnectionList.AddRemoteConnectionL(requestedConn)); |
|
1422 if(err != KErrNone) |
|
1423 { |
|
1424 LOG1(_L("CPanAgent::GetExistingConnections - Failed to add existing connection [%d]"), i); |
|
1425 break; |
|
1426 } |
|
1427 } |
|
1428 } |
|
1429 |
|
1430 if(!localRoleSet) |
|
1431 { |
|
1432 aPanConnectionList.SetCurrentLocalRole(TUUID(0)); |
|
1433 } |
|
1434 } |
|
1435 |
|
1436 |
|
1437 TBool CPanAgent::WorthTrying(const TPanDeviceWorthTryingRolesList& aRemoteWorthTryingRoles) const |
|
1438 { |
|
1439 LOG_FUNC |
|
1440 TBool ret = ETrue; |
|
1441 if(iFixedRemoteRole != EPanRoleUnknown) // check for fixed remote role |
|
1442 { |
|
1443 ret = aRemoteWorthTryingRoles.IsWorthTryingARole(iFixedRemoteRole); // check if it is worth trying |
|
1444 } |
|
1445 return ret; |
|
1446 } |
|
1447 |
|
1448 |
|
1449 #ifndef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
1450 MPanLinkControlBase& CPanAgent::BnepConnectionController() |
|
1451 { |
|
1452 LOG_FUNC |
|
1453 return *this; |
|
1454 } |
|
1455 |
|
1456 |
|
1457 TAny* CPanAgent::MplcbGetInterface(const TUid & aInterface) |
|
1458 { |
|
1459 LOG_FUNC |
|
1460 if (aInterface ==KUidPanLinkControlV1) |
|
1461 { |
|
1462 return PanLinkControlInterface(); |
|
1463 } |
|
1464 return NULL; |
|
1465 } |
|
1466 |
|
1467 MPanLinkControl* CPanAgent::PanLinkControlInterface() |
|
1468 { |
|
1469 LOG_FUNC |
|
1470 return this; |
|
1471 } |
|
1472 |
|
1473 TInt CPanAgent::MplcRequestSniff(const TBTDevAddr & aAddr) |
|
1474 { |
|
1475 LOG_FUNC |
|
1476 CPanRemoteDeviceStateMachine* dev=FindRemoteDeviceByAddress(aAddr); |
|
1477 if (dev) |
|
1478 { |
|
1479 return dev->PhysicalLinkAdapter().ActivateSniffRequester(); |
|
1480 } |
|
1481 else |
|
1482 { |
|
1483 return KErrNotFound; |
|
1484 } |
|
1485 } |
|
1486 |
|
1487 TInt CPanAgent::MplcRequestActive(const TBTDevAddr & aAddr) |
|
1488 { |
|
1489 LOG_FUNC |
|
1490 CPanRemoteDeviceStateMachine* dev=FindRemoteDeviceByAddress(aAddr); |
|
1491 if (dev) |
|
1492 { |
|
1493 return dev->PhysicalLinkAdapter().ActivateActiveRequester(); |
|
1494 } |
|
1495 else |
|
1496 { |
|
1497 return KErrNotFound; |
|
1498 } |
|
1499 |
|
1500 } |
|
1501 #endif |
|
1502 // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
1503 |
|
1504 // |
|
1505 // PAN agent helper methods |
|
1506 // |
|
1507 |
|
1508 CPanRemoteDeviceStateMachine* CPanAgent::FindRemoteDeviceByAddress(const TBTDevAddr& remoteDeviceAddress) |
|
1509 /** |
|
1510 Find the remote device with the specified address |
|
1511 @note Simple linear search (the array size is small) - easier than constructing a temporary to use |
|
1512 with RPointerArray::Find() |
|
1513 */ |
|
1514 { |
|
1515 LOG_FUNC |
|
1516 for(TInt i=0; i < iRemoteDevices.Count(); ++i) |
|
1517 { |
|
1518 if(iRemoteDevices[i]->DevAddr() == remoteDeviceAddress) |
|
1519 { |
|
1520 return (iRemoteDevices[i]); |
|
1521 } |
|
1522 } |
|
1523 return NULL; |
|
1524 } |
|
1525 |
|
1526 void CPanAgent::CheckDeviceIsNotAlreadyAttachedL(const TBTDevAddr& aDevAddr) |
|
1527 /** |
|
1528 Ensure the remote device is not already a member of the PAN network |
|
1529 (PAN profile only allows one BNEP connection between devices) |
|
1530 */ |
|
1531 { |
|
1532 LOG_FUNC |
|
1533 |
|
1534 if(FindRemoteDeviceByAddress(aDevAddr)) |
|
1535 { |
|
1536 LOG(_L("CPanAgent: ...it is - disconnecting it")); |
|
1537 |
|
1538 User::Leave(KErrAlreadyExists); |
|
1539 } |
|
1540 |
|
1541 LOG(_L("CPanAgent: ...it isn't - creating new connection")); |
|
1542 } |
|
1543 |
|
1544 void CPanAgent::RequestDisconnect(TInt aError) |
|
1545 /** |
|
1546 Request from role state machine to disconnect |
|
1547 @note Any code in this class that wants to trigger a disconnect should call this method. |
|
1548 @note This is designed to be called only from the role state machine - states can trigger |
|
1549 a shutdown by leaving from within their state |
|
1550 @param aError The error code that occurred, or KErrNone if the shutdown state does not know |
|
1551 what the error is |
|
1552 */ |
|
1553 { |
|
1554 LOG_FUNC |
|
1555 LOG1(_L("CPanAgent: request disconnect from state with error %d"), aError); |
|
1556 |
|
1557 if(aError!=KErrNone) // shutdown state may not know what the error is, in which case it will |
|
1558 // pass KErrNone, and we should preserve the previous value of iError |
|
1559 { |
|
1560 iError = aError; |
|
1561 } |
|
1562 |
|
1563 if(iNifmanConnected) // once connected, we need to disconnect when there's an error |
|
1564 { |
|
1565 iInitiateDisconnectCallback->CallBack(); |
|
1566 } |
|
1567 else // we haven't actually brought the connection up properly yet, so rather than issuing |
|
1568 //a Stop() we should just pass an error code back to nifman in ConnectComplete() |
|
1569 { |
|
1570 __ASSERT_DEBUG(iError!=KErrNone, PanAgentPanic(ESomeoneLeftWithoutGivingAReason)); // there's a problem, but no-one's set an error code to say what it is! |
|
1571 } |
|
1572 } |
|
1573 |
|
1574 // |
|
1575 // Agent extended management interface methods |
|
1576 // |
|
1577 |
|
1578 TInt CPanAgent::GetInterfaceType(TConnectionType& aConnectionType) |
|
1579 /** |
|
1580 Return the type of this interface |
|
1581 */ |
|
1582 { |
|
1583 LOG_FUNC |
|
1584 aConnectionType = EConnectionBTPAN; |
|
1585 return KErrNone; |
|
1586 } |
|
1587 |
|
1588 TInt CPanAgent::EnumerateSubConnections(TUint& aCount) |
|
1589 /** |
|
1590 Return the number of subconnections |
|
1591 @note Connections to a device are not treated as subconnections, as subconnections are reserved |
|
1592 currently reserved to refer to QoS channels - since BT PAN profile does not support QoS at the |
|
1593 moment, there are no subconnections to expose |
|
1594 */ |
|
1595 { |
|
1596 LOG_FUNC |
|
1597 aCount = 1; // the "whole connection" subconnection |
|
1598 return KErrNone; |
|
1599 } |
|
1600 |
|
1601 TInt CPanAgent::GetSubConnectionInfo(TUint /*aIndex*/, TDes8& /*aSubConnectionInfo*/) |
|
1602 { |
|
1603 LOG_FUNC |
|
1604 return KErrNotSupported; |
|
1605 } |
|
1606 |
|
1607 TInt CPanAgent::GetSubConnectionInfo(TDes8& /*aSubConnectionInfo*/) |
|
1608 { |
|
1609 LOG_FUNC |
|
1610 return KErrNotSupported; |
|
1611 } |
|
1612 |
|
1613 TBool CPanAgent::AllowIncoming() const |
|
1614 { |
|
1615 LOG_FUNC |
|
1616 return iAllowIncoming; |
|
1617 } |
|
1618 |
|
1619 void CPanAgent::SetAllowIncoming(TBool aAllowIncoming) |
|
1620 { |
|
1621 LOG_FUNC |
|
1622 iAllowIncoming = aAllowIncoming; |
|
1623 } |
|
1624 |
|
1625 TBool CPanAgent::NapEnabled() const |
|
1626 { |
|
1627 LOG_FUNC |
|
1628 return iNapEnabled; |
|
1629 } |
|
1630 |
|
1631 void CPanAgent::SetNapEnabled(TBool aNapEnabled) |
|
1632 { |
|
1633 LOG_FUNC |
|
1634 iNapEnabled = aNapEnabled; |
|
1635 } |
|
1636 |
|
1637 TInt CPanAgent::TryToCreateNewPanConnection() |
|
1638 { |
|
1639 LOG_FUNC |
|
1640 if (iPanCoexistenceConnectionController) |
|
1641 { |
|
1642 return iPanCoexistenceConnectionController->TryToCreateNewPanConnection(); |
|
1643 } |
|
1644 else |
|
1645 { |
|
1646 // Make sure the release build works fine if iPanCoexistenceConnectionController is null |
|
1647 LOG(_L("CPanAgent::TryToCreateNewPanConnection - iPanCoexistenceConnectionController is NULL")); |
|
1648 return KErrNone; |
|
1649 } |
|
1650 } |
|
1651 |
|
1652 void CPanAgent::HandleAllPanConnectionsClosed() |
|
1653 { |
|
1654 LOG_FUNC |
|
1655 if (iPanCoexistenceConnectionController) |
|
1656 { |
|
1657 iPanCoexistenceConnectionController->HandleAllPanConnectionsClosed(); |
|
1658 } |
|
1659 else |
|
1660 { |
|
1661 // Log it when iPanCoexistenceConnectionController is null |
|
1662 LOG(_L("CPanAgent::HandleAllPanConnectionsClosed - iPanCoexistenceConnectionController is NULL")); |
|
1663 } |
|
1664 } |
|
1665 |
|
1666 TBool CPanAgent::IsNewPanConnectionAllowed() const |
|
1667 { |
|
1668 LOG_FUNC |
|
1669 TBool rValue = EFalse; |
|
1670 |
|
1671 if(iPanCoexistenceConnectionController) |
|
1672 { |
|
1673 TIPBearerCoexistenceStatus status = iPanCoexistenceConnectionController->ReadStatus(); |
|
1674 if(status == EBTPanIsActive || status == ENoneIsActive) |
|
1675 { |
|
1676 __ASSERT_DEBUG(status != EBTPanIsActive, PanAgentPanic(EImproperSituationToSetPropertyToBTPanIsActive)); |
|
1677 rValue = ETrue; |
|
1678 } |
|
1679 } |
|
1680 else |
|
1681 { |
|
1682 LOG(_L("CPanAgent::IsNewPanConnectionAllowed - iPanCoexistenceConnectionController is NULL")); |
|
1683 //Make sure the release build works fine if iPanCoexistenceConnectionController is null |
|
1684 rValue = ETrue; |
|
1685 } |
|
1686 |
|
1687 return rValue; |
|
1688 } |
|
1689 |
|
1690 void CPanAgent::SendUplinkAccessRequiredProgressNotification() |
|
1691 { |
|
1692 LOG_FUNC |
|
1693 // Check if any active devices require the uplink. |
|
1694 TBool uplinkRequired = EFalse; |
|
1695 TInt count = iRemoteDevices.Count(); |
|
1696 for(TInt i=0;i<count;i++) |
|
1697 { |
|
1698 if(iRemoteDevices[i]->GetState() == EActive && iRemoteDevices[i]->UplinkAccessAllowed()) |
|
1699 { |
|
1700 uplinkRequired = ETrue; |
|
1701 break; |
|
1702 } |
|
1703 } |
|
1704 |
|
1705 if(iUplinkRequiredProgressSent && !uplinkRequired) |
|
1706 { |
|
1707 // The uplink is no longer required send a progress notification |
|
1708 iUplinkRequiredProgressSent = EFalse; |
|
1709 SendProgress(EPanAgtUplinkNotRequired, KErrNone); |
|
1710 } |
|
1711 else if(!iUplinkRequiredProgressSent && uplinkRequired) |
|
1712 { |
|
1713 // The uplink is now required, send a progress notification |
|
1714 iUplinkRequiredProgressSent = ETrue; |
|
1715 SendProgress(EPanAgtUplinkRequired, KErrNone); |
|
1716 } |
|
1717 } |
|
1718 |
|
1719 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
1720 /** |
|
1721 */ |
|
1722 void CPanAgent::ReceivedL(const Messages::TRuntimeCtxId& /* aSender */, const Messages::TNodeId& /* aRecipient */, Messages::TSignatureBase& aCFMessage) |
|
1723 { |
|
1724 LOG_FUNC |
|
1725 if (aCFMessage.MessageId().Realm() == TPanMessage::ERealmId) |
|
1726 { |
|
1727 switch (aCFMessage.MessageId().MessageId()) |
|
1728 { |
|
1729 case TPanMessage::TSetRetryConnectComplete::EId: |
|
1730 { |
|
1731 // We would expect that iState should always be the paused state when |
|
1732 // we get here. We assert it in debug builds in case something we |
|
1733 // haven't accounted for changes it unexpectedly |
|
1734 __ASSERT_DEBUG(iState->iStateNumber == CPanAgtStateBase::EPanAgtStatePaused, PanAgentPanic(EPanAgtUnexpectedStateChange)); |
|
1735 if (iState->iStateNumber == CPanAgtStateBase::EPanAgtStatePaused) |
|
1736 { |
|
1737 static_cast<CPanAgtStatePaused*>(iState)->TransitionToNextState(); |
|
1738 } |
|
1739 } |
|
1740 break; |
|
1741 |
|
1742 default: |
|
1743 __ASSERT_DEBUG(EFalse, PanAgentPanic(EPanAgtUnexpectedMessage)); |
|
1744 break; |
|
1745 } |
|
1746 } |
|
1747 else |
|
1748 { |
|
1749 __ASSERT_DEBUG(EFalse, PanAgentPanic(EPanAgtUnexpectedMessage)); |
|
1750 } |
|
1751 |
|
1752 // Absorb messages |
|
1753 aCFMessage.ClearMessageId(); |
|
1754 } |
|
1755 #endif |
|
1756 |
|
1757 |
|
1758 |
|
1759 |
|
1760 |
|
1761 |
|
1762 // |
|
1763 // State base class implementations |
|
1764 // |
|
1765 |
|
1766 void CPanAgtStateBase::DeviceActiveL(CPanRemoteDeviceStateMachine& /*aDevice*/) |
|
1767 /** |
|
1768 Base class implementation - should never be called |
|
1769 */ |
|
1770 { |
|
1771 LOG_FUNC |
|
1772 PanicInState(EUnexpectedDeviceActiveReceivedByState); |
|
1773 } |
|
1774 |
|
1775 void CPanAgtStateBase::DeviceRoleChangeFailedL(CPanRemoteDeviceStateMachine& /*aDevice*/) |
|
1776 /** |
|
1777 Base class implementation - should never be called |
|
1778 */ |
|
1779 { |
|
1780 LOG_FUNC |
|
1781 PanicInState(EUnexpectedDeviceRoleChangeFailedReceivedByState); |
|
1782 } |
|
1783 |
|
1784 void CPanAgtStateBase::DeviceDisconnectedL(CPanRemoteDeviceStateMachine& /*aDevice*/) |
|
1785 /** |
|
1786 Base class implementation - should never be called |
|
1787 */ |
|
1788 { |
|
1789 LOG_FUNC |
|
1790 PanicInState(EUnexpectedDeviceDisconnectedReceivedByState); |
|
1791 } |
|
1792 |
|
1793 void CPanAgtStateBase::StateSendRoleNotification() |
|
1794 /** |
|
1795 Base class implementation - will be called but should need to do nothing, just log |
|
1796 overridden for states EPanAgtStateURole and EPanAgtStateGnRole |
|
1797 */ |
|
1798 { |
|
1799 LOG_FUNC |
|
1800 LOG1(_L("PanAgtSB - CPanAgtStateBase::StateSendRoleNotification() called for state %d"),iStateNumber); |
|
1801 } |
|
1802 |
|
1803 void CPanAgtStateBase::IncomingConnectionFromPeerL(TBluetoothPanRole /*aLocalRole*/) |
|
1804 /** |
|
1805 Base class implementation - should never be called |
|
1806 */ |
|
1807 { |
|
1808 LOG_FUNC |
|
1809 PanicInState(EUnexpectedIncomingConnectionFromPeerReceivedByState); |
|
1810 } |
|
1811 |
|
1812 void CPanAgtStateBase::RoleChangeRequestFromPeerL(TBluetoothPanRole /*aLocalRole*/) |
|
1813 /** |
|
1814 Base class implementation - should never be called |
|
1815 */ |
|
1816 { |
|
1817 LOG_FUNC |
|
1818 PanicInState(EUnexpectedRoleChangeRequestFromPeerReceivedByState); |
|
1819 } |
|
1820 |
|
1821 void CPanAgtStateBase::InitiateOutgoingConnectionL(TBluetoothPanRole& /*aLocalRole*/, TBluetoothPanRole& /*aRemoteRole*/, TPanDeviceWorthTryingRolesList& /*aWorthTryingRemoteRoles*/) |
|
1822 /** |
|
1823 Base class implementation - should never be called |
|
1824 */ |
|
1825 { |
|
1826 LOG_FUNC |
|
1827 PanicInState(EUnexpectedInitiateOutgoingConnectionReceivedByState); |
|
1828 } |
|
1829 |
|
1830 void CPanAgtStateBase::PerformLocalRoleChangeRequestL(TBluetoothPanRole& /*aLocalRole*/, TBluetoothPanRole& /*aRemoteRole*/) |
|
1831 /** |
|
1832 Base class implementation - should never be called |
|
1833 */ |
|
1834 { |
|
1835 LOG_FUNC |
|
1836 PanicInState(EUnexpectedPerformLocalRoleChangeRequestReceivedByState); |
|
1837 } |
|
1838 |
|
1839 CPanAgtStateBase::CPanAgtStateBase(MPanAgtStateMachineNotify& aStateMachine, TPanAgtStates aStateNumber) : |
|
1840 iStateMachine(aStateMachine), iStateNumber(aStateNumber) |
|
1841 /** |
|
1842 When implementing a new state that derives from this base class, ensure that |
|
1843 it provides a unique number to identify the state from other possible |
|
1844 states. @see PanAgent::TPanAgtStates. |
|
1845 */ |
|
1846 { |
|
1847 LOG_FUNC |
|
1848 |
|
1849 } |
|
1850 |
|
1851 void CPanAgtStateBase::StartNegotiationWithFirstPendingDevice() |
|
1852 /** |
|
1853 Check for any idle devices in the device array, and trigger negotiation on the first one; if there are no idle devices this method returns without doing anything. |
|
1854 @note Device negotiation is performed in the order that devices are held in the array - new devices should be inserted at the end of the array |
|
1855 */ |
|
1856 { |
|
1857 LOG_FUNC |
|
1858 |
|
1859 // find first pending device in array and call ReadyForRoleRequest |
|
1860 for(TInt i=0;i<StateMachine().Devices().Count();++i) |
|
1861 { |
|
1862 CPanRemoteDeviceStateMachine& device = *StateMachine().Devices()[i]; |
|
1863 |
|
1864 if(device.GetState() == EPendingNegotiation) |
|
1865 { |
|
1866 LOG(_L("PanAgtSB - ...device with negotiation pending found - calling ReadyForRoleRequest")); |
|
1867 device.ReadyForRoleRequest(); |
|
1868 return; |
|
1869 } |
|
1870 } |
|
1871 LOG(_L("PanAgtSB - ...no pending devices found")); |
|
1872 } |
|
1873 |
|
1874 TInt CPanAgtStateBase::IsRoleRequestValid(TBluetoothPanRole aRequestedLocalRole, TBluetoothPanRole aRequestedRemoteRole) const |
|
1875 /** |
|
1876 Check the role request is legal according to the PAN profile spec |
|
1877 @param aRequestedLocalRole The requested local role |
|
1878 @param aRequestedRemoteRole The requested remote role |
|
1879 @return KErrNone if role request is OK, KErrArgument if the role combination was illegal |
|
1880 @note Not a bug as such, but just a convenient way to get doxygen to record that this method embeds knowledge |
|
1881 of legal PAN role combinations, and allows EPanRoleUnknown as a valid local role. Later code must decide on |
|
1882 a concrete local role if this is the case. |
|
1883 */ |
|
1884 { |
|
1885 LOG_FUNC |
|
1886 // check for invalid role combinations |
|
1887 if((aRequestedLocalRole==EPanRoleGn || aRequestedLocalRole==EPanRoleNap) && (aRequestedRemoteRole==EPanRoleGn || aRequestedRemoteRole==EPanRoleNap)) |
|
1888 { |
|
1889 LOG2(_L("PanAgtSB - CheckRoleRequest: invalid role combination received (%x, %x)"), aRequestedLocalRole, aRequestedRemoteRole); |
|
1890 return KErrArgument; |
|
1891 } |
|
1892 else |
|
1893 { |
|
1894 return KErrNone; |
|
1895 } |
|
1896 } |
|
1897 |
|
1898 TInt CPanAgtStateBase::SelectRemoteRoleBasedOnLocalRole(TBluetoothPanRole aSelectedLocalRole, TBluetoothPanRole& aRemoteRole, TPanDeviceWorthTryingRolesList& aWorthTryingRemoteRoles) |
|
1899 /** |
|
1900 Given a selected local role, check what role has been proposed for the remote device and alter it accordingly |
|
1901 @note This handles setting the remote role if it is fixed in commdb |
|
1902 @param aSelectedLocalRole The local role that has been selected by the role state machine |
|
1903 @param aRemoteRole On entry, the role that was proposed by the remote device state machine. On return, the |
|
1904 remote role that will be requested |
|
1905 @return The same error codes and meanings as MRemoteDeviceNotify::RoleRequest() |
|
1906 @note Embeds knowledge of valid PAN profile role combinations |
|
1907 */ |
|
1908 { |
|
1909 LOG_FUNC |
|
1910 TBluetoothPanRole fixedRemoteRole = StateMachine().FixedRemoteRole(); |
|
1911 |
|
1912 // Check to see if there's a fixed remote role first... |
|
1913 if(fixedRemoteRole != EPanRoleUnknown) // check for fixed remote role |
|
1914 { |
|
1915 LOG1(_L("PanAgtSB - SelectRemoteRole: ...remote role is fixed as %x..."), StateMachine().FixedRemoteRole()); |
|
1916 |
|
1917 if(aWorthTryingRemoteRoles.IsWorthTryingARole(fixedRemoteRole) || fixedRemoteRole == EPanRoleU) |
|
1918 { |
|
1919 // if the remote device doesn't support the role (and it's not U role, which isn't |
|
1920 // necessarily advertised in SDP (see PAN profile spec v1.0, section 8.1.3) |
|
1921 // then return an error |
|
1922 aRemoteRole = fixedRemoteRole; |
|
1923 aWorthTryingRemoteRoles.SetWorthTrying(fixedRemoteRole, EFalse); |
|
1924 } |
|
1925 else |
|
1926 { |
|
1927 LOG(_L("PanAgtSB - SelectRemoteRole: ...fixed remote role is not supported! (not included in SDP)")); |
|
1928 return KErrInvalidOrUnacceptableRoleCombination; |
|
1929 } |
|
1930 } |
|
1931 else |
|
1932 { |
|
1933 // ...otherwise use dynamic role selection |
|
1934 switch(aSelectedLocalRole) |
|
1935 { |
|
1936 case EPanRoleU: |
|
1937 { |
|
1938 LOG(_L("PanAgtSB - CheckAndAdjustRemoteRole: no SDP query to use for remote role selection, making a guess and trying U role - there's not much else we can do")); |
|
1939 // see PAN profile spec v1.0, section 8.1.3 for reasoning |
|
1940 |
|
1941 /* now if we don't know what they do support |
|
1942 and the other side has refused us, or we didn't ask |
|
1943 then we might ask for something else |
|
1944 */ |
|
1945 // lets decide what we'll try this time |
|
1946 if (aWorthTryingRemoteRoles.IsWorthTryingU()) |
|
1947 { |
|
1948 aRemoteRole = EPanRoleU; |
|
1949 } |
|
1950 else if (aWorthTryingRemoteRoles.IsWorthTryingGn()) |
|
1951 { |
|
1952 aRemoteRole = EPanRoleGn; |
|
1953 } |
|
1954 else if (aWorthTryingRemoteRoles.IsWorthTryingNap()) |
|
1955 { |
|
1956 aRemoteRole = EPanRoleNap; |
|
1957 } |
|
1958 |
|
1959 aWorthTryingRemoteRoles.SetWorthTrying(aRemoteRole, EFalse); |
|
1960 } |
|
1961 break; // RVCT detects this as dead code - if you change the logic above, *beware* |
|
1962 // you may need this! |
|
1963 case EPanRoleGn: |
|
1964 case EPanRoleNap: |
|
1965 aRemoteRole = EPanRoleU; |
|
1966 break; |
|
1967 |
|
1968 default: |
|
1969 PanicInState(EPanAgentRoleStateMachineSelectedUnknownAsLocalRole); |
|
1970 }; |
|
1971 } |
|
1972 |
|
1973 return KErrNone; |
|
1974 } |
|
1975 |
|
1976 void CPanAgtStateBase::DoDeviceDisconnectL(CPanRemoteDeviceStateMachine& aDevice) |
|
1977 /** |
|
1978 Delete the disconnected device from the array, and check if it was the last device. If it was, and we're |
|
1979 not allowing incoming connections, then shutdown. |
|
1980 */ |
|
1981 { |
|
1982 LOG_FUNC |
|
1983 __ASSERT_DEBUG(FindDeviceInArray(aDevice)>=0, PanicInState(EDeviceDisconnectedThatWasNotInArray)); |
|
1984 |
|
1985 TInt index = FindDeviceInArray(aDevice); |
|
1986 if(index>=0) // ie. the device is in the array |
|
1987 { |
|
1988 LOG(_L("RoleState: <[base]> - device disconnected")); |
|
1989 delete StateMachine().Devices()[index]; |
|
1990 StateMachine().Devices().Remove(index); |
|
1991 } |
|
1992 |
|
1993 if (StateMachine().Devices().Count()==0) |
|
1994 { |
|
1995 StateMachine().HandleAllPanConnectionsClosed(); |
|
1996 |
|
1997 // see if this was the last device, and if we're not listening for incoming connections |
|
1998 if (!(StateMachine().AllowIncoming()) && !(StateMachine().IsPromptingUserForDeviceSelection())) |
|
1999 { |
|
2000 User::Leave(KErrAllDevicesDisconnected); |
|
2001 } |
|
2002 |
|
2003 } |
|
2004 } |
|
2005 |
|
2006 TInt CPanAgtStateBase::NegotiatingDeviceCount() const |
|
2007 /** |
|
2008 The number of devices in the device array in negotiating state |
|
2009 @return The number of devices in the device array in negotiating state |
|
2010 */ |
|
2011 { |
|
2012 LOG_FUNC |
|
2013 return(DeviceCountInState(EPerformingNegotiation)); |
|
2014 } |
|
2015 |
|
2016 |
|
2017 TInt CPanAgtStateBase::ActiveDeviceCount() const |
|
2018 /** |
|
2019 The number of devices in the device array in active state |
|
2020 @return The number of devices in the device array in active state |
|
2021 */ |
|
2022 { |
|
2023 LOG_FUNC |
|
2024 return(DeviceCountInState(EActive)); |
|
2025 } |
|
2026 |
|
2027 MPanAgtStateMachineNotify& CPanAgtStateBase::StateMachine() |
|
2028 /** |
|
2029 Return a handle to the state machine |
|
2030 */ |
|
2031 { |
|
2032 LOG_FUNC |
|
2033 return(iStateMachine); |
|
2034 } |
|
2035 |
|
2036 const MPanAgtStateMachineNotify& CPanAgtStateBase::StateMachine() const |
|
2037 /** |
|
2038 Return a const handle to the state machine |
|
2039 */ |
|
2040 { |
|
2041 LOG_FUNC |
|
2042 return(iStateMachine); |
|
2043 } |
|
2044 |
|
2045 TInt CPanAgtStateBase::FindDeviceInArray(const CPanRemoteDeviceStateMachine& aDevice) const |
|
2046 /** |
|
2047 Find a given device in the array |
|
2048 @param aRequestingConnection The connection handle to find |
|
2049 @return Either the position of the device in the array, or KErrNotFound |
|
2050 */ |
|
2051 { |
|
2052 LOG_FUNC |
|
2053 for(TInt i=0; i<StateMachine().Devices().Count(); i++) |
|
2054 { |
|
2055 if(StateMachine().Devices()[i] == &aDevice) |
|
2056 { |
|
2057 return i; |
|
2058 } |
|
2059 } |
|
2060 return KErrNotFound; |
|
2061 } |
|
2062 |
|
2063 TInt CPanAgtStateBase::DeviceCountInState(TRemoteDeviceState aState) const |
|
2064 /** |
|
2065 The number of devices in the given state |
|
2066 @param aState Devices in this state should be counted |
|
2067 @return The number of devices in the given state |
|
2068 */ |
|
2069 { |
|
2070 LOG_FUNC |
|
2071 #ifdef _DEBUG |
|
2072 DumpDeviceArray(); |
|
2073 #endif |
|
2074 TInt devCountInState = 0; |
|
2075 |
|
2076 for(TInt i=0; i<StateMachine().Devices().Count(); i++) |
|
2077 { |
|
2078 if((StateMachine().Devices()[i]->GetState()) == aState) |
|
2079 { |
|
2080 ++devCountInState; |
|
2081 } |
|
2082 } |
|
2083 |
|
2084 return(devCountInState); |
|
2085 } |
|
2086 |
|
2087 void CPanAgtStateBase::LockDeviceAsPiconetMasterL() |
|
2088 /** |
|
2089 Set link policy to stop other devices changing the baseband role, once we are in the master role |
|
2090 @note The ASSERT to ensure that we are in the master role is performed in the remote device state machines |
|
2091 in debug mode only |
|
2092 */ |
|
2093 { |
|
2094 LOG_FUNC |
|
2095 __ASSERT_DEBUG(NegotiatingDeviceCount()==0, PanicInState(ETryingToLockBasebandRolesWhenDevicesAreNegotiating)); |
|
2096 |
|
2097 for(TInt i=0; i < StateMachine().Devices().Count(); ++i) |
|
2098 { |
|
2099 // lock any device that is active into it's current baseband role (which should be master) |
|
2100 // can't lock other devices, because in hardware that supports scatternetting, they |
|
2101 // might still be in slave role, because we haven't gone through the role negotiation |
|
2102 // process with them yet, which is where we do baseband role switches |
|
2103 if(StateMachine().Devices()[i]->GetState() == EActive) |
|
2104 { |
|
2105 User::LeaveIfError(StateMachine().Devices()[i]->DisallowRoleSwitch()); |
|
2106 } |
|
2107 } |
|
2108 } |
|
2109 |
|
2110 TInt CPanAgtStateBase::ReleasePiconetMasterLock() |
|
2111 /** |
|
2112 Set link policy to allow other devices to change the baseband role |
|
2113 */ |
|
2114 { |
|
2115 LOG_FUNC |
|
2116 TInt count; |
|
2117 TInt err; |
|
2118 for(count=0; count < StateMachine().Devices().Count(); ++count) |
|
2119 { |
|
2120 err = StateMachine().Devices()[count]->AllowRoleSwitch(); |
|
2121 if(!err) |
|
2122 { |
|
2123 continue; |
|
2124 } |
|
2125 else // go back through the devices resetting the link policy to lock us as master |
|
2126 { |
|
2127 for(--count; count >= 0; --count) // decrement before starting so we only reset role switching for the ones that we have previously set |
|
2128 { |
|
2129 if(StateMachine().Devices()[count]->GetState() == EActive) |
|
2130 { |
|
2131 // ignore errors - if we don't then the only other choice is to shut down everything! |
|
2132 StateMachine().Devices()[count]->DisallowRoleSwitch(); |
|
2133 } |
|
2134 } |
|
2135 } |
|
2136 break; |
|
2137 } |
|
2138 return KErrNone; |
|
2139 } |
|
2140 |
|
2141 void CPanAgtStateBase::StartListenerL() |
|
2142 /** |
|
2143 Work out which local roles we support and register the appropriate records |
|
2144 */ |
|
2145 { |
|
2146 LOG_FUNC |
|
2147 |
|
2148 if(StateMachine().AllowIncoming()) |
|
2149 { |
|
2150 __ASSERT_DEBUG(StateMachine().FixedLocalRole() != EPanRoleU, PanAgentPanic(EFixedLocalRoleUForListeningIap)); |
|
2151 |
|
2152 // Register U role if fixed local role is not specified. |
|
2153 if(StateMachine().FixedLocalRole() == EPanRoleUnknown) |
|
2154 { |
|
2155 StateMachine().PanLocalSdpRegistrar().RegisterLocalSdpRecordL(EPanRoleU, StateMachine().IapId()); |
|
2156 } |
|
2157 |
|
2158 // Register either GN or NAP |
|
2159 if(StateMachine().NapEnabled()) |
|
2160 { |
|
2161 StateMachine().PanLocalSdpRegistrar().RegisterLocalSdpRecordL(EPanRoleNap, StateMachine().IapId()); |
|
2162 } |
|
2163 else |
|
2164 { |
|
2165 StateMachine().PanLocalSdpRegistrar().RegisterLocalSdpRecordL(EPanRoleGn, StateMachine().IapId()); |
|
2166 } |
|
2167 |
|
2168 User::LeaveIfError(StateMachine().StartIncomingConnectionListener()); |
|
2169 } |
|
2170 } |
|
2171 |
|
2172 void CPanAgtStateBase::StopListener() |
|
2173 { |
|
2174 LOG(_L("StopListener - remove local SDP registation and close listener.")); |
|
2175 |
|
2176 //check that listerner is started |
|
2177 if(StateMachine().IsIncomingConnectionListenerEnabled()) |
|
2178 { |
|
2179 __ASSERT_DEBUG(StateMachine().FixedLocalRole() != EPanRoleU, PanAgentPanic(EFixedLocalRoleUForListeningIap)); |
|
2180 |
|
2181 // Unregister U role if fixed local role is not specified. |
|
2182 if(StateMachine().FixedLocalRole() == EPanRoleUnknown) |
|
2183 { |
|
2184 StateMachine().PanLocalSdpRegistrar().UnregisterLocalSdpRecord(EPanRoleU); |
|
2185 } |
|
2186 |
|
2187 // Unregister either GN or NAP |
|
2188 if(StateMachine().NapEnabled()) |
|
2189 { |
|
2190 StateMachine().PanLocalSdpRegistrar().UnregisterLocalSdpRecord(EPanRoleNap); |
|
2191 } |
|
2192 else |
|
2193 { |
|
2194 StateMachine().PanLocalSdpRegistrar().UnregisterLocalSdpRecord(EPanRoleGn); |
|
2195 } |
|
2196 |
|
2197 StateMachine().CloseIncomingConnectionListener(); |
|
2198 } |
|
2199 } |
|
2200 |
|
2201 void CPanAgtStateBase::Connect() |
|
2202 { |
|
2203 LOG_FUNC |
|
2204 iServiceStartedCallback->CallBack(); |
|
2205 } |
|
2206 |
|
2207 void CPanAgtStateBase::CancelConnect() |
|
2208 { |
|
2209 LOG_FUNC |
|
2210 iServiceStartedCallback->Cancel(); |
|
2211 } |
|
2212 |
|
2213 void CPanAgtStateBase::ServiceStarted() |
|
2214 { |
|
2215 LOG_FUNC |
|
2216 |
|
2217 StateMachine().SendProgress(EPanAgtInitialising, KErrNone); |
|
2218 iConnectCompleteCallback->CallBack(); // Queued here before ServiceStarted as ServiceStarted can delete iConnectCompleteCallback, causing a null pointer exception |
|
2219 StateMachine().ServiceStarted(); |
|
2220 |
|
2221 } |
|
2222 |
|
2223 TInt CPanAgtStateBase::ServiceStartedCb(TAny* aThisPtr) |
|
2224 /** |
|
2225 Connection Callback static function |
|
2226 */ |
|
2227 { |
|
2228 LOG_STATIC_FUNC |
|
2229 __ASSERT_DEBUG(aThisPtr, PanAgentPanic(ENullTAnyPointer)); |
|
2230 |
|
2231 CPanAgtStateBase* self = static_cast<CPanAgtStateBase*>(aThisPtr); |
|
2232 self->ServiceStarted(); |
|
2233 return KErrNone; |
|
2234 } |
|
2235 |
|
2236 TInt CPanAgtStateBase::ConnectCompleteCb(TAny* aThisPtr) |
|
2237 /** |
|
2238 Second callback used during connection creation |
|
2239 */ |
|
2240 { |
|
2241 LOG_STATIC_FUNC |
|
2242 __ASSERT_DEBUG(aThisPtr, PanAgentPanic(ENullTAnyPointer)); |
|
2243 |
|
2244 CPanAgtStateBase* self = static_cast<CPanAgtStateBase*>(aThisPtr); |
|
2245 self->StateMachine().ConnectComplete(); |
|
2246 return KErrNone; |
|
2247 } |
|
2248 |
|
2249 void CPanAgtStateBase::BaseConstructL() |
|
2250 { |
|
2251 LOG_FUNC |
|
2252 iConnectCompleteCallback = new (ELeave) CAsyncCallBack(KPanAgtAoPriority); |
|
2253 TCallBack connectCompleteCallback(ConnectCompleteCb, this); |
|
2254 iConnectCompleteCallback->Set(connectCompleteCallback); |
|
2255 |
|
2256 iServiceStartedCallback = new (ELeave) CAsyncCallBack(KPanAgtAoPriority); |
|
2257 TCallBack serviceStartedCallback(ServiceStartedCb, this); |
|
2258 iServiceStartedCallback->Set(serviceStartedCallback); |
|
2259 } |
|
2260 |
|
2261 CPanAgtStateBase::~CPanAgtStateBase() |
|
2262 { |
|
2263 LOG_FUNC |
|
2264 iServiceStartedCallback->Cancel(); |
|
2265 delete iServiceStartedCallback; |
|
2266 iServiceStartedCallback = NULL; |
|
2267 |
|
2268 iConnectCompleteCallback->Cancel(); |
|
2269 delete iConnectCompleteCallback; |
|
2270 iConnectCompleteCallback = NULL; |
|
2271 } |
|
2272 |
|
2273 void CPanAgtStateBase::CancelReconnect() |
|
2274 { |
|
2275 LOG_FUNC |
|
2276 //do nothing |
|
2277 } |
|
2278 /** |
|
2279 Calls the appropriate panic function to encode the panic |
|
2280 code with the current state identifier. |
|
2281 @param aPanic The panic code that the state is panicking with. |
|
2282 */ |
|
2283 void CPanAgtStateBase::PanicInState(TPanAgentPanic aPanic) const |
|
2284 { |
|
2285 LOG_FUNC |
|
2286 PanAgentPanic(aPanic, iStateNumber); |
|
2287 } |
|
2288 |
|
2289 #ifdef _DEBUG |
|
2290 void CPanAgtStateBase::DumpDeviceArray() const |
|
2291 /** |
|
2292 Dump the device array to the logs |
|
2293 */ |
|
2294 { |
|
2295 LOG_FUNC |
|
2296 const RPointerArray<CPanRemoteDeviceStateMachine>& deviceArray(StateMachine().Devices()); |
|
2297 |
|
2298 for(TInt i=0; i<deviceArray.Count(); i++) |
|
2299 { |
|
2300 LOG2(_L("Device: %x, state: %d"), deviceArray[i], deviceArray[i]->GetState()); |
|
2301 } |
|
2302 } |
|
2303 #endif // _DEBUG |
|
2304 |
|
2305 |