|
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 /** |
|
17 @file |
|
18 @note PAN agent remote device class implementation, and remote device state base class implementation |
|
19 */ |
|
20 |
|
21 #include <bluetooth/logger.h> |
|
22 #include "panagtlog.h" |
|
23 #include "panagtremdev.h" |
|
24 #include "panagtremdevstates.h" |
|
25 |
|
26 using namespace PanAgent; |
|
27 |
|
28 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
29 #include <elements/nm_signals.h> |
|
30 #include "panmessages.h" |
|
31 |
|
32 using namespace ESock; |
|
33 using namespace Messages; |
|
34 |
|
35 #ifdef ESOCK_EXTLOG_ACTIVE |
|
36 _LIT8(KPanAgtSubTag, "panagt"); |
|
37 #endif |
|
38 |
|
39 #endif |
|
40 // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
41 |
|
42 #ifdef __FLOG_ACTIVE |
|
43 _LIT8(KLogComponent, LOG_COMPONENT_PAN_AGENT); |
|
44 #endif |
|
45 |
|
46 CPanRemoteDeviceStateMachine* CPanRemoteDeviceStateMachine::NewL(RInternalSocket& aConnectedSocket, MRemoteDeviceNotify& aParent, CCommsDbAccess& aDatabase) |
|
47 /** |
|
48 Create a new bnep channel in the nif using an already connected socket. |
|
49 @note This is for incoming connections only. |
|
50 @param aConnectedSocket A preconnected L2CAP socket ready to hand off to BNEP |
|
51 @param aParent The class to be notified when events occur |
|
52 @param aDatabase An handle to the commdb facade to allow us to read records from it |
|
53 */ |
|
54 { |
|
55 CPanRemoteDeviceStateMachine* self = new(ELeave) CPanRemoteDeviceStateMachine(aParent, aDatabase); |
|
56 CleanupStack::PushL(self); |
|
57 self->ConstructL(aConnectedSocket); |
|
58 CleanupStack::Pop(self); |
|
59 return(self); |
|
60 } |
|
61 |
|
62 CPanRemoteDeviceStateMachine* CPanRemoteDeviceStateMachine::NewL(const TBTDevAddr& aRemDevAddr, MRemoteDeviceNotify& aParent, CCommsDbAccess& aDatabase) |
|
63 /** |
|
64 Create a new BNEP channel in the nif by connecting a socket and passing it across. |
|
65 @note This is for outgoing connections only. |
|
66 @param aRemDevAddr A preconnected L2CAP socket ready to hand off to BNEP |
|
67 @param aParent The class to be notified when events occur |
|
68 @param aDatabase An handle to the commdb facade to allow us to read records from it |
|
69 */ |
|
70 { |
|
71 CPanRemoteDeviceStateMachine* self = new(ELeave) CPanRemoteDeviceStateMachine(aParent, aDatabase); |
|
72 CleanupStack::PushL(self); |
|
73 self->ConstructL(aRemDevAddr); |
|
74 CleanupStack::Pop(self); |
|
75 return(self); |
|
76 } |
|
77 |
|
78 CPanRemoteDeviceStateMachine::CPanRemoteDeviceStateMachine(MRemoteDeviceNotify& aParent, CCommsDbAccess& aDatabase) : |
|
79 CActive(KPanAgtAoPriority), iParent(aParent), iDatabase(aDatabase) |
|
80 { |
|
81 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
82 NM_LOG_NODE_CREATE(KPanAgtSubTag, CPanRemoteDeviceStateMachine); |
|
83 #endif |
|
84 CONNECT_LOGGER |
|
85 CActiveScheduler::Add(this); |
|
86 } |
|
87 |
|
88 void CPanRemoteDeviceStateMachine::ConstructL(const TBTDevAddr& aRemDevAddr) |
|
89 /** |
|
90 Connect a new socket and create a BNEP channel to use it. |
|
91 @note This happens for outgoing connections only. |
|
92 */ |
|
93 { |
|
94 iRemSockAddr.SetBTAddr(aRemDevAddr); |
|
95 iRemSockAddr.SetPort(KBnepPsm); |
|
96 iSockServ.Connect(); |
|
97 |
|
98 #ifdef __FLOG_ACTIVE |
|
99 TBuf<KMaxBtAddrSize> tempDevAddrBuf; |
|
100 iRemSockAddr.BTAddr().GetReadable(tempDevAddrBuf, KNullDesC, KBtAddrSeparator, KNullDesC); |
|
101 LOG2(_L("RemDev[%x]: connected to %S"), this, &tempDevAddrBuf); |
|
102 #endif |
|
103 |
|
104 // preallocate the shutdown state |
|
105 iShutdownState = new(ELeave) CPanRemDevStateShutdown(*this); |
|
106 |
|
107 LOG(_L("RemDevStateMachine - Deciding whether to perform SDP query")); |
|
108 TBool sdpQueriesDisabledStatus; |
|
109 Database().GetBoolL(TPtrC(PAN_SERVICE_EXTENSIONS), TPtrC(PAN_DISABLE_SDP_QUERY), sdpQueriesDisabledStatus); |
|
110 |
|
111 SdpQueriesDisabled(sdpQueriesDisabledStatus); |
|
112 |
|
113 // if we're allowed to use SDP, then perform the SDP query |
|
114 CPanRemDevStateBase* nextState; |
|
115 if(!IsSdpQueriesDisabled()) |
|
116 { |
|
117 // open an SDP query subsession |
|
118 LOG(_L("RemDevStateMachine - Connected to remote SDP querier")); |
|
119 User::LeaveIfError(RemoteSdpQuerier().Open()); |
|
120 |
|
121 nextState = new(ELeave) CPanRemDevStatePerformingSdpQuery(*this); |
|
122 } |
|
123 else // SDP queries are inhibited by setting in commdb |
|
124 { |
|
125 LOG(_L("RemDevStateMachine - SDP query inhibited by commdb settings")); |
|
126 nextState = new(ELeave) CPanRemDevStateConnectingSocket(*this); |
|
127 } |
|
128 SetState(*nextState); |
|
129 } |
|
130 |
|
131 void CPanRemoteDeviceStateMachine::ConstructL(RInternalSocket& aConnectedSocket) |
|
132 /** |
|
133 Take a preconnected socket and create a BNEP channel to use it. |
|
134 @note This happens for incoming connections only. |
|
135 */ |
|
136 { |
|
137 User::LeaveIfError(iSocket.Transfer(aConnectedSocket)); // take ownership of the socket, so that the initial state can perform actions on it |
|
138 |
|
139 // make a note of the remote device address |
|
140 iSocket.RemoteName(iRemSockAddr); |
|
141 iSockServ.Connect(); |
|
142 |
|
143 #ifdef __FLOG_ACTIVE |
|
144 TBuf<KMaxBtAddrSize> tempDevAddrBuf; |
|
145 iRemSockAddr.BTAddr().GetReadable(tempDevAddrBuf, KNullDesC, KBtAddrSeparator, KNullDesC); |
|
146 LOG2(_L("RemDev[%x]: connected to %S"), this, &tempDevAddrBuf); |
|
147 #endif |
|
148 |
|
149 // preallocate the shutdown state |
|
150 iShutdownState = new(ELeave) CPanRemDevStateShutdown(*this); |
|
151 |
|
152 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
153 // Create the states first so if we Leave no message is sent to BNEP |
|
154 CPanRemDevStateBase* nextState = new(ELeave) CPanRemDevStatePerformingRoleNegotiationForIncomingConnection(*this); |
|
155 CleanupStack::PushL(nextState); |
|
156 CPanRemDevStatePaused* pausedState = new(ELeave)CPanRemDevStatePaused(*this, *nextState); |
|
157 CleanupStack::Pop(); |
|
158 SetState(*pausedState); |
|
159 |
|
160 CreateNewBnepConnection(iSocket, TPanMessage::EActivityCreateChannelControllerForIncoming); |
|
161 OpenPhysicalLinkAdapterL(); |
|
162 |
|
163 #else |
|
164 // !SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
165 |
|
166 // create the connection |
|
167 CreateNewBnepConnectionL(iSocket); |
|
168 OpenPhysicalLinkAdapterL(); |
|
169 |
|
170 CPanRemDevStateBase* nextState = new(ELeave) CPanRemDevStatePerformingRoleNegotiationForIncomingConnection(*this); |
|
171 SetState(*nextState); |
|
172 #endif |
|
173 // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
174 } |
|
175 |
|
176 CPanRemoteDeviceStateMachine::~CPanRemoteDeviceStateMachine() |
|
177 /** |
|
178 Delete the last state on the way out, and tidy up various other bits and pieces |
|
179 */ |
|
180 { |
|
181 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
182 __ASSERT_DEBUG(iBnepChannelController == TNodeId::NullId(), PanAgentPanic(EDeletingRemoteDeviceWithoutDisconnecting)); |
|
183 #else |
|
184 __ASSERT_DEBUG(!iBnepChannelController, PanAgentPanic(EDeletingRemoteDeviceWithoutDisconnecting)); |
|
185 #endif |
|
186 |
|
187 __ASSERT_DEBUG(iState, PanAgentPanic(ENoStateOnExit)); |
|
188 __ASSERT_DEBUG(!IsActive(), PanAgentPanic(EStillActiveOnExit)); |
|
189 |
|
190 Cancel(); // in release builds, cancel the outstanding request |
|
191 |
|
192 #ifndef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
193 if(iBnepChannelController) |
|
194 iBnepChannelController->Close(); |
|
195 #endif |
|
196 |
|
197 delete iState; |
|
198 iState = NULL; |
|
199 |
|
200 __ASSERT_DEBUG(!iShutdownState, PanAgentPanic(ERemoteDeviceDidNotUsePreallocatedShutdownState)); |
|
201 // everyone should be shutting down by leaving from the appropriate method and letting the |
|
202 // state machine clean up/shut down the connection. If this pointer is not NULL, it suggests |
|
203 // that someone's created the shutdown state directly (which can fail in OOM situations) |
|
204 delete iShutdownState; // delete the shutdown state if it exists |
|
205 iSocket.Close(); // shouldn't be open, but just in case |
|
206 iPhysicalLinkAdapter.Close(); |
|
207 iRemoteSdpQuerier.Close(); |
|
208 iSockServ.Close(); |
|
209 |
|
210 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
211 NM_LOG_NODE_DESTROY(KPanAgtSubTag, CPanRemoteDeviceStateMachine); |
|
212 #endif |
|
213 CLOSE_LOGGER |
|
214 } |
|
215 |
|
216 |
|
217 // |
|
218 // CActive methods |
|
219 // |
|
220 |
|
221 void CPanRemoteDeviceStateMachine::RunL() |
|
222 /** |
|
223 Called when the new socket is connected |
|
224 @note Only used when creating a new socket for an outgoing connection |
|
225 */ |
|
226 { |
|
227 __ASSERT_ALWAYS(iState, PanAgentPanic(ENoRemDevState)); |
|
228 |
|
229 TRAPD(err, iState->AsyncEventCompleteL()); |
|
230 if(err) |
|
231 { |
|
232 Shutdown(err); |
|
233 } |
|
234 } |
|
235 |
|
236 void CPanRemoteDeviceStateMachine::DoCancel() |
|
237 /** |
|
238 Cancel the connection |
|
239 */ |
|
240 { |
|
241 __ASSERT_ALWAYS(iState, PanAgentPanic(ENoRemDevState)); |
|
242 |
|
243 TRAPD(err, iState->AsyncEventCancelL()); |
|
244 if(err) |
|
245 { |
|
246 Shutdown(err); |
|
247 } |
|
248 } |
|
249 |
|
250 // |
|
251 // Other state machine downcall methods |
|
252 // |
|
253 |
|
254 void CPanRemoteDeviceStateMachine::ReadyForRoleRequest() |
|
255 /** |
|
256 Pass the request from the local device to the appropriate control channel. |
|
257 Called from the state machine when it's ready to negotiate roles for this connection |
|
258 @note This can be called when the connection is active, and indicates that the state machine wants to renegotiate roles |
|
259 @note Clients must set a flag and initiate a callback to start the RoleRequest() process to prevent call stacks from getting too large |
|
260 */ |
|
261 { |
|
262 __ASSERT_ALWAYS(iState, PanAgentPanic(ENoRemDevState)); |
|
263 |
|
264 TRAPD(err, iState->ReadyForRoleRequestL()); |
|
265 if(err) |
|
266 { |
|
267 Cancel(); // cancel any outstanding async requests that states may have had running before shutting down |
|
268 // note - not all states use async requests, so this may have no effect |
|
269 Shutdown(err); |
|
270 } |
|
271 } |
|
272 |
|
273 void CPanRemoteDeviceStateMachine::Disconnect() |
|
274 /** |
|
275 Locally initiated disconnect |
|
276 */ |
|
277 { |
|
278 __ASSERT_ALWAYS(iState, PanAgentPanic(ENoRemDevState)); |
|
279 |
|
280 TRAPD(err, iState->ShutdownL()); |
|
281 if(err) |
|
282 { |
|
283 Cancel(); // cancel any outstanding async requests that states may have had running before shutting down |
|
284 // note - not all states use async requests, so this may have no effect |
|
285 Shutdown(err); |
|
286 } |
|
287 } |
|
288 |
|
289 TInt CPanRemoteDeviceStateMachine::DisallowRoleSwitch() |
|
290 /** |
|
291 Change the link policy to prevent other devices performing master/slave switches |
|
292 @note This is intended to lock us in the master role |
|
293 */ |
|
294 { |
|
295 TInt err = iPhysicalLinkAdapter.PreventRoleSwitch(); |
|
296 |
|
297 #ifdef __FLOG_ACTIVE |
|
298 TBuf<KMaxBtAddrSize> tempDevAddrBuf; |
|
299 iRemSockAddr.BTAddr().GetReadable(tempDevAddrBuf, KNullDesC, KBtAddrSeparator, KNullDesC); |
|
300 LOG2(_L("RemDev[%S]: ...prevent role change returned %d"), &tempDevAddrBuf, err); |
|
301 #endif |
|
302 |
|
303 return err; |
|
304 } |
|
305 |
|
306 TInt CPanRemoteDeviceStateMachine::AllowRoleSwitch() |
|
307 /** |
|
308 Change the link policy to allow other devices to perform master/slave switches |
|
309 */ |
|
310 { |
|
311 TInt err = iPhysicalLinkAdapter.AllowRoleSwitch(); |
|
312 |
|
313 #ifdef __FLOG_ACTIVE |
|
314 TBuf<KMaxBtAddrSize> tempDevAddrBuf; |
|
315 iRemSockAddr.BTAddr().GetReadable(tempDevAddrBuf, KNullDesC, KBtAddrSeparator, KNullDesC); |
|
316 LOG2(_L("RemDev[%S]: ...allow role change returned %d"), &tempDevAddrBuf, err); |
|
317 #endif |
|
318 |
|
319 return err; |
|
320 } |
|
321 |
|
322 TBTDevAddr CPanRemoteDeviceStateMachine::DevAddr() const |
|
323 /** |
|
324 Return the device address of the remote device |
|
325 */ |
|
326 { |
|
327 return(iRemSockAddr.BTAddr()); |
|
328 } |
|
329 |
|
330 // |
|
331 // MPanConnectionNotify methods |
|
332 // |
|
333 |
|
334 void CPanRemoteDeviceStateMachine::BnepRoleRequestFromRemoteDevice(const TUUID& aRequestedLocalRole, const TUUID& aRequestedRemoteRole) |
|
335 /** |
|
336 Request from remote device for given BNEP roles |
|
337 */ |
|
338 { |
|
339 __ASSERT_ALWAYS(iState, PanAgentPanic(ENoRemDevState)); |
|
340 |
|
341 TRAPD(err, iState->BnepRoleRequestFromRemoteDeviceL(aRequestedLocalRole, aRequestedRemoteRole)); |
|
342 if(err) |
|
343 { |
|
344 Cancel(); // cancel any outstanding async requests that states may have had running before shutting down |
|
345 // note - not all states use async requests, so this may have no effect |
|
346 Shutdown(err); |
|
347 } |
|
348 } |
|
349 |
|
350 void CPanRemoteDeviceStateMachine::BnepRoleResponseFromRemoteDevice(TBnepSetupConnectionResponseMessage aRoleResponseCode) |
|
351 /** |
|
352 Response from remote device to our request for BNEP roles |
|
353 */ |
|
354 { |
|
355 __ASSERT_ALWAYS(iState, PanAgentPanic(ENoRemDevState)); |
|
356 |
|
357 TRAPD(err, iState->BnepRoleResponseFromRemoteDeviceL(aRoleResponseCode)); |
|
358 if(err) |
|
359 { |
|
360 Cancel(); // cancel any outstanding async requests that states may have had running before shutting down |
|
361 // note - not all states use async requests, so this may have no effect |
|
362 Shutdown(err); |
|
363 } |
|
364 } |
|
365 |
|
366 void CPanRemoteDeviceStateMachine::SetRetryConnect() |
|
367 { |
|
368 iParent.SetRetryConnect(*this); |
|
369 } |
|
370 |
|
371 void CPanRemoteDeviceStateMachine::RemoteDeviceDisconnect(TInt aError) |
|
372 /** |
|
373 The remote device has disconnected |
|
374 */ |
|
375 { |
|
376 __ASSERT_ALWAYS(iState, PanAgentPanic(ENoRemDevState)); |
|
377 |
|
378 TRAPD(err, iState->RemoteDeviceDisconnectL(aError)); |
|
379 if(err) |
|
380 { |
|
381 Cancel(); // cancel any outstanding async requests that states may have had running before shutting down |
|
382 // note - not all states use async requests, so this may have no effect |
|
383 Shutdown(err); |
|
384 } |
|
385 } |
|
386 |
|
387 TInt CPanRemoteDeviceStateMachine::IncrementConnectionRetryAttempts() |
|
388 { |
|
389 return iConnectionRetryAttempts++; |
|
390 } |
|
391 |
|
392 void CPanRemoteDeviceStateMachine::ResetConnectionRetryAttempts() |
|
393 { |
|
394 iConnectionRetryAttempts = 0; |
|
395 } |
|
396 |
|
397 void CPanRemoteDeviceStateMachine::ResetRetryParameters() |
|
398 { |
|
399 iRemoteWorthTryingRoles.ResetWorthTryingRoles(); |
|
400 } |
|
401 |
|
402 TBool CPanRemoteDeviceStateMachine::WorthTrying() |
|
403 { |
|
404 LOG(_L("CPanRemoteDeviceStateMachine::WorthTrying")); |
|
405 TBool retval = EFalse; // assume its not worth retrying until we prove otherwise |
|
406 |
|
407 if(iParent.WorthTrying(iRemoteWorthTryingRoles)) |
|
408 { |
|
409 if (RemoteWorthTryingRolesList().IsWorthTryingU()) |
|
410 { |
|
411 retval = ETrue; |
|
412 } |
|
413 else if (RemoteWorthTryingRolesList().IsWorthTryingGn()) |
|
414 { |
|
415 retval = ETrue; |
|
416 } |
|
417 else if (RemoteWorthTryingRolesList().IsWorthTryingNap()) |
|
418 { |
|
419 retval = ETrue; |
|
420 } |
|
421 } |
|
422 return(retval); |
|
423 } |
|
424 |
|
425 TRemoteDeviceState CPanRemoteDeviceStateMachine::GetState() const |
|
426 { |
|
427 TRemoteDeviceState state = EIdle; |
|
428 if(iState) |
|
429 { |
|
430 state = iState->GetState(); |
|
431 } |
|
432 return state; |
|
433 } |
|
434 |
|
435 TBool CPanRemoteDeviceStateMachine::NewConnectedDeviceProgressSent() const |
|
436 { |
|
437 return iNewConnectedDeviceProgressSent; |
|
438 } |
|
439 |
|
440 void CPanRemoteDeviceStateMachine::SetNewConnectedDeviceProgressSent(TBool aNewConnectedDeviceProgressSent) |
|
441 { |
|
442 iNewConnectedDeviceProgressSent = aNewConnectedDeviceProgressSent; |
|
443 } |
|
444 |
|
445 #ifndef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
446 MPanLinkControlBase& CPanRemoteDeviceStateMachine::BnepConnectionController() |
|
447 { |
|
448 return iParent.BnepConnectionController(); |
|
449 } |
|
450 #endif |
|
451 |
|
452 |
|
453 |
|
454 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
455 /** |
|
456 */ |
|
457 void CPanRemoteDeviceStateMachine::ReceivedL(const Messages::TRuntimeCtxId& aSender, const Messages::TNodeId& /* aRecipient */, Messages::TSignatureBase& aCFMessage) |
|
458 { |
|
459 if (aCFMessage.MessageId().Realm() == TPanMessage::ERealmId) |
|
460 { |
|
461 switch (aCFMessage.MessageId().MessageId()) |
|
462 { |
|
463 case TPanMessage::TChannelControllerCreated::EId: |
|
464 { |
|
465 const TNodeCtxId& ctxId = address_cast<TNodeCtxId> (aSender); |
|
466 TUint activityId = ctxId.NodeCtx(); |
|
467 TPanMessage::TChannelControllerCreated& msg = message_cast<TPanMessage::TChannelControllerCreated>(aCFMessage); |
|
468 if (activityId == TPanMessage::EActivityCreateChannelControllerForIncoming) |
|
469 { |
|
470 // We now know that the socket has been transfered, or an error has occured |
|
471 // and that either way it is now safe for the incoming connection listener |
|
472 // to continue accepting connections |
|
473 iParent.RestartIncomingConnectionListener(msg.iValue); |
|
474 } |
|
475 |
|
476 if (msg.iValue == KErrNone) |
|
477 { |
|
478 // Channel controller created - transition into whatever next |
|
479 // state is waiting |
|
480 iBnepChannelController = aSender; |
|
481 |
|
482 // We would expect that iState should always be the paused state when |
|
483 // we get here. We assert it in debug builds in case something we |
|
484 // haven't accounted for changes it unexpectedly |
|
485 __ASSERT_DEBUG(iState->iStateNumber == CPanRemDevStateBase::EPanRemDevStatePaused, PanAgentPanic(EPanAgtUnexpectedStateChange)); |
|
486 if (iState->iStateNumber == CPanRemDevStateBase::EPanRemDevStatePaused) |
|
487 { |
|
488 // Calling AsyncEventCompleteL() on the paused state will make it |
|
489 // transition to the real state, start its OnEntryL() processing |
|
490 TRAPD(err, iState->AsyncEventCompleteL()); |
|
491 if (err != KErrNone) |
|
492 { |
|
493 Shutdown(err); |
|
494 } |
|
495 } |
|
496 } |
|
497 else |
|
498 { |
|
499 // Error handling for the TCreateChannelController |
|
500 if (activityId == TPanMessage::EActivityCreateChannelControllerForIncoming) |
|
501 { |
|
502 // For outgoing (initial connect or retry connect) the handling should |
|
503 // be a call to Shutdown(msg.iValue); |
|
504 Shutdown(msg.iValue); |
|
505 } |
|
506 else if (activityId != TPanMessage::EActivityCreateChannelControllerForIncoming) |
|
507 { |
|
508 __ASSERT_DEBUG(EFalse, PanAgentPanic(EPanAgtUnexpectedMessage)); |
|
509 } |
|
510 } |
|
511 } |
|
512 break; |
|
513 |
|
514 case TPanMessage::TRoleRequestFromRemoteDevice::EId: |
|
515 { |
|
516 TPanMessage::TRoleRequestFromRemoteDevice& msg = message_cast<TPanMessage::TRoleRequestFromRemoteDevice>(aCFMessage); |
|
517 BnepRoleRequestFromRemoteDevice(msg.iRequestedLocalRole, msg.iRequestedRemoteRole); |
|
518 } |
|
519 break; |
|
520 |
|
521 case TPanMessage::TRoleResponseFromRemoteDevice::EId: |
|
522 { |
|
523 TPanMessage::TRoleResponseFromRemoteDevice& msg = message_cast<TPanMessage::TRoleResponseFromRemoteDevice>(aCFMessage); |
|
524 BnepRoleResponseFromRemoteDevice(msg.iSetupResponse); |
|
525 } |
|
526 break; |
|
527 |
|
528 case TPanMessage::TRemoteDeviceDisconnect::EId: |
|
529 { |
|
530 TPanMessage::TRemoteDeviceDisconnect& msg = message_cast<TPanMessage::TRemoteDeviceDisconnect>(aCFMessage); |
|
531 RemoteDeviceDisconnect(msg.iValue); |
|
532 } |
|
533 break; |
|
534 |
|
535 default: |
|
536 __ASSERT_DEBUG(EFalse, PanAgentPanic(EPanAgtUnexpectedMessage)); |
|
537 break; |
|
538 } |
|
539 } |
|
540 else |
|
541 { |
|
542 __ASSERT_DEBUG(EFalse, PanAgentPanic(EPanAgtUnexpectedMessage)); |
|
543 } |
|
544 |
|
545 // Absorb messages |
|
546 aCFMessage.ClearMessageId(); |
|
547 } |
|
548 #endif |
|
549 // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
550 |
|
551 |
|
552 // |
|
553 // MPanAgtRemDevStateMachineNotify methods |
|
554 // |
|
555 |
|
556 // |
|
557 // getter methods |
|
558 // |
|
559 TBluetoothPanRole& CPanRemoteDeviceStateMachine::LocalRole() |
|
560 /** |
|
561 Get a handle to the local role |
|
562 */ |
|
563 { |
|
564 return(iLocalRole); |
|
565 } |
|
566 |
|
567 TBluetoothPanRole& CPanRemoteDeviceStateMachine::RemoteRole() |
|
568 /** |
|
569 Get a handle to the remote role |
|
570 */ |
|
571 { |
|
572 return(iRemoteRole); |
|
573 } |
|
574 |
|
575 RPanRemoteSdpQuerier& CPanRemoteDeviceStateMachine::RemoteSdpQuerier() |
|
576 /** |
|
577 Get handle to PAN remote SDP querier |
|
578 */ |
|
579 { |
|
580 return(iRemoteSdpQuerier); |
|
581 } |
|
582 |
|
583 |
|
584 TPanDeviceRolesList& CPanRemoteDeviceStateMachine::RemoteRolesList() |
|
585 /** |
|
586 Return a handle to the remote device roles list |
|
587 */ |
|
588 { |
|
589 return(iRemotePanRolesFromSdp); |
|
590 } |
|
591 |
|
592 TPanDeviceWorthTryingRolesList& CPanRemoteDeviceStateMachine::RemoteWorthTryingRolesList() |
|
593 /** |
|
594 Return a handle to the remote device roles list |
|
595 */ |
|
596 { |
|
597 return(iRemoteWorthTryingRoles); |
|
598 } |
|
599 |
|
600 TBTSockAddr& CPanRemoteDeviceStateMachine::RemSockAddr() |
|
601 /** |
|
602 Return the remote device address |
|
603 */ |
|
604 { |
|
605 return(iRemSockAddr); |
|
606 } |
|
607 |
|
608 RInternalSocket& CPanRemoteDeviceStateMachine::Socket() |
|
609 /** |
|
610 Get a handle to the socket |
|
611 */ |
|
612 { |
|
613 return(iSocket); |
|
614 } |
|
615 |
|
616 CCommsDbAccess& CPanRemoteDeviceStateMachine::Database() |
|
617 /** |
|
618 Get a handle to commdb |
|
619 */ |
|
620 { |
|
621 return(iDatabase); |
|
622 } |
|
623 |
|
624 TRequestStatus& CPanRemoteDeviceStateMachine::Status() |
|
625 /** |
|
626 Return this objects TRequestStatus |
|
627 */ |
|
628 { |
|
629 return(iStatus); |
|
630 } |
|
631 |
|
632 TBool CPanRemoteDeviceStateMachine::IsSdpQueriesDisabled() |
|
633 /** |
|
634 Are SDP queries disabled by settings in commdb? |
|
635 */ |
|
636 { |
|
637 return(iSdpQueriesDisabled); |
|
638 } |
|
639 void CPanRemoteDeviceStateMachine::SdpQueriesDisabled(TBool aSdpQueriesStatus) |
|
640 { |
|
641 iSdpQueriesDisabled = aSdpQueriesStatus; |
|
642 } |
|
643 |
|
644 TInt CPanRemoteDeviceStateMachine::Error() const |
|
645 /** |
|
646 Return the last error to occur |
|
647 */ |
|
648 { |
|
649 return(iError); |
|
650 } |
|
651 |
|
652 TBool CPanRemoteDeviceStateMachine::HasBnepChannel() const |
|
653 /** |
|
654 Have we got to a stage where we have a BNEP channel open? |
|
655 */ |
|
656 { |
|
657 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
658 return(iBnepChannelController != TNodeId::NullId() ? ETrue : EFalse); |
|
659 #else |
|
660 return(iBnepChannelController ? ETrue : EFalse); |
|
661 #endif |
|
662 } |
|
663 |
|
664 // |
|
665 // do'er methods |
|
666 // |
|
667 void CPanRemoteDeviceStateMachine::SetActive() |
|
668 /** |
|
669 Set this object active |
|
670 */ |
|
671 { |
|
672 CActive::SetActive(); |
|
673 } |
|
674 |
|
675 void CPanRemoteDeviceStateMachine::Cancel() |
|
676 /** |
|
677 Cancel the outstanding request |
|
678 */ |
|
679 { |
|
680 CActive::Cancel(); |
|
681 } |
|
682 |
|
683 void CPanRemoteDeviceStateMachine::DeviceActive() |
|
684 /** |
|
685 Inform the PAN agent role state machine that we are active |
|
686 */ |
|
687 { |
|
688 iParent.DeviceActive(*this); |
|
689 } |
|
690 |
|
691 void CPanRemoteDeviceStateMachine::RoleChangeFailed() |
|
692 /** |
|
693 Inform the PAN agent role state machine that the role upgrade failed |
|
694 */ |
|
695 { |
|
696 iParent.DeviceRoleChangeFailed(*this); |
|
697 } |
|
698 |
|
699 void CPanRemoteDeviceStateMachine::ShutdownComplete() |
|
700 /** |
|
701 Inform the PAN agent role state machine that we have shut down |
|
702 */ |
|
703 { |
|
704 iParent.DeviceDisconnected(*this); |
|
705 } |
|
706 |
|
707 TInt CPanRemoteDeviceStateMachine::InitiateOutgoingConnection(TBluetoothPanRole& aLocalRole, TBluetoothPanRole& aRemoteRole, TPanDeviceWorthTryingRolesList& aWorthTryingRemoteRoles) |
|
708 { |
|
709 return iParent.InitiateOutgoingConnection(aLocalRole, aRemoteRole, aWorthTryingRemoteRoles); |
|
710 } |
|
711 |
|
712 TInt CPanRemoteDeviceStateMachine::PerformLocalRoleChangeRequest(TBluetoothPanRole& aLocalRole, TBluetoothPanRole& aRemoteRole) |
|
713 { |
|
714 return iParent.PerformLocalRoleChangeRequest(aLocalRole, aRemoteRole); |
|
715 } |
|
716 |
|
717 TInt CPanRemoteDeviceStateMachine::RoleChangeRequestFromPeer(TBluetoothPanRole aLocalRole, TBluetoothPanRole aRemoteRole) |
|
718 { |
|
719 return iParent.RoleChangeRequestFromPeer(aLocalRole, aRemoteRole); |
|
720 } |
|
721 |
|
722 TInt CPanRemoteDeviceStateMachine::IncomingConnectionFromPeer(TBluetoothPanRole aLocalRole, TBluetoothPanRole aRemoteRole) |
|
723 { |
|
724 return iParent.IncomingConnectionFromPeer(aLocalRole, aRemoteRole); |
|
725 } |
|
726 |
|
727 void CPanRemoteDeviceStateMachine::SendRoleRequest(TBluetoothPanRole aLocalRole, TBluetoothPanRole aRemoteRole) |
|
728 /** |
|
729 Send a role request to the remote device |
|
730 @param aLocalRole The proposed local role |
|
731 @param aRemoteRole The proposed remote role |
|
732 */ |
|
733 { |
|
734 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
735 LOG3(_L("RemDev[%x]: - sending role request, local: %x, remote: %x"), this, aLocalRole, aRemoteRole); |
|
736 __ASSERT_ALWAYS(iBnepChannelController != TNodeId::NullId(), PanAgentPanic(ECallToBnepChannelBeforeChannelSetup)); |
|
737 __ASSERT_DEBUG(aLocalRole!=EPanRoleUnknown, PanAgentPanic(ESendingUnknownRoleInRoleRequest)); |
|
738 __ASSERT_DEBUG(aRemoteRole!=EPanRoleUnknown, PanAgentPanic(ESendingUnknownRoleInRoleRequest)); |
|
739 |
|
740 TPanMessage::TRoleRequestFromLocalDevice msg(aLocalRole, aRemoteRole); |
|
741 RClientInterface::OpenPostMessageClose(Id(),iBnepChannelController,msg); |
|
742 |
|
743 #else |
|
744 // !SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
745 __ASSERT_ALWAYS(iBnepChannelController, PanAgentPanic(ECallToBnepChannelBeforeChannelSetup)); |
|
746 __ASSERT_DEBUG(aLocalRole!=EPanRoleUnknown, PanAgentPanic(ESendingUnknownRoleInRoleRequest)); |
|
747 __ASSERT_DEBUG(aRemoteRole!=EPanRoleUnknown, PanAgentPanic(ESendingUnknownRoleInRoleRequest)); |
|
748 |
|
749 LOG3(_L("RemDev[%x]: - sending role request, local: %x, remote: %x"), this, aLocalRole, aRemoteRole); |
|
750 |
|
751 iBnepChannelController->BnepRoleRequestFromLocalDevice(aLocalRole, aRemoteRole); |
|
752 #endif |
|
753 // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
754 } |
|
755 |
|
756 void CPanRemoteDeviceStateMachine::SendRoleResponse(TBnepSetupConnectionResponseMessage aRoleResponseCode) |
|
757 /** |
|
758 Send a role reponse to the remote device |
|
759 @param aRoleReponseCode A BNEP error code indicating the status of the request |
|
760 */ |
|
761 { |
|
762 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
763 __ASSERT_ALWAYS(iBnepChannelController != TNodeId::NullId(), PanAgentPanic(ECallToBnepChannelBeforeChannelSetup)); |
|
764 |
|
765 TPanMessage::TRoleResponseFromLocalDevice msg(aRoleResponseCode); |
|
766 RClientInterface::OpenPostMessageClose(Id(),iBnepChannelController,msg); |
|
767 #else |
|
768 // !SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
769 |
|
770 __ASSERT_ALWAYS(iBnepChannelController, PanAgentPanic(ECallToBnepChannelBeforeChannelSetup)); |
|
771 iBnepChannelController->BnepRoleResponseFromLocalDevice(aRoleResponseCode); |
|
772 #endif |
|
773 // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
774 } |
|
775 |
|
776 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
777 /** |
|
778 Get BNEP to create a new BNEP level connection for this remote device |
|
779 */ |
|
780 void CPanRemoteDeviceStateMachine::CreateNewBnepConnection(RInternalSocket& aConnectedSocket, TPanMessage::TPanActivity aActivity) |
|
781 { |
|
782 __ASSERT_DEBUG(iBnepChannelController == TNodeId::NullId(), PanAgentPanic(EChannelControllerAlreadyExists)); |
|
783 |
|
784 TPanMessage::TCreateChannelController msg(&aConnectedSocket); |
|
785 RClientInterface::OpenPostMessageClose(TNodeCtxId(aActivity,Id()),iParent.BnepConnectionManager(),msg); |
|
786 } |
|
787 |
|
788 #else |
|
789 // !SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
790 |
|
791 /** |
|
792 Get BNEP to create a new BNEP level connection for this remote device |
|
793 */ |
|
794 void CPanRemoteDeviceStateMachine::CreateNewBnepConnectionL(RInternalSocket& aConnectedSocket) |
|
795 { |
|
796 __ASSERT_DEBUG(!iBnepChannelController, PanAgentPanic(EChannelControllerAlreadyExists)); |
|
797 iBnepChannelController = &(iParent.BnepConnectionManager().NewBnepConnectionL(aConnectedSocket, *this)); |
|
798 } |
|
799 #endif |
|
800 // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
801 |
|
802 |
|
803 void CPanRemoteDeviceStateMachine::DisconnectBnepChannel() |
|
804 /** |
|
805 Tell the BNEP channel to disconnect; if there is no BNEP channel, just return |
|
806 */ |
|
807 { |
|
808 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
809 if(iBnepChannelController != TNodeId::NullId()) |
|
810 { |
|
811 TPanMessage::TCloseChannelController msg; |
|
812 RClientInterface::OpenPostMessageClose(Id(),iBnepChannelController,msg); |
|
813 iBnepChannelController = TNodeId::NullId(); |
|
814 } |
|
815 |
|
816 #else |
|
817 // !SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
818 if(iBnepChannelController) |
|
819 { |
|
820 iBnepChannelController->Close(); // shutdown the connection if it exists and detach this object from BNEP |
|
821 iBnepChannelController = NULL; |
|
822 } |
|
823 #endif |
|
824 // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
825 } |
|
826 |
|
827 void CPanRemoteDeviceStateMachine::SetUplinkAccessAllowed(TBool aAllowed) |
|
828 { |
|
829 // Nothing to be done if the argument matches the current state. |
|
830 if(aAllowed != iUplinkAccessAllowed) |
|
831 { |
|
832 if(aAllowed) |
|
833 { |
|
834 // Close any existing connection that has access to the uplink |
|
835 // THIS SHOULD BE REMOVED WHEN >1 REMOTE DEVICE IS ALLOWED TO ACCESS THE UPLINK. |
|
836 iParent.CloseExistingConnectionWithUplinkAccess(); |
|
837 } |
|
838 |
|
839 iUplinkAccessAllowed = aAllowed; |
|
840 |
|
841 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
842 // Inform BNEP that packets can be forwarded to the uplink |
|
843 TPanMessage::TSetUplinkAccessAllowedForBnepLink msg(iUplinkAccessAllowed); |
|
844 RClientInterface::OpenPostMessageClose(Id(),iBnepChannelController,msg); |
|
845 |
|
846 #else |
|
847 // Inform BNEP that packets can be forwarded to the uplink |
|
848 iBnepChannelController->SetUplinkAccessAllowedForBnepLink(iUplinkAccessAllowed); |
|
849 #endif |
|
850 } |
|
851 } |
|
852 |
|
853 TBool CPanRemoteDeviceStateMachine::UplinkAccessAllowed() const |
|
854 { |
|
855 return iUplinkAccessAllowed; |
|
856 } |
|
857 |
|
858 void CPanRemoteDeviceStateMachine::SetState(CPanRemDevStateBase& aState) |
|
859 /** |
|
860 Change the current state to the one provided |
|
861 */ |
|
862 { |
|
863 iState = &aState; |
|
864 TRAPD(err, iState->OnEntryL()); |
|
865 if(err) |
|
866 { |
|
867 Cancel(); // cancel any outstanding async requests that states may have had running before shutting down |
|
868 // note - not all states use async requests, so this may have no effect |
|
869 Shutdown(err); |
|
870 } |
|
871 } |
|
872 |
|
873 RBTPhysicalLinkAdapter& CPanRemoteDeviceStateMachine::PhysicalLinkAdapter() |
|
874 { |
|
875 return iPhysicalLinkAdapter; |
|
876 } |
|
877 |
|
878 void CPanRemoteDeviceStateMachine::OpenPhysicalLinkAdapterL() |
|
879 { |
|
880 TBTDevAddr addr = RemSockAddr().BTAddr(); |
|
881 User::LeaveIfError( iPhysicalLinkAdapter.Open(iSockServ, addr) ); |
|
882 } |
|
883 |
|
884 void CPanRemoteDeviceStateMachine::Shutdown(TInt aErr) |
|
885 /** |
|
886 Shutdown the connection using the preallocated shutdown state |
|
887 @note This can either be because an unrecoverable error occured, or just a normal shutdown |
|
888 */ |
|
889 { |
|
890 __ASSERT_ALWAYS(iShutdownState, PanAgentPanic(EDoubleShutdownAttemptOnDevice)); |
|
891 |
|
892 iError = aErr; |
|
893 |
|
894 // set the member pointer to NULL to indicate that we've gone to the shutdown state |
|
895 CPanRemDevStateBase* shutdownState = iShutdownState; // take a copy of the pointer, so we can NULLify the one in the class |
|
896 iShutdownState = NULL; // shutdown is about to be the active state, so drop the second pointer to it |
|
897 |
|
898 // if the state has left, then it won't have performed the setup of the next state correctly |
|
899 // this code performs the same actions to cleanup the old state and activate the new, but in |
|
900 // reverse order - otherwise we'd lose the pointer to the old state when we activated the new |
|
901 delete iState; |
|
902 iState = NULL; |
|
903 SetState(*shutdownState); |
|
904 } |
|
905 |
|
906 void CPanRemoteDeviceStateMachine::GetExistingConnections(TPanConnectionList& aPanConnectionList) |
|
907 { |
|
908 iParent.GetExistingConnections(aPanConnectionList); |
|
909 } |
|
910 |
|
911 |
|
912 // |
|
913 // State base class implementations |
|
914 // |
|
915 |
|
916 CPanRemDevStateBase::CPanRemDevStateBase(MPanRemDevStateMachineNotify& aStateMachine, TPanRemDevStates aStateNumber) : |
|
917 #ifdef _DEBUG |
|
918 iStateMachine(aStateMachine), iStateNumber(aStateNumber) |
|
919 #else |
|
920 iStateMachine(aStateMachine), iStateNumber(aStateNumber) |
|
921 #endif // _DEBUG |
|
922 /** |
|
923 Stash the state machine handle in our variable |
|
924 */ |
|
925 { } |
|
926 |
|
927 CPanRemDevStateBase::~CPanRemDevStateBase() |
|
928 /** |
|
929 Nothing to do here... |
|
930 */ |
|
931 { } |
|
932 |
|
933 /** |
|
934 Calls the appropriate panic function to encode the panic |
|
935 code with the current state identifier. |
|
936 @param aPanic The panic code that the state is panicking with. |
|
937 */ |
|
938 void CPanRemDevStateBase::PanicInState(TPanAgentPanic aPanic) const |
|
939 { |
|
940 PanAgentPanic(aPanic, iStateNumber); |
|
941 } |
|
942 |
|
943 void CPanRemDevStateBase::BnepRoleRequestFromRemoteDeviceL(const TUUID& /*aRequestedLocalRole*/, const TUUID& /*aRequestedRemoteRole*/) |
|
944 /** |
|
945 Base class implementation - should never be called |
|
946 */ |
|
947 { |
|
948 PanicInState(EInvalidBnepRoleRequestReceived); |
|
949 } |
|
950 |
|
951 void CPanRemDevStateBase::BnepRoleResponseFromRemoteDeviceL(TBnepSetupConnectionResponseMessage /*aRoleResponseCode*/) |
|
952 /** |
|
953 Base class implementation - should never be called |
|
954 */ |
|
955 { |
|
956 PanicInState(EInvalidBnepRoleResponseReceived); |
|
957 } |
|
958 |
|
959 void CPanRemDevStateBase::RemoteDeviceDisconnectL(TInt /*aError*/) |
|
960 /** |
|
961 Base class implementation - should never be called |
|
962 */ |
|
963 { |
|
964 PanicInState(EInvalidRemoteDeviceDisconnectReceived); |
|
965 } |
|
966 |
|
967 void CPanRemDevStateBase::ReadyForRoleRequestL() |
|
968 /** |
|
969 Base class implementation - should never be called |
|
970 */ |
|
971 { |
|
972 PanicInState(EInvalidReadyForRoleRequestReceived); |
|
973 } |
|
974 |
|
975 void CPanRemDevStateBase::AsyncEventCompleteL() |
|
976 /** |
|
977 Base class implementation - should never be called |
|
978 */ |
|
979 { |
|
980 PanicInState(EUnexpectedAsyncEventReceivedByState); |
|
981 } |
|
982 |
|
983 void CPanRemDevStateBase::AsyncEventCancelL() |
|
984 /** |
|
985 Base class implementation - should never be called |
|
986 */ |
|
987 { |
|
988 PanicInState(EUnexpectedAsyncEventReceivedByState); |
|
989 } |
|
990 |
|
991 TInt CPanRemDevStateBase::PerformMasterSlaveSwitchIfNecessary(TBluetoothPanRole aLocalRole) |
|
992 /** |
|
993 |
|
994 */ |
|
995 { |
|
996 TInt rerr = KErrNone; |
|
997 __ASSERT_ALWAYS((aLocalRole==EPanRoleU)||(aLocalRole==EPanRoleGn)||(aLocalRole==EPanRoleNap), PanicInState(ETryingToDecideWhetherToBecomePiconetMasterBasedOnInvalidRole)); |
|
998 |
|
999 if(aLocalRole==EPanRoleU) |
|
1000 { |
|
1001 LOG1(_L("RemDevSB: ...local role %x, don't need to be master"), aLocalRole); |
|
1002 } |
|
1003 else // we *must* be piconet master |
|
1004 { |
|
1005 // Check the current Master Slave role for this physical link. |
|
1006 TUint32 currentPhyState; |
|
1007 TInt err = StateMachine().PhysicalLinkAdapter().PhysicalLinkState(currentPhyState); |
|
1008 LOG2(_L("PerformMasterSlaveSwitchIfNecessary: PhysicalLinkState Err = %d, Link State = %x"), |
|
1009 err, currentPhyState); |
|
1010 |
|
1011 // If the current PHY state was retrieved successfully and the state indicates that |
|
1012 // this device is not currently master of the PHY then attempt to switch roles. |
|
1013 if(err == KErrNone && !(currentPhyState & ENotifyMaster)) |
|
1014 { |
|
1015 rerr = BecomePiconetMaster(); |
|
1016 } |
|
1017 else |
|
1018 { |
|
1019 // The represents the following logic: |
|
1020 // If retrieval of PHY state succeed but the local device is already master then |
|
1021 // return KErrNone. |
|
1022 // Otherwise return the failure reason from the PhysicalLinkState method. |
|
1023 rerr = err; |
|
1024 } |
|
1025 } |
|
1026 |
|
1027 return rerr; |
|
1028 } |
|
1029 |
|
1030 void CPanRemDevStateBase::ConvertUuidsToPanRolesL(const TUUID& aLocalRoleUuid, const TUUID& aRemoteRoleUuid, TBluetoothPanRole& aLocalRole, TBluetoothPanRole& aRemoteRole) |
|
1031 /** |
|
1032 Convert the supplied UUIDs to TBluetoothPanRoles |
|
1033 @note If this method leaves with an invalid UUID error, it will have sent a response to the |
|
1034 remote device with the appropriate failure code |
|
1035 @param aLocalRoleUuid The local role UUID |
|
1036 @param aRemoteRoleUuid The remote role UUID |
|
1037 @param aLocalRole On return, contains the local PAN role UUID in TBluetoothPanRole form |
|
1038 @param aRemoteRole On return, contains the remote PAN role UUID in TBluetoothPanRole form |
|
1039 @leave KErrInvalidDestinationServiceUuid, if the destination service UUID is invalid; KErrInvalidSourceServiceUuid if the source service UUID is invalid |
|
1040 */ |
|
1041 { |
|
1042 TInt err; |
|
1043 err = UuidToPanRole(aLocalRoleUuid, aLocalRole); |
|
1044 if(err) |
|
1045 { |
|
1046 LOG(_L("RemDevState: <[base]> - sending invalid destination service UUID error.")); |
|
1047 StateMachine().SendRoleResponse(EInvalidDestinationServiceUuid); |
|
1048 User::Leave(KErrInvalidDestinationServiceUuid); |
|
1049 } |
|
1050 |
|
1051 err = UuidToPanRole(aRemoteRoleUuid, aRemoteRole); |
|
1052 if(err) |
|
1053 { |
|
1054 LOG(_L("RemDevState: <[base]> - sending invalid source service UUID error.")); |
|
1055 StateMachine().SendRoleResponse(EInvalidSourceServiceUuid); |
|
1056 User::Leave(KErrInvalidSourceServiceUuid); |
|
1057 } |
|
1058 } |
|
1059 |
|
1060 TInt CPanRemDevStateBase::UuidToPanRole(const TUUID& aUuid, TBluetoothPanRole& aRole) |
|
1061 /** |
|
1062 Convert the given UUID into a TBluetoothPanRole |
|
1063 @param aUuid The UUID to convert |
|
1064 @param aRole If successful, on return contains the UUID in TBluetoothPanRole form |
|
1065 @return KErrNone if successful; KErrArgument if the supplied UUID is an invalid PAN role |
|
1066 */ |
|
1067 { |
|
1068 TInt err; |
|
1069 |
|
1070 TPtrC8 ptr(aUuid.ShortestForm()); |
|
1071 |
|
1072 TUint16 panRole = static_cast<TUint16>(EPanRoleUnknown); |
|
1073 if(ptr.Length()!=2) |
|
1074 { |
|
1075 err = KErrArgument; |
|
1076 } |
|
1077 else |
|
1078 { |
|
1079 panRole = static_cast<TUint16>((ptr.Ptr()[0] << 8) | ptr.Ptr()[1]); |
|
1080 err = KErrNone; |
|
1081 } |
|
1082 |
|
1083 aRole = static_cast<TBluetoothPanRole>(panRole); |
|
1084 |
|
1085 if(err || ((aRole!=EPanRoleU)&&(aRole!=EPanRoleGn)&&(aRole!=EPanRoleNap))) //@note Embeds knowledge of valid PAN roles |
|
1086 { |
|
1087 LOG(_L("RemDevSB: ...could not convert to PAN role, returning KErrArgument.")); |
|
1088 return KErrArgument; |
|
1089 } |
|
1090 else |
|
1091 { |
|
1092 LOG1(_L("RemDevSB: ...converted to PAN role %x"), panRole); |
|
1093 return KErrNone; |
|
1094 } |
|
1095 } |
|
1096 |
|
1097 TInt CPanRemDevStateBase::BecomePiconetMaster() |
|
1098 /** |
|
1099 Become the master of the piconet. |
|
1100 Code from RBTBaseband |
|
1101 @return KErrNone if successful; KErrWaitingForBasebandRoleSwitch if role switch is necessary and in progress; otherwise a Symbian standard error code |
|
1102 */ |
|
1103 { |
|
1104 #ifdef _DEBUG |
|
1105 TBTDevAddr KNullDevAddr(MAKE_TINT64(0x0000, 0x00000000)); |
|
1106 __ASSERT_DEBUG(StateMachine().RemSockAddr().BTAddr()!=KNullDevAddr, PanicInState(ENullRemoteDeviceAddress)); |
|
1107 #endif |
|
1108 |
|
1109 |
|
1110 TInt err = StateMachine().PhysicalLinkAdapter().RequestMasterRole(); |
|
1111 return (err == KErrNone ? KErrWaitingForBasebandRoleSwitch : err); |
|
1112 } |
|
1113 |
|
1114 MPanRemDevStateMachineNotify& CPanRemDevStateBase::StateMachine() |
|
1115 /** |
|
1116 Return the handle to the state machine |
|
1117 */ |
|
1118 { |
|
1119 return(iStateMachine); |
|
1120 } |
|
1121 |
|
1122 |
|
1123 |