bluetoothmgmt/bluetoothclientlib/btlib/btbaseband.cpp
changeset 0 29b1cd4cb562
child 14 f8503e232b0c
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Generic functions associated with all Bluetooth socket addresses
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <bt_sock.h>
       
    19 #include <bluetooth/hci/hcierrors.h>
       
    20 #include <bluetooth/aclsockaddr.h>
       
    21 #include "btsocketpanic.h"
       
    22 
       
    23 //.................................
       
    24 //
       
    25 //Actual raw client
       
    26 //
       
    27 
       
    28 RBTBaseband::RBTBaseband()
       
    29 	{
       
    30 	}
       
    31 
       
    32 void RBTBaseband::Close()
       
    33 	{
       
    34 	if (SubSessionHandle())
       
    35 		{
       
    36 		iSocket.Close();
       
    37 		}
       
    38 	}
       
    39 
       
    40 
       
    41 /**
       
    42 
       
    43   API useful for Bluetooth as seen from a single physical link perspective
       
    44 
       
    45 */
       
    46 
       
    47 // for 'getting' a RBTBaseband from a connected socket
       
    48 TInt RBTBaseband::Open(RSocketServ& aSocketServ, RSocket& aConnectedSocket)
       
    49 	{
       
    50 	if (!aConnectedSocket.SubSessionHandle())
       
    51 		{
       
    52 		return KErrNotReady;
       
    53 		}
       
    54 	
       
    55 	THCIConnHandle bbHandle;
       
    56 	TPckg<THCIConnHandle> bbHandleBuf(bbHandle);
       
    57 
       
    58 	TInt err = aConnectedSocket.GetOpt(KLMGetACLHandle, KSolBtACL, bbHandleBuf);
       
    59 	if (err)
       
    60 		{
       
    61 		return err;
       
    62 		}
       
    63 	err = iSocket.Open(aSocketServ, KBTAddrFamily, bbHandle, KBTLinkManager);
       
    64 
       
    65 	return err;
       
    66 	}
       
    67 
       
    68 TInt RBTBaseband::Open(RSocketServ& aSocketServ, const TBTDevAddr& aBDAddr)
       
    69 	{
       
    70 	//open unsubscribed socket (currently use KSockBluetoothTypeRawBroadcast)
       
    71 	TInt err = iSocket.Open(aSocketServ, 
       
    72 							KBTAddrFamily, 
       
    73 							KSockBluetoothTypeRawBroadcast, 
       
    74 							KBTLinkManager);
       
    75 	if (err)
       
    76 		{
       
    77 		return err;
       
    78 		}
       
    79 
       
    80 	//attempt to subscribe socket to supplied address
       
    81 	TPckg<TBTDevAddr> pckg(aBDAddr);
       
    82 	err = iSocket.SetOpt(EBBSubscribePhysicalLink, KSolBtLMProxy, pckg);
       
    83 	if(err)
       
    84 		//only leave open if there is an EXISTING connection
       
    85 		{
       
    86 		iSocket.Close();
       
    87 		}
       
    88 
       
    89 	return err;
       
    90 	}
       
    91 
       
    92 TInt RBTBaseband::PhysicalLinkState(TUint32& aState)
       
    93 	{
       
    94 	TInt err;
       
    95 	if (!SubSessionHandle())
       
    96 		{
       
    97 		err = KErrNotReady;
       
    98 		}
       
    99 	else
       
   100 		{
       
   101 		TBTBasebandEvent pckgEvent;
       
   102 
       
   103 		err = iSocket.GetOpt(EBBGetPhysicalLinkState, KSolBtLMProxy, pckgEvent);
       
   104 		if (err == KErrNone)
       
   105 			{
       
   106 			aState = pckgEvent().EventType();
       
   107 			}
       
   108 		}
       
   109 
       
   110 	return err;
       
   111 	}
       
   112 
       
   113 /**Role change methods*/
       
   114 TInt RBTBaseband::PreventRoleSwitch()
       
   115 	{
       
   116 	TInt err;
       
   117 	if (!SubSessionHandle())
       
   118 		{
       
   119 		err = KErrNotReady;
       
   120 		}
       
   121 	else
       
   122 		{
       
   123 		err = iSocket.SetOpt(EBBRequestPreventRoleChange, KSolBtLMProxy, 0);
       
   124 		}
       
   125 
       
   126 	return err;
       
   127 	}
       
   128 
       
   129 TInt RBTBaseband::AllowRoleSwitch()
       
   130 	{
       
   131 	TInt err;
       
   132 	if (!SubSessionHandle())
       
   133 		{
       
   134 		err = KErrNotReady;
       
   135 		}
       
   136 	else
       
   137 		{
       
   138 		err = iSocket.SetOpt(EBBRequestAllowRoleChange, KSolBtLMProxy, 0);
       
   139 		}
       
   140 		
       
   141 	return err;
       
   142 	}
       
   143 
       
   144 TInt RBTBaseband::RequestMasterRole()
       
   145 	{
       
   146 	return RequestRole(EBBRequestRoleMaster);
       
   147 	}
       
   148 
       
   149 TInt RBTBaseband::RequestSlaveRole()
       
   150 	{
       
   151 	return RequestRole(EBBRequestRoleSlave);
       
   152 	}
       
   153 
       
   154 
       
   155 /**Low power mode methods*/
       
   156 TInt RBTBaseband::PreventLowPowerModes(TUint32 aLowPowerModes)
       
   157 	{
       
   158 	if (!SubSessionHandle())
       
   159 		{
       
   160 		return KErrNotReady;
       
   161 		}
       
   162 	//if caller has used silly bits
       
   163 	if(aLowPowerModes & ~(EAnyLowPowerMode))
       
   164 		{
       
   165 		return KErrArgument;
       
   166 		}
       
   167 
       
   168 	TUint32 mask = 0;
       
   169 	if(aLowPowerModes & EHoldMode)
       
   170 		{
       
   171 		mask |= EBBRequestPreventHold;
       
   172 		}
       
   173 	if(aLowPowerModes & ESniffMode)
       
   174 		{
       
   175 		mask |= EBBRequestPreventSniff;
       
   176 		}
       
   177 	if(aLowPowerModes & EParkMode)
       
   178 		{
       
   179 		mask |= EBBRequestPreventPark;
       
   180 		}
       
   181 
       
   182 	return iSocket.SetOpt(mask, KSolBtLMProxy);
       
   183 	}
       
   184 
       
   185 TInt RBTBaseband::AllowLowPowerModes(TUint32 aLowPowerModes)
       
   186 	{
       
   187 	
       
   188 	if (!SubSessionHandle())
       
   189 		{
       
   190 		return KErrNotReady;
       
   191 		}
       
   192 	
       
   193 	//if caller has used silly bits
       
   194 	if(aLowPowerModes & ~(EAnyLowPowerMode))
       
   195 		{
       
   196 		return KErrArgument;
       
   197 		}
       
   198 
       
   199 	TUint32 mask = 0;
       
   200 	if(aLowPowerModes & EHoldMode)
       
   201 		{
       
   202 		mask |= EBBRequestAllowHold;
       
   203 		}
       
   204 	if(aLowPowerModes & ESniffMode)
       
   205 		{
       
   206 		mask |= EBBRequestAllowSniff;
       
   207 		}
       
   208 	if(aLowPowerModes & EParkMode)
       
   209 		{
       
   210 		mask |= EBBRequestAllowPark;
       
   211 		}
       
   212 
       
   213 	return iSocket.SetOpt(mask, KSolBtLMProxy);
       
   214 	}
       
   215 
       
   216 TInt RBTBaseband::ActivateSniffRequester()
       
   217 	{
       
   218 	TInt err;
       
   219 	if (!SubSessionHandle())
       
   220 		{
       
   221 		err = KErrNotReady;
       
   222 		}
       
   223 	else 
       
   224 		{
       
   225 		err = iSocket.SetOpt(EBBRequestSniff, KSolBtLMProxy, 0);
       
   226 		}
       
   227 	return err;
       
   228 	}
       
   229 
       
   230 TInt RBTBaseband::ActivateParkRequester()
       
   231 	{
       
   232 	TInt err;
       
   233 	if (!SubSessionHandle())
       
   234 		{
       
   235 		err = KErrNotReady;
       
   236 		}
       
   237 	else
       
   238 		{
       
   239 		err = iSocket.SetOpt(EBBRequestPark, KSolBtLMProxy);
       
   240 		}
       
   241 	return err;
       
   242 	}
       
   243 
       
   244 TInt RBTBaseband::CancelLowPowerModeRequester()
       
   245 	{
       
   246 	TInt err;
       
   247 	if (!SubSessionHandle())
       
   248 		{
       
   249 		err = KErrNotReady;
       
   250 		}
       
   251 	else 
       
   252 		{
       
   253 		err = iSocket.SetOpt(EBBCancelModeRequest, KSolBtLMProxy, 0);
       
   254 		}
       
   255 		
       
   256 	return err;
       
   257 	}
       
   258 
       
   259 TInt RBTBaseband::RequestExplicitActiveMode(TBool aActive)
       
   260 	{
       
   261 	TInt err;
       
   262 	if (!SubSessionHandle())
       
   263 		{
       
   264 		err = KErrNotReady;
       
   265 		}
       
   266 	else
       
   267 		{
       
   268 		TPckgBuf<TBool> active = aActive;
       
   269 		err = iSocket.SetOpt(EBBRequestExplicitActiveMode, KSolBtLMProxy, active);
       
   270 		}
       
   271 	return err;
       
   272 	}
       
   273 
       
   274 
       
   275 /**Packet method*/
       
   276 TInt RBTBaseband::RequestChangeSupportedPacketTypes(TUint16 aPacketTypes)
       
   277 	{
       
   278 	TInt err;
       
   279 	if (!SubSessionHandle())
       
   280 		{
       
   281 		err = KErrNotReady;
       
   282 		}
       
   283 	else
       
   284 		{
       
   285 		// Only allow ACL packet types to be changed
       
   286 		// Although EAnyNonEdrACLPacket is a confusing name in this context
       
   287 		// it is correct. As standard ACL packet types are to be used when the
       
   288 		// appropriate bit is set, for EDR packets the bit is set if they
       
   289 		// are not to be used.  Thus we are correctly checking that only
       
   290 		// valid bits are set when using the EAnyNonEdrACLPacket bitmask.
       
   291 
       
   292 		if ((aPacketTypes & ~EAnyNonEdrACLPacket) != 0)
       
   293 			{
       
   294 			return KErrArgument;
       
   295 			}
       
   296 			
       
   297 		TPckgBuf<TUint16> packetTypes = aPacketTypes;
       
   298 		err = iSocket.SetOpt(EBBRequestChangeSupportedPacketTypes, KSolBtLMProxy, packetTypes);
       
   299 		}
       
   300 	return err;
       
   301 	}
       
   302 
       
   303 void RBTBaseband::ReadNewPhysicalLinkMetricValue(TRequestStatus& aStatus, TDes8& aPLMData, TBTLMIoctls anIoctl)
       
   304 	{
       
   305 	if (!SubSessionHandle())
       
   306 		{
       
   307 		LocalComplete(aStatus, KErrNotReady);
       
   308 		}
       
   309 	else
       
   310 		{
       
   311 		iSocket.Ioctl(anIoctl, aStatus, &aPLMData, KSolBtLMProxy);
       
   312 		}
       
   313 	}
       
   314 
       
   315 void RBTBaseband::CancelPhysicalLinkMetricUpdate()
       
   316 	{
       
   317 	if(SubSessionHandle())
       
   318 		{
       
   319 		iSocket.CancelIoctl();
       
   320 		}
       
   321 	}
       
   322 
       
   323 /**Notification methods*/
       
   324 void RBTBaseband::ActivateNotifierForOneShot(TBTBasebandEvent& aEventNotification, 
       
   325 		                                     TRequestStatus& aStatus, 
       
   326 											 TUint32 aEventMask)
       
   327 	{
       
   328 	if (!SubSessionHandle())
       
   329 		{
       
   330 		LocalComplete(aStatus, KErrNotReady);
       
   331 		}
       
   332 	else
       
   333 		{
       
   334 		aEventNotification().SetEventType(aEventMask);
       
   335 		iSocket.Ioctl(KLMBasebandEventOneShotNotificationIoctl, aStatus, &aEventNotification, KSolBtLMProxy);		
       
   336 		}
       
   337 	}
       
   338 
       
   339 void RBTBaseband::ActivateNotifierForRecall(TBTBasebandEvent& aEventNotification, 
       
   340 		                                    TRequestStatus& aStatus, 
       
   341 											TUint32 aEventMask)
       
   342 	{
       
   343 	if (!SubSessionHandle())
       
   344 		{
       
   345 		LocalComplete(aStatus, KErrNotReady);
       
   346 		}
       
   347 	else
       
   348 		{
       
   349 		aEventNotification().SetEventType(aEventMask);
       
   350 		iSocket.Ioctl(KLMBasebandEventNotificationIoctl, aStatus, &aEventNotification, KSolBtLMProxy);		
       
   351 		}
       
   352 	}
       
   353 
       
   354 void RBTBaseband::CancelNextBasebandChangeEventNotifier()
       
   355 	{
       
   356 	if (SubSessionHandle())
       
   357 		{
       
   358 		//only allowed one Ioctl at a time - only one used is the Notifications Ioctl
       
   359 		iSocket.CancelIoctl();		
       
   360 		}
       
   361 	}
       
   362 
       
   363 TInt RBTBaseband::Authenticate()
       
   364 	{
       
   365 	// First check that the socket is open etc	
       
   366 	TInt err = KErrNone;
       
   367 	if (!SubSessionHandle())
       
   368 		{
       
   369 		err = KErrNotReady;
       
   370 		}
       
   371 	else 
       
   372 		{
       
   373 		// Send the request - this will return KErrAlreadyExists if the link is already authenticated.
       
   374 		err = iSocket.SetOpt(EBBRequestLinkAuthentication, KSolBtLMProxy, 0);
       
   375 		}
       
   376 
       
   377 	return err;
       
   378 	}
       
   379 
       
   380 
       
   381 /**
       
   382 
       
   383   API useful for Bluetooth as seen from a device perspective
       
   384 
       
   385 */
       
   386 
       
   387 TInt RBTBaseband::Open(RSocketServ& aSocketServ)
       
   388 	{
       
   389 	// need to specify this is a raw socket
       
   390 	TInt err = iSocket.Open(aSocketServ, 
       
   391 							KBTAddrFamily, 
       
   392 							KSockBluetoothTypeRawBroadcast, 
       
   393 							KBTLinkManager);
       
   394 	return err;
       
   395 	}
       
   396 
       
   397 void RBTBaseband::Connect(const TBTDevAddr& aAddr, TRequestStatus& aStatus)
       
   398 	{
       
   399 	iConnectToken().iDevice.SetAddress(aAddr);
       
   400 	DoConnect(aStatus);
       
   401 	}
       
   402 
       
   403 void RBTBaseband::Connect(const TPhysicalLinkQuickConnectionToken& aToken, TRequestStatus& aStatus)
       
   404 
       
   405 //  (Not for documentation!)
       
   406 //	param	aDevice	
       
   407 //	A valid nameless device - that may have been obtained from Registry
       
   408 
       
   409 	{
       
   410 	if (!iConnectToken().iDevice.IsValidAddress())
       
   411 		{
       
   412 		LocalComplete(aStatus, KErrArgument);
       
   413 		}
       
   414 	else
       
   415 		{
       
   416 		iConnectToken() = aToken;
       
   417 		DoConnect(aStatus);
       
   418 		}
       
   419 	}
       
   420 
       
   421 
       
   422 TInt RBTBaseband::Broadcast(const TDesC8& aData)
       
   423 	{
       
   424 #ifdef PROXY_COMMUNICATES
       
   425 	// have to notify Proxy that we intend to write data via it
       
   426 	TInt err;
       
   427 	if (!SubSessionHandle())
       
   428 		{
       
   429 		err = KErrNotReady;
       
   430 		}
       
   431 	else
       
   432 		{
       
   433 		err = iSocket.SetOpt(EBBBeginRaw, KSolBtLMProxy, 0);
       
   434 		}
       
   435 	if (err == KErrNone || err == KErrAlreadyExists)
       
   436 		{
       
   437 		TRequestStatus s;
       
   438 		TUint8 flags = KPiconetBroadcast << 2;
       
   439 		iSocket.Send(aData, flags, s);	// 'send' to allow flags
       
   440 		User::WaitForRequest(s);
       
   441 		err = s.Int();
       
   442 		}
       
   443 	return err;
       
   444 #else
       
   445 	return KErrNotSupported;
       
   446 #endif
       
   447 	}
       
   448 
       
   449 TInt RBTBaseband::ReadRaw(TDes8& aData)
       
   450 /**
       
   451 	NOT PROPERLY IMPLEMENTED - JUST A PLACE HOLDER REALLY
       
   452 */
       
   453 	{
       
   454 #ifdef PROXY_COMMUNICATES
       
   455 	// have to notify Proxy that we intend to write data via it
       
   456 	TInt err;
       
   457 	if (!SubSessionHandle())
       
   458 		{
       
   459 		err = KErrNotReady;
       
   460 		}
       
   461 	else
       
   462 		{
       
   463 		err = iSocket.SetOpt(EBBBeginRaw, KSolBtLMProxy, 0);
       
   464 		}
       
   465 	if (err == KErrNone || err == KErrAlreadyExists)
       
   466 		{
       
   467 		TRequestStatus s;
       
   468 		TUint8 flags = KPiconetBroadcast << 2;
       
   469 		iSocket.Recv(aData, flags, s);	// 'send' to allow flags
       
   470 		User::WaitForRequest(s);
       
   471 		err = s.Int();
       
   472 		}
       
   473 	return err;
       
   474 #else
       
   475 	return KErrNotSupported;
       
   476 #endif
       
   477 	}
       
   478 
       
   479 
       
   480 void RBTBaseband::TerminatePhysicalLink(TInt /*aReason*/)
       
   481 	{
       
   482 	// synchronise
       
   483 	TRequestStatus stat;
       
   484 	TerminatePhysicalLink(0, stat);
       
   485 	User::WaitForRequest(stat);
       
   486 	}
       
   487 
       
   488 void RBTBaseband::TerminatePhysicalLink(TInt /*aReason*/, TRequestStatus& aStatus)
       
   489 	{
       
   490 	if (!SubSessionHandle())
       
   491 		{
       
   492 		LocalComplete(aStatus, KErrNotReady);
       
   493 		}
       
   494 	else
       
   495 		{
       
   496 		// synchronise
       
   497 		TBuf8<1> dummy;
       
   498 		iSocket.Shutdown(RSocket::EImmediate, KDisconnectOnePhysicalLink, dummy, aStatus); // this *means* detach now
       
   499 		}
       
   500 	}
       
   501 
       
   502 void RBTBaseband::TerminatePhysicalLink(TInt /*aReason*/, const TBTDevAddr& aAddr, TRequestStatus& aStatus)
       
   503 	{
       
   504 	if (!SubSessionHandle())
       
   505 		{
       
   506 		LocalComplete(aStatus, KErrNotReady);
       
   507 		}
       
   508 	else
       
   509 		{
       
   510 		// ensure that BT address has persistence
       
   511 		iSocketAddress.Zero();
       
   512 		iSocketAddress.Copy(aAddr.Des());
       
   513 		// the following line needs to be EImmediate when ESock has been fixed
       
   514 		iSocket.Shutdown(RSocket::ENormal, iSocketAddress, iConnectInData, aStatus); // this *means* detach now
       
   515 		}
       
   516 	}
       
   517 
       
   518 void RBTBaseband::ShutdownPhysicalLink(TRequestStatus& aStatus)
       
   519 	{
       
   520 	if (!SubSessionHandle())
       
   521 		{
       
   522 		LocalComplete(aStatus, KErrNotReady);
       
   523 		}
       
   524 	else
       
   525 		{
       
   526 		// synchronise
       
   527 		TBuf8<1> dummy;
       
   528   		iSocket.Shutdown(RSocket::ENormal, KDisconnectOnePhysicalLink, dummy, aStatus); // this *means* detach gently
       
   529 		}	
       
   530 	}
       
   531 
       
   532 void RBTBaseband::TerminateAllPhysicalLinks(TInt aReason)
       
   533 	{
       
   534 	TRequestStatus stat;
       
   535 	TerminateAllPhysicalLinks(aReason, stat);
       
   536 	User::WaitForRequest(stat);
       
   537 	}
       
   538 
       
   539 void RBTBaseband::TerminateAllPhysicalLinks(TInt /*aReason*/, TRequestStatus& aStatus)
       
   540 	{
       
   541 	if (!SubSessionHandle())
       
   542 		{
       
   543 		LocalComplete(aStatus, KErrNotReady);
       
   544 		}
       
   545 	else
       
   546 		{
       
   547 		TBuf8<1> dummy;
       
   548 		iSocket.Shutdown(RSocket::ENormal, KDisconnectAllPhysicalLinks, dummy, aStatus); // this *means* detach now
       
   549 		}
       
   550 	}
       
   551 
       
   552 TInt RBTBaseband::Enumerate(RBTDevAddrArray& aBTDevAddrArray, TUint aMaxNumber)
       
   553 	{
       
   554 	if (!SubSessionHandle())
       
   555 		{
       
   556 		return KErrNotReady;
       
   557 		}
       
   558 
       
   559 	__ASSERT_DEBUG(aMaxNumber>=1, Panic(EBadArgument));
       
   560 	if(!aMaxNumber)
       
   561 		{
       
   562 		return KErrArgument;
       
   563 		}
       
   564 	HBufC8* buffer=0;
       
   565 	const TInt KAddrLen = sizeof(TBTDevAddr);
       
   566 
       
   567 	TRAPD(err, buffer = HBufC8::NewL(aMaxNumber*KAddrLen));
       
   568 	if(err)
       
   569 		{
       
   570 		return KErrNoMemory;
       
   571 		}
       
   572 
       
   573 	TPtr8 ptr = buffer->Des();
       
   574 	err = iSocket.GetOpt(EBBEnumeratePhysicalLinks, KSolBtLMProxy, ptr);
       
   575 	if (err)
       
   576 		{
       
   577 		delete buffer;
       
   578 		return err;
       
   579 		}
       
   580 
       
   581 	/**
       
   582 	Parse the supplied descriptor
       
   583 	*/
       
   584 	
       
   585 	aBTDevAddrArray.Reset();
       
   586 	while(ptr.Length()>=KBTDevAddrSize)
       
   587 		{
       
   588 		TBTDevAddr parsedAddr(ptr.Mid(ptr.Length()-KAddrLen, KBTDevAddrSize));
       
   589 		ptr.SetLength(Max(ptr.Length()-KAddrLen, 0));
       
   590 		aBTDevAddrArray.Append(parsedAddr);
       
   591 		}
       
   592 
       
   593 	delete buffer;
       
   594 	return KErrNone;
       
   595 	}
       
   596 
       
   597 
       
   598 TInt RBTBaseband::SubSessionHandle() const
       
   599 	{
       
   600 	return iSocket.SubSessionHandle();
       
   601 	}
       
   602 
       
   603 
       
   604 /**Private Methods*/
       
   605 TInt RBTBaseband::RequestRole(TBTLMOptions aRole)
       
   606 	{
       
   607 	if (!SubSessionHandle())
       
   608 		{
       
   609 		return KErrNotReady;
       
   610 		}
       
   611 	__ASSERT_DEBUG(aRole==EBBRequestRoleMaster||aRole==EBBRequestRoleSlave, 
       
   612 				   Panic(EBadArgument));
       
   613 
       
   614 	return iSocket.SetOpt(aRole, KSolBtLMProxy, 0);
       
   615 	}
       
   616 
       
   617 
       
   618 void RBTBaseband::LocalComplete(TRequestStatus& aStatus, TInt aErr)
       
   619 	{
       
   620 	aStatus = KRequestPending;
       
   621 	TRequestStatus* pStat = &aStatus;
       
   622 	User::RequestComplete(pStat, aErr);
       
   623 	}
       
   624 
       
   625 void RBTBaseband::DoConnect(TRequestStatus& aStatus)
       
   626 	{
       
   627 	if (!SubSessionHandle())
       
   628 		{
       
   629 		LocalComplete(aStatus, KErrNotReady);
       
   630 		}
       
   631 	
       
   632 	__ASSERT_DEBUG(iConnectToken().iDevice.IsValidAddress(), Panic(EBBInvalidAddress));
       
   633 	
       
   634 	iSocketAddress.SetBTAddr(iConnectToken().iDevice.Address()); // not that useful
       
   635 	iSocket.Connect(iSocketAddress, iConnectToken, iConnectInData, aStatus);
       
   636 	}
       
   637 
       
   638 
       
   639 
       
   640 //.................................
       
   641 //
       
   642 //Class used for choosing baseband events to report, and for reporting 
       
   643 //those events to the Bluetooth client
       
   644 //
       
   645 
       
   646 EXPORT_C TInt TBTBasebandEventNotification::SymbianErrorCode() const
       
   647 /** Returns an error in 'Symbian' format
       
   648 	@return Symbian error code	
       
   649 	@publishedAll
       
   650 	@released
       
   651 */	
       
   652 	{ 
       
   653 	return iErrorCode==KErrNone?iErrorCode:KHCIErrorBase-iErrorCode; 
       
   654 	};
       
   655 
       
   656 
       
   657 
       
   658 //.................................
       
   659 //
       
   660 //Facade class for developers wishing who wish to use a pre-existing connected 
       
   661 //physical link
       
   662 //
       
   663 
       
   664 EXPORT_C RBTPhysicalLinkAdapter::RBTPhysicalLinkAdapter()
       
   665 /** Constructor
       
   666 	@publishedAll
       
   667 	@released
       
   668 */
       
   669 	{
       
   670 	}
       
   671 
       
   672 EXPORT_C TInt RBTPhysicalLinkAdapter::Open(RSocketServ& aSocketServ, RSocket& aSocket)
       
   673 /**	Open a physical link adapter on an existing physical link defined by 'aSocket'.
       
   674 	@pre There exists a Bluetooth connection
       
   675 	@param aSocketServ	 
       
   676 	An existing ESock session
       
   677 	@param aSocket
       
   678 	An open connected socket (ESock subsession) on that existing ESock session
       
   679 	@return Error code	
       
   680 	@publishedAll
       
   681 	@released
       
   682 	@capability LocalServices
       
   683 */
       
   684 	{
       
   685 	return iBTBaseband.Open(aSocketServ, aSocket);
       
   686 	}
       
   687 
       
   688 EXPORT_C TInt RBTPhysicalLinkAdapter::Open(RSocketServ& aSocketServ, const TBTDevAddr& aBDAddr)
       
   689 /**	Open a physical link adapter on an existing physical link defined by 'aDevAddr'.
       
   690 	@pre There exists a Bluetooth connection
       
   691 	@param aSocketServ	 
       
   692 	An existing ESock session
       
   693 	@param aBDAddr 
       
   694 	The Bluetooth address of a remote device with which there is an existing connection 
       
   695 	@return Error code	
       
   696 	@publishedAll
       
   697 	@released
       
   698 	@capability LocalServices
       
   699 */
       
   700 	{
       
   701 	return iBTBaseband.Open(aSocketServ, aBDAddr);
       
   702 	}
       
   703 
       
   704 EXPORT_C void RBTPhysicalLinkAdapter::Close()
       
   705 /**	Close the physical link adapter.
       
   706 	@publishedAll
       
   707 	@released
       
   708 */
       
   709 	{
       
   710 	iBTBaseband.Close();
       
   711 	}
       
   712 
       
   713 EXPORT_C TInt RBTPhysicalLinkAdapter::PhysicalLinkState(TUint32& aState)
       
   714 /**	Get the state of the physical link.
       
   715 	@pre One of the Open functions has been called
       
   716 	@param aState
       
   717 	Used to return the physical link state - as a combination of bit values
       
   718 	defined in TBTPhysicalLinkStateNotifier.
       
   719 	@see TBTPhysicalLinkStateNotifier
       
   720 	@return Error code	
       
   721 	@publishedAll
       
   722 	@released
       
   723 */
       
   724 	{
       
   725 	return iBTBaseband.PhysicalLinkState(aState);
       
   726 	}
       
   727 
       
   728 //Role change methods
       
   729 EXPORT_C TInt RBTPhysicalLinkAdapter::PreventRoleSwitch()
       
   730 /**	Blocks a role switch
       
   731 
       
   732 	Stops a Master/Slave switch occurring until such time as 'AllowRoleSwitch' is called. 
       
   733 	@pre One of the Open functions has been called
       
   734 	@return Error code	
       
   735 	@publishedAll
       
   736 	@released
       
   737 */
       
   738 	{
       
   739 	return iBTBaseband.PreventRoleSwitch();
       
   740 	}
       
   741 
       
   742 EXPORT_C TInt RBTPhysicalLinkAdapter::AllowRoleSwitch()
       
   743 /**	Ensures this object does not block a role switch.
       
   744 
       
   745 	Switches off 'PreventRoleSwitch'. If another RBTPhysicalLinkAdapter object requests, 
       
   746 	or has requested a Master/Slave switch, that request will now not be blocked by 
       
   747 	this RBTPhysicalLinkAdapter object
       
   748 	The default is to allow a Master/Slave switch.
       
   749 	@pre One of the Open functions has been called
       
   750 	@return Error code	
       
   751 	@publishedAll
       
   752 	@released
       
   753 */
       
   754 	{
       
   755 	return iBTBaseband.AllowRoleSwitch();
       
   756 	}
       
   757 
       
   758 EXPORT_C TInt RBTPhysicalLinkAdapter::RequestMasterRole()
       
   759 /**	Attempt to be the Bluetooth Master of a Piconet.
       
   760 
       
   761 	If the local device is currently the slave, a role switch maybe performed 
       
   762 	if no other user of a RBTPhysicalLinkAdapter object has called PreventRoleSwitch 
       
   763 	and the remote device allows the role switch.
       
   764 	@return Error code	
       
   765 	@publishedAll
       
   766 	@released
       
   767 */
       
   768 	{
       
   769 	return iBTBaseband.RequestMasterRole();
       
   770 	}
       
   771 
       
   772 EXPORT_C TInt RBTPhysicalLinkAdapter::RequestSlaveRole()
       
   773 /**	Attempt to be a Bluetooth Slave of a Piconet. 
       
   774 
       
   775 	If the local device is currently the master, a role switch maybe performed if 
       
   776 	no other user of a RBTPhysicalLinkAdapter object has called PreventRoleSwitch 
       
   777 	and the remote device allows the role switch.
       
   778 	@pre One of the Open functions has been called
       
   779 	@return Error code	
       
   780 	@publishedAll
       
   781 	@released
       
   782 */
       
   783 	{
       
   784 	return iBTBaseband.RequestSlaveRole();
       
   785 	}
       
   786 
       
   787 //Low power mode methods
       
   788 EXPORT_C TInt RBTPhysicalLinkAdapter::PreventLowPowerModes(TUint32 aLowPowerModes)
       
   789 /**	Blocks the use of a specified set of low power modes
       
   790 
       
   791 	Stops the physical link using any one of the set of low power modes specified by 
       
   792 	the bit mask 'aLowPowerModes'. To undo this blocking mechanism for a given set
       
   793 	of low power modes, 'AllowLowPowerModes' needs to be called with appropriate values 
       
   794 	in its 'aLowPowerModes' parameter.
       
   795 	
       
   796 	NB  THIS METHOD CAN BE USED TO FORCE THE PHYSICAL LINK INTO ACTIVE MODE.
       
   797 		To do this set the parameter to EAnyLowPowerMode. The requests for low power 
       
   798 		modes by any RBTPhysicalLinkAdapter objects will now be blocked by this object.
       
   799 	
       
   800 	NB  Some remote devices will automatically disconnect from a device whose Link Policy 
       
   801 		settings prevent low power modes.  
       
   802 		
       
   803 	@pre One of the Open functions has been called
       
   804 	@param	aLowPowerModes
       
   805 	A mask to specify which power modes are to be prevented. 
       
   806 	(Combine EHoldMode, ESniffMode, EParkMode or use EAnyLowPowerMode)
       
   807 	@return Error code	
       
   808 	@publishedAll
       
   809 	@released
       
   810 */
       
   811 	{
       
   812 	return iBTBaseband.PreventLowPowerModes(aLowPowerModes);
       
   813 	}
       
   814 
       
   815 EXPORT_C TInt RBTPhysicalLinkAdapter::AllowLowPowerModes(TUint32 aLowPowerModes)
       
   816 /**	Ensures this object does not block the use of a specified set of low power modes
       
   817 
       
   818 	Switches off 'PreventLowPowerModes' for the low power modes specified by the parameter 
       
   819 	'aLowPowerModes'. If another RBTPhysicalLinkAdapter object requests, or has 
       
   820 	requested one of those low power modes, that request will now NOT be blocked by 
       
   821 	this RBTPhysicalLinkAdapter object. 
       
   822 	The default is to allow all low power modes.
       
   823 	NB. Warning this may reactivate a low power mode requester.
       
   824 		For example: 
       
   825 		ActivateSniffRequester(); //sniff requester active
       
   826 		PreventLowPowersModes(ESniffMode); //sniff requester dormant
       
   827 		....
       
   828 		AllowLowPowersModes(ESniffMode); //sniff requseter active
       
   829 
       
   830 	@pre One of the Open functions has been called
       
   831 	@param	aLowPowerModes
       
   832 	A mask to specify which power modes are to be prevented. 
       
   833 	(Combine EHoldMode, ESniffMode, EParkMode or use EAnyLowPowerMode)
       
   834 	@return Error code	
       
   835 	@publishedAll
       
   836 	@released
       
   837 */
       
   838 	{
       
   839 	return iBTBaseband.AllowLowPowerModes(aLowPowerModes);
       
   840 	}
       
   841 
       
   842 EXPORT_C TInt RBTPhysicalLinkAdapter::ActivateSniffRequester()
       
   843 /**	Start a facility that will continually attempt to put the physical link into Sniff Mode.
       
   844 
       
   845 	Attempt to put the physical link into Sniff mode. If for any reason this is
       
   846 	not possible (e.g another user of a RBTPhysicalLinkAdapter object has called 
       
   847 	PreventLowPowerModes on Sniff) or the physical link comes out of Sniff mode, 
       
   848 	this attempt will be repeated whenever a relevant event occurs or command is made.
       
   849 	These attempts will cease if a call to either ActivateParkRequester, ActivateActiveRequester or
       
   850 	CancelLowPowerModeRequester is made.
       
   851 	@pre One of the Open functions has been called
       
   852 	@return Error code	
       
   853 	@publishedAll
       
   854 	@released
       
   855 */
       
   856 	{
       
   857 	return iBTBaseband.ActivateSniffRequester();
       
   858 	}
       
   859 
       
   860 EXPORT_C TInt RBTPhysicalLinkAdapter::ActivateParkRequester()
       
   861 /**	Start a facility that will continually attempt to put the physical link into Park Mode.
       
   862 
       
   863 	Attempt to put the physical link into Park mode. If for any reason this is
       
   864 	not possible (e.g another user of a RBTPhysicalLinkAdapter object has called 
       
   865 	PreventLowPowerModes on Park) or the physical link comes out of Park mode, 
       
   866 	this attempt will be repeated whenever a relevant event occurs or command is made.
       
   867 	These attempts will cease, if a call to either ActivateSniffRequester, ActivateActiveRequester or
       
   868 	CancelLowPowerModeRequester is made.
       
   869 	@pre One of the Open functions has been called
       
   870 	@return Error code	
       
   871 	@publishedAll
       
   872 	@released
       
   873 */
       
   874 	{
       
   875 	return iBTBaseband.ActivateParkRequester();
       
   876 	}
       
   877 
       
   878 EXPORT_C TInt RBTPhysicalLinkAdapter::ActivateActiveRequester()
       
   879 /**	Start a facility that will continually attempt to put the physical link into Active Mode.
       
   880 
       
   881 	Puts the physical link into Active mode, even if a Low Power Mode (Sniff or Park) has 
       
   882 	been explicitly requested by another client of the physical link.
       
   883 	Calling CancelLowPowerModeRequests() will cancel the explicit request for Active mode.
       
   884 	@pre One of the Open functions has been called
       
   885 	@return Error code	
       
   886 	@publishedAll
       
   887 	@released
       
   888 */
       
   889 	{
       
   890 	TInt err;
       
   891 	err = iBTBaseband.RequestExplicitActiveMode(ETrue);
       
   892 	if(err == KErrNone)
       
   893 		{
       
   894 		err = iBTBaseband.CancelLowPowerModeRequester();
       
   895 		}
       
   896 	return err;
       
   897 	}
       
   898 
       
   899 EXPORT_C TInt RBTPhysicalLinkAdapter::CancelLowPowerModeRequester()
       
   900 /**	Cancel a facility that is continually requesting a low power mode
       
   901 
       
   902 	If ActivateSniffRequester, ActivateParkRequester or ActivateActiveRequester has been called by the user
       
   903 	of this RBTPhysicalLinkAdapter object, repeated attempts will be made to put/return 
       
   904 	the physical link to that mode whenever a relevant event occurs or command is made. 
       
   905 	CancelLowPowerModeRequester stops these requests. However if another user of a 
       
   906 	RBTPhysicalLinkAdapter object has called ActivateSniffRequester, ActivateParkRequester or ActivateActiveRequester,
       
   907 	those requests will still be active, and so the physical link will remain controlled by these requests.
       
   908 	
       
   909 	To try to force the physical link into active mode, a call to 
       
   910 	either PreventLowPowerModes(EAnyLowPowerMode) or ActivateActiveRequester() should be made.
       
   911 	
       
   912 	@pre One of the Open functions has been called
       
   913 	@return Error code	
       
   914 	@publishedAll
       
   915 	@released
       
   916 */
       
   917 	{
       
   918 	TInt err;
       
   919 	err = iBTBaseband.RequestExplicitActiveMode(EFalse);
       
   920 	if(err == KErrNone)
       
   921 		{
       
   922 		err = iBTBaseband.CancelLowPowerModeRequester();
       
   923 		}
       
   924 	return err; 
       
   925 	}
       
   926 
       
   927 
       
   928 //Packet method
       
   929 EXPORT_C TInt RBTPhysicalLinkAdapter::RequestChangeSupportedPacketTypes(TUint16 aPacketTypes)
       
   930 /**	Update the set of baseband packet types that are allowed locally
       
   931 
       
   932 	Attempts to control which Bluetooth baseband ACL packet types (i.e. DM1, DH1, DM3 etc)
       
   933 	are allowed by our host controller on the physical link.
       
   934 	@pre One of the Open functions has been called
       
   935 	@param aPacketTypes
       
   936 	Bitmask for packet types to be supported 
       
   937 	(Combine elements of TBTPacketType (or use TBTPacketTypeCombinations))
       
   938 	@see TBTPacketType
       
   939 	@see TBTPacketTypeCombinations
       
   940 
       
   941 	@return Error code	
       
   942 	@publishedAll
       
   943 	@released
       
   944 */
       
   945 	{
       
   946 	return iBTBaseband.RequestChangeSupportedPacketTypes(aPacketTypes);
       
   947 	}
       
   948 
       
   949 //Notification methods
       
   950 EXPORT_C void RBTPhysicalLinkAdapter::NotifyNextBasebandChangeEvent(TBTBasebandEvent& aEventNotification, 
       
   951 		                                                            TRequestStatus& aStatus, 
       
   952 											                        TUint32 aEventMask)
       
   953 /**	Request a notification 
       
   954 
       
   955 	Request notification the next time one of a user specified selection (see parameter 3) 
       
   956 	of baseband events occurs.
       
   957  	@pre One of the Open functions has been called
       
   958 	@param aEventNotification
       
   959 	Return parameter
       
   960 	@param aStatus
       
   961 	Status parameter for asynchronous request
       
   962 	@param aEventMask
       
   963 	Bitmask for those events for which notification is being requested 
       
   964 	Use TBTPhysicalLinkStateNotifier (and TBTPhysicalLinkStateNotifierCombinations)
       
   965 	@see TBTPhysicalLinkStateNotifier
       
   966 	@see TBTPhysicalLinkStateNotifierCombinations
       
   967 	@publishedAll
       
   968 	@released
       
   969 */
       
   970 	{
       
   971 	iBTBaseband.ActivateNotifierForOneShot(aEventNotification, aStatus, aEventMask);
       
   972 	}
       
   973 
       
   974 EXPORT_C void RBTPhysicalLinkAdapter::CancelNextBasebandChangeEventNotifier()
       
   975 /**	Cancel a currently requested notification
       
   976 
       
   977 	Switch off the currently active baseband change event notifier.	
       
   978 	@pre One of the Open functions has been called
       
   979 	@publishedAll
       
   980 	@released
       
   981 */
       
   982 	{
       
   983 	iBTBaseband.CancelNextBasebandChangeEventNotifier();
       
   984 	}
       
   985 
       
   986 EXPORT_C TInt RBTPhysicalLinkAdapter::Authenticate()
       
   987 /**	Attempts to authenticate the existing physical link
       
   988 
       
   989 	If the the physical link has already been authenticated it will return an error,
       
   990 	otherwise an Authentication Request will be made to the remote device.
       
   991 	
       
   992 	This is a synchronous call and will return immediately the request has been issued.
       
   993 	If required, NotifyNextBasebandChangeEvent() should be issued before this to wait for
       
   994 	the completion of this authenticaton (for both authentication success and failure)	
       
   995 
       
   996 	@pre One of the Open functions has been called
       
   997 	@return Error code. KErrAlreadyExists if the link is already authenticated
       
   998 */
       
   999 	{
       
  1000 	return iBTBaseband.Authenticate();
       
  1001 	}
       
  1002 
       
  1003 EXPORT_C TBool RBTPhysicalLinkAdapter::IsOpen() const
       
  1004 /**	Check whether the physical link adapter is open
       
  1005 
       
  1006 	This method is not required to be called before the other methods.
       
  1007 	KErrNotReady will be returned by other methods, if RBTPhysicalLinkAdapter is not open yet.
       
  1008 
       
  1009 	@publishedAll
       
  1010 	@released
       
  1011 */
       
  1012 	{
       
  1013 	return (iBTBaseband.SubSessionHandle() ? ETrue : EFalse);
       
  1014 	}
       
  1015 	
       
  1016 
       
  1017 
       
  1018