bluetoothcommsprofiles/btpan/panagt/panagtremdev.cpp
changeset 0 29b1cd4cb562
child 21 14e240312f6f
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     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