bluetooth/btstack/common/btprt.cpp
changeset 0 29b1cd4cb562
child 51 20ac952a623c
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 1999-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 // This file implements the generic interface to a ESOCK PRT
       
    15 // for the Bluetooth PRT module
       
    16 // 
       
    17 //
       
    18 
       
    19 // The Bluetooth protocol family also provides Control-plane facilities
       
    20 // thereby relieving the user-plane SAPs and muxers of these duties
       
    21 #include <bluetooth/logger.h>
       
    22 #include "Avctp.h"
       
    23 #include "bt.h"
       
    24 #include "linkmgr.h"
       
    25 #include "l2cap.h"
       
    26 #include "rfcomm.h"
       
    27 #include "sdp.h"
       
    28 #include "avdtp.h"
       
    29 
       
    30 #include "IncomingConnListener.h"
       
    31 
       
    32 #ifdef __FLOG_ACTIVE
       
    33 _LIT8(KLogComponent, LOG_COMPONENT_BT_PRT);
       
    34 #endif
       
    35 
       
    36 #ifdef _DEBUG
       
    37 PANICCATEGORY("btprt");
       
    38 #endif
       
    39 
       
    40 _LIT(KBTPrtPanic, "BluetoothPRT Panic");
       
    41 
       
    42 
       
    43 void Panic(TBluetoothFamilyPanic aPanic)
       
    44 	{
       
    45 	LOG_STATIC_FUNC
       
    46 	User::Panic(KBTPrtPanic, aPanic);
       
    47 	}
       
    48 
       
    49 extern "C"
       
    50 	{
       
    51 	IMPORT_C CProtocolFamilyBase* InstallBTProtocolFamily();	// Force export 
       
    52 	}
       
    53 
       
    54 EXPORT_C CProtocolFamilyBase* InstallBTProtocolFamily()
       
    55 // Create a new protocol family
       
    56 	{
       
    57 	LOG_STATIC_FUNC
       
    58 	//Return NULL if CBTProtocolFamily::NewL() leaves
       
    59 	CProtocolFamilyBase* result=NULL;
       
    60 	TRAP_IGNORE(result=CBTProtocolFamily::NewL());
       
    61 	return result;
       
    62 	}
       
    63 
       
    64 CBTProtocolFamily* CBTProtocolFamily::NewL()
       
    65 	{
       
    66 #ifdef __FLOG_ACTIVE
       
    67 	CONNECT_LOGGER
       
    68 #endif
       
    69 	LOG_STATIC_FUNC
       
    70     // Flogging can start after the installation of the Blogger
       
    71 	// and the instantiation of the HCI
       
    72 	//	LOG(_L("+CBTProtocolFamily::NewL"));
       
    73 	CBTProtocolFamily* pf= new (ELeave) CBTProtocolFamily();
       
    74 	CleanupStack::PushL(pf);
       
    75 	pf->ConstructL();
       
    76 	CleanupStack::Pop();
       
    77 	return pf;
       
    78 	}
       
    79 
       
    80 CBTProtocolFamily::CBTProtocolFamily() 
       
    81  : CProtocolFamilyBase(),
       
    82    iBTRefCount(0)
       
    83 	{
       
    84 	LOG_FUNC
       
    85 	}
       
    86 
       
    87 void CBTProtocolFamily::ConstructL()
       
    88 	{
       
    89 	LOG_FUNC
       
    90 	// install TLS
       
    91 	Dll::SetTls(&iBTTls);
       
    92 
       
    93 	LOG(_L("+CBTProtocolFamily::ConstructL"));
       
    94 	iCallback = new (ELeave) CAsyncCallBack(EPriorityHigh);
       
    95 	}
       
    96 
       
    97 CBTProtocolFamily::~CBTProtocolFamily()
       
    98 	{
       
    99 	LOG_FUNC
       
   100 	LOG(_L("+CBTProtocolFamily::~CBTProtocolFamily"));
       
   101 	BTSocketTimer::Close();
       
   102 	delete iSecurityMgr;
       
   103 	delete iCallback;
       
   104 	delete iCodServiceMan;
       
   105 	iControlPlane.Close();
       
   106 	Dll::FreeTls();
       
   107 #ifdef __FLOG_ACTIVE
       
   108 	CLOSE_LOGGER
       
   109 #endif
       
   110 	}
       
   111 	
       
   112 
       
   113 TInt CBTProtocolFamily::Install()
       
   114 	{
       
   115 	LOG_FUNC
       
   116 
       
   117 	TRAPD(err, BTSocketTimer::InitL());
       
   118 	return err;
       
   119 	}
       
   120 
       
   121 TInt CBTProtocolFamily::Remove()
       
   122 	{
       
   123 	LOG_FUNC
       
   124 	// set the asynccallback to delete us cleanly
       
   125 	return KErrNone;
       
   126 	}
       
   127 
       
   128 TUint CBTProtocolFamily::ProtocolList(TServerProtocolDesc*& aProtocolPointer)
       
   129 	{
       
   130 	LOG_FUNC
       
   131 	// This is cleaned up by ESOCK
       
   132 	aProtocolPointer = new TServerProtocolDesc[6];
       
   133 
       
   134 	if (!aProtocolPointer)
       
   135 		return 0;
       
   136 	
       
   137 	// Note it helps if the protocols are defined here in the same order 
       
   138 	// as in the .esk file or Esock's tags will get mis-assigned.
       
   139 
       
   140 	CLinkMgrProtocol::ProtocolIdentity(&aProtocolPointer[0]);
       
   141 	CL2CAPProtocol::ProtocolIdentity  (&aProtocolPointer[1]);
       
   142 #ifdef TCI
       
   143 	return 2;
       
   144 #else // !TCI
       
   145 	CRfcommProtocol::ProtocolIdentity (&aProtocolPointer[2]);
       
   146 	CSdpProtocol::ProtocolIdentity    (&aProtocolPointer[3]);
       
   147 #ifndef BLUETOOTH_NO_AV
       
   148  	CAvctpProtocol::ProtocolIdentity  (&aProtocolPointer[4]); 	
       
   149 	CAvdtpProtocol::ProtocolIdentity  (&aProtocolPointer[5]);
       
   150 	return 6;
       
   151 #else
       
   152 	#pragma message("Note: Bluetooth stack will not contain AVCTP or AVDTP");
       
   153 	return 4;
       
   154 #endif // BLUETOOTH_NO_AV
       
   155 #endif // TCI
       
   156 	};
       
   157 
       
   158 CProtocolBase* CBTProtocolFamily::NewProtocolL(TUint /*aSockType*/,TUint aProtocol)
       
   159 /**
       
   160 	Called by the socket server to create an instance of a new 
       
   161 	Protocol (layer) of the specified name - must be a subclass of 
       
   162 	CProtocolBase.
       
   163 **/
       
   164 	{
       
   165 	LOG_FUNC
       
   166 
       
   167 	// Create the Security mgr
       
   168 	if (!iSecurityMgr)
       
   169 		{
       
   170 		iSecurityMgr = CBTSecMan::NewL();
       
   171 		}
       
   172 
       
   173 	// We create our one instance of our protocols
       
   174 	CBluetoothProtocolBase* p = NULL;
       
   175 
       
   176 	// Create the Cod Service manager with reference to linkmgr
       
   177 	if (!iCodServiceMan)
       
   178 		{
       
   179 		iCodServiceMan = CBTCodServiceMan::NewL(/*reinterpret_cast<CLinkMgrProtocol&>(p)*/);
       
   180 		}
       
   181 		
       
   182 
       
   183 	switch (aProtocol)
       
   184 		{
       
   185 	case KBTLinkManager:
       
   186 		LOG(_L("CBTProtocolFamily::NewProtocolL - BTLinkMgr"));
       
   187 		p = CLinkMgrProtocol::NewL(*iSecurityMgr, iControlPlane, *iCodServiceMan);
       
   188 		
       
   189 		iCodServiceMan->iLinkMgr = reinterpret_cast<CLinkMgrProtocol*>(p);
       
   190 		
       
   191 		break;
       
   192 
       
   193 #ifdef TCI
       
   194 	case KTCIL2CAP:
       
   195 #endif
       
   196 	case KL2CAP:
       
   197 		LOG(_L("CBTProtocolFamily::NewProtocolL - L2CAP"));
       
   198 		p = CL2CAPProtocol::NewL(*iSecurityMgr, iControlPlane, *iCodServiceMan);
       
   199 		break;
       
   200 
       
   201 #ifndef TCI
       
   202 	case KRFCOMM:
       
   203 		LOG(_L("CBTProtocolFamily::NewProtocolL - RFCOMM"));
       
   204 		p = CRfcommProtocol::NewL(*iSecurityMgr, iControlPlane, *iCodServiceMan );
       
   205 		break;
       
   206 
       
   207 	case KSDP:
       
   208 		LOG(_L("CBTProtocolFamily::NewProtocolL - SDP"));
       
   209 		p = CSdpProtocol::NewL(*iSecurityMgr, iControlPlane, *iCodServiceMan);
       
   210 		break;
       
   211 	case KAVCTP:
       
   212 #ifndef BLUETOOTH_NO_AV
       
   213 		LOG(_L("CBTProtocolFamily::NewProtocolL - AVCTP"));
       
   214 		p = CAvctpProtocol::NewL(*iSecurityMgr, iControlPlane, *iCodServiceMan);
       
   215 #else
       
   216 		LOG(_L("CBTProtocolFamily::NewProtocolL - AVCTP: NOT SUPPORTED, Leaving"));
       
   217 		User::Leave(KErrNotSupported);
       
   218 #endif //BLUETOOTH_NO_AV
       
   219 		break;
       
   220 
       
   221 	case KAVDTP:
       
   222 #ifndef BLUETOOTH_NO_AV
       
   223 		LOG(_L("CBTProtocolFamily::NewProtocolL - AVDTP"));
       
   224 		p = CAvdtpProtocol::NewL(*iSecurityMgr, iControlPlane, *iCodServiceMan);
       
   225 #else
       
   226 		LOG(_L("CBTProtocolFamily::NewProtocolL - AVDTP: NOT SUPPORTED, Leaving"));
       
   227 		User::Leave(KErrNotSupported);
       
   228 #endif //BLUETOOTH_NO_AV
       
   229 		break;
       
   230 
       
   231 #endif //TCI
       
   232 
       
   233 	default:
       
   234 		User::Leave(KErrArgument);
       
   235 		}
       
   236 	CleanupStack::PushL(p);
       
   237 	iControlPlane.AttachProtocolL(aProtocol, *p);
       
   238 	CleanupStack::Pop(p);
       
   239 	return p;
       
   240 	}
       
   241 	
       
   242 void CBTProtocolFamily::Open()
       
   243 	{
       
   244 	LOG_FUNC
       
   245 	// we don't use the reference-counting of the base-class. We prefer to async close
       
   246 	// so we override Open amd implement our own ref counting.
       
   247 	iBTRefCount++;
       
   248 	}
       
   249 
       
   250 void CBTProtocolFamily::Close()
       
   251 	{
       
   252 	LOG_FUNC
       
   253 	if(--iBTRefCount <= 0)
       
   254 		{
       
   255 		iBTRefCount = 0;
       
   256 		iCallback->Cancel();
       
   257 		// defer calling d'tor
       
   258 		TCallBack cb(Destruct, this);
       
   259 		iCallback->Set(cb);
       
   260 		iCallback->CallBack();
       
   261 		}
       
   262 	}
       
   263 
       
   264 /*static*/ TInt CBTProtocolFamily::Destruct(TAny* aProtocolFamily)
       
   265 	{
       
   266 	LOG_STATIC_FUNC
       
   267 	// self-destruct
       
   268 	CProtocolFamilyBase* p = reinterpret_cast<CProtocolFamilyBase*>(aProtocolFamily);
       
   269 	delete p;
       
   270 
       
   271 	return EFalse;
       
   272 	}
       
   273 
       
   274 CBluetoothProtocolBase::CBluetoothProtocolBase(CBTSecMan& aSecMan, RBTControlPlane& aControlPlane, CBTCodServiceMan& aCodMan)
       
   275 : iSecMan(aSecMan), iControlPlane(aControlPlane), iCodMan(aCodMan)
       
   276 	{
       
   277 	LOG_FUNC
       
   278 	}
       
   279 
       
   280 CBluetoothProtocolBase::~CBluetoothProtocolBase()
       
   281 	{
       
   282 	LOG_FUNC
       
   283 	// detach from control plane
       
   284 	ControlPlane().DetachProtocol(*this);
       
   285 	delete iListener;
       
   286 	}
       
   287 
       
   288 
       
   289 TInt CBluetoothProtocolBase::IncrementListeners()
       
   290 /**
       
   291 	A protocol object (typically a SAP) has declared that it is listening
       
   292 
       
   293 	This may mean that the protocol has to provide a bearer-listener
       
   294 **/
       
   295 	{
       
   296 	LOG_FUNC
       
   297 	TInt retVal = KErrNone;
       
   298 
       
   299 	if (!iListeningEntities++)
       
   300 		{
       
   301 		// need our own listener to bring up lower layers if required for this protocol-level listening SAPs
       
   302 		retVal = StartProtocolListening();
       
   303 		}
       
   304 	return retVal;
       
   305 	}
       
   306 
       
   307 void CBluetoothProtocolBase::DecrementListeners()
       
   308 /**
       
   309 	A protocol object (typically a SAP) has declared that it is not listening
       
   310 
       
   311 	This may mean that the protocol can cleanup the bearer-listener
       
   312 **/
       
   313 	{
       
   314 	LOG_FUNC
       
   315 	--iListeningEntities;
       
   316 	ASSERT_DEBUG(iListeningEntities>=0);
       
   317 	if (!iListeningEntities)
       
   318 		{
       
   319 		// stop protocol listening
       
   320 		StopProtocolListening();
       
   321 		}
       
   322 	}
       
   323 
       
   324 
       
   325 TInt CBluetoothProtocolBase::StartListening(TUint aPort, TUint aSockType, TUint aQueSize, TUid aUid)
       
   326 	{
       
   327 	LOG_FUNC
       
   328 	TRAPD(err, DoStartListeningL(aPort, aSockType, aQueSize, aUid));
       
   329 	return err;
       
   330 	}
       
   331 
       
   332 TInt CBluetoothProtocolBase::StartProtocolListening()
       
   333 	{
       
   334 	LOG_FUNC
       
   335 	// protocol doesnt support listening
       
   336 	Panic(EBTPrtProtocolCannotListen);
       
   337 	return KErrNotSupported;
       
   338 	}
       
   339 
       
   340 // default implementation for stopping a protocol listening
       
   341 void CBluetoothProtocolBase::StopProtocolListening()
       
   342 	{
       
   343 	LOG_FUNC
       
   344 	delete iListener;
       
   345 	iListener = NULL;
       
   346 	}
       
   347 
       
   348 
       
   349 void CBluetoothProtocolBase::DoStartListeningL(TUint aPort, TUint aSockType, TUint aQueSize, TUid aUid)
       
   350 	{
       
   351 	LOG_FUNC
       
   352 	CServProviderBase* sap =iLowerProtocol->NewSAPL(aSockType);
       
   353 	iListener=CIncomingConnectionListener::NewL(*this, sap, aPort, aQueSize, aUid);
       
   354 	}
       
   355 
       
   356 TInt CBluetoothProtocolBase::ControlPlaneMessage(TBTControlPlaneMessage /*aMessage*/, TAny* /*aParam*/)
       
   357 	{
       
   358 	LOG_FUNC
       
   359 	__DEBUGGER(); // a C-plane message was targetted for a protocol that didnt implement C-plane stuff
       
   360 	return KErrNotSupported;
       
   361 	}
       
   362 void CBluetoothProtocolBase::Error(TInt /*aError*/,CProtocolBase* /*aSourceProtocol=NULL*/)
       
   363 	{
       
   364 	LOG_FUNC
       
   365 	//Don't do anything, overrides CProtocolBase::Error which causes a Panic
       
   366 	}
       
   367 void RBTControlPlane::AttachProtocolL(TInt aProtocolNum, CBluetoothProtocolBase& aProtocol)
       
   368 /**
       
   369 	Called when a protocol is instantiated - allows the Control plane to
       
   370 	be aware of it
       
   371 **/
       
   372 	{
       
   373 	LOG_FUNC
       
   374 	if (Protocol(aProtocolNum))
       
   375 		{
       
   376 		User::Leave(KErrAlreadyExists);
       
   377 		}
       
   378 		
       
   379 	TBTProtocol protocol;
       
   380 	protocol.iProtocolNum = aProtocolNum;
       
   381 	protocol.iProtocol = &aProtocol;
       
   382 
       
   383 	User::LeaveIfError(iProtocols.Append(protocol));
       
   384 	}
       
   385 	
       
   386 void RBTControlPlane::DetachProtocol(CBluetoothProtocolBase& aProtocol)
       
   387 	{
       
   388 	LOG_FUNC
       
   389 	for (TInt i=0; i<iProtocols.Count();i++)
       
   390 		{
       
   391 		if (iProtocols[i].iProtocol == &aProtocol)
       
   392 			{
       
   393 			iProtocols.Remove(i);
       
   394 			break;
       
   395 			}
       
   396 		}
       
   397 	}
       
   398 	
       
   399 void RBTControlPlane::Close()
       
   400 	{
       
   401 	LOG_FUNC
       
   402 	iProtocols.Close();
       
   403 	}
       
   404 
       
   405 
       
   406 CBluetoothProtocolBase* RBTControlPlane::Protocol(TInt aProtocolNum) const
       
   407 	{
       
   408 	LOG_FUNC
       
   409 	CBluetoothProtocolBase* p= NULL;
       
   410 	for (TInt i=0; i<iProtocols.Count(); i++)
       
   411 		{
       
   412 		if (iProtocols[i].iProtocolNum == aProtocolNum)
       
   413 			p = iProtocols[i].iProtocol;
       
   414 		}
       
   415 	return p;	// does not pass ownership
       
   416 	}
       
   417 
       
   418 /*
       
   419 a C-plane message to send a signal to the (possible) SAP handling the physical link
       
   420 to the address aAddr
       
   421 */
       
   422 TInt RBTControlPlane::ModifyPhysicalLink(TBTControlPlaneMessage aMessage, const TBTDevAddr& aAddr) const
       
   423 	{
       
   424 	LOG_FUNC
       
   425 	// link mgr must be there!
       
   426 	CBluetoothProtocolBase* linkmgr = Protocol(KBTLinkManager);
       
   427 	ASSERT_DEBUG(linkmgr);
       
   428 	return linkmgr->ControlPlaneMessage(aMessage, const_cast<TAny*>(reinterpret_cast<const TAny*>(&aAddr)));
       
   429 	}
       
   430 	
       
   431 void RBTControlPlane::TryToAndThenPreventHostEncryptionKeyRefresh(const TBTDevAddr& aAddr, MBluetoothControlPlaneToken*& aOutToken)
       
   432 	{
       
   433 	LOG_FUNC
       
   434 	CBluetoothProtocolBase* linkmgr = Protocol(KBTLinkManager);
       
   435 	ASSERT_DEBUG(linkmgr);
       
   436 	const TBTDevAddr* addrPtr = &aAddr;
       
   437 	TAny* ptr = reinterpret_cast<TAny*>(&addrPtr);
       
   438 	TInt err = linkmgr->ControlPlaneMessage(ETryToAndThenPreventHostEncryptionKeyRefresh, ptr);
       
   439 	if (err == KErrNone)
       
   440 		{
       
   441 		aOutToken = *reinterpret_cast<MBluetoothControlPlaneToken**>(ptr);
       
   442 		}
       
   443 	else
       
   444 		{
       
   445 		aOutToken = NULL;
       
   446 		}
       
   447 	}
       
   448 
       
   449 /*
       
   450 a C-plane message to send a message to a target protocol telling them not to authorise a device
       
   451 used for multiple protocols taking part in a single use-case that requires only
       
   452 one authorisation - eg AVCTP and AVDTP doing A2DP + AVRCP stereo headset
       
   453 */
       
   454 TInt RBTControlPlane::Preauthorise(TInt aTargetProtocolNum,
       
   455 									const TOverrideAuthorise& aSetPreauthorisation)
       
   456 	{
       
   457 	LOG_FUNC
       
   458 	// either protocol may not be running
       
   459 	CBluetoothProtocolBase* target = Protocol(aTargetProtocolNum);
       
   460 	if (target)
       
   461 		{
       
   462 		return target->ControlPlaneMessage(EPreauthoriseDevice, const_cast<TAny*>(reinterpret_cast<const TAny*>(&aSetPreauthorisation)));
       
   463 		}
       
   464 	else
       
   465 		{
       
   466 		return KErrNotFound;
       
   467 		}
       
   468 	}
       
   469 
       
   470 TPhysicalLinkPresent RBTControlPlane::PhysicalLinkPresent(const TBTDevAddr& aAddr) const
       
   471 	{
       
   472 	LOG_FUNC
       
   473 	// need to stick down a control plane message to ascertain whether a physical channel is in place
       
   474 	// linkmgr must be there
       
   475 	CBluetoothProtocolBase* linkmgr = Protocol(KBTLinkManager);
       
   476 	ASSERT_DEBUG(linkmgr);
       
   477 	
       
   478 	return static_cast<TPhysicalLinkPresent>(
       
   479 		linkmgr->ControlPlaneMessage(EPresent,
       
   480 		const_cast<TAny*>(reinterpret_cast<const TAny*>(&aAddr))));
       
   481 	}
       
   482 
       
   483 /*
       
   484 a C-plane message to send a signal to the (possible) SAP handling the Physical Link(aAddr)
       
   485 to add aObserver to its list of subscribers.
       
   486 */
       
   487 TInt RBTControlPlane::SubscribePhysicalLink(MPhysicalLinkObserver& aObserver, TBTDevAddr aAddr) const
       
   488 	{
       
   489 	LOG_FUNC
       
   490 	// link mgr must be there!
       
   491 	CBluetoothProtocolBase* linkmgr = Protocol(KBTLinkManager);
       
   492 	ASSERT_DEBUG(linkmgr);
       
   493 	
       
   494 	TPhysicalLinkSubscriptionInfo subscriptionInfo(aObserver,aAddr);
       
   495 	
       
   496 	return linkmgr->ControlPlaneMessage(ESubscribePhysicalLink, const_cast<TAny*>(reinterpret_cast<const TAny*>(&subscriptionInfo)));
       
   497 	}
       
   498 	
       
   499 /*
       
   500 a C-plane message to send a signal to the (possible) SAP handling the Physical Link(aAddr)
       
   501 to remove aObserver its list of subscribers.
       
   502 */
       
   503 TInt RBTControlPlane::UnsubscribePhysicalLink(MPhysicalLinkObserver& aObserver, TBTDevAddr aAddr) const
       
   504 	{
       
   505 	LOG_FUNC
       
   506 	// link mgr must be there!
       
   507 	CBluetoothProtocolBase* linkmgr = Protocol(KBTLinkManager);
       
   508 	ASSERT_DEBUG(linkmgr);
       
   509 	
       
   510 	TPhysicalLinkSubscriptionInfo subscriptionInfo(aObserver,aAddr);
       
   511 	
       
   512 	return linkmgr->ControlPlaneMessage(EUnsubscribePhysicalLink, const_cast<TAny*>(reinterpret_cast<const TAny*>(&subscriptionInfo)));
       
   513 	}
       
   514 	
       
   515 void MBluetoothControlPlaneToken::Release(MBluetoothControlPlaneToken*& aToken)
       
   516 	{
       
   517 	if(aToken)
       
   518 		{
       
   519 		aToken->Release();
       
   520 		aToken = NULL;	
       
   521 		}
       
   522 	}	
       
   523 
       
   524