bluetooth/btstack/l2cap/l2cap.cpp
changeset 0 29b1cd4cb562
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 implements the CL2CAPProtocol object that is the contact point from
       
    15 // BT PRT to the L2cap stack
       
    16 // 
       
    17 //
       
    18 
       
    19 #include <bluetooth/logger.h>
       
    20 #include <bt_sock.h>
       
    21 #include <bluetooth/aclsockaddr.h>
       
    22 
       
    23 #include "l2cap.h"
       
    24 
       
    25 #include "l2sapstates.h"
       
    26 #include "l2util.h"
       
    27 #include "linkmgr.h"
       
    28 #include "l2capSAPSignalHandler.h"
       
    29 #include "l2sap.h"
       
    30 
       
    31 
       
    32 #ifdef _DEBUG
       
    33 #include "L2CapDebugControlInterface.h"
       
    34 #endif
       
    35 
       
    36 #ifdef __FLOG_ACTIVE
       
    37 _LIT8(KLogComponent, LOG_COMPONENT_L2CAP);
       
    38 #endif
       
    39 
       
    40 // Construction & Initialisation
       
    41 
       
    42 CL2CAPProtocol::CL2CAPProtocol(CBTSecMan& aSecMan, RBTControlPlane& aControlPlane, CBTCodServiceMan& aCodMan)
       
    43  : CBluetoothProtocolBase(aSecMan, aControlPlane, aCodMan)
       
    44 	{
       
    45 	LOG_FUNC
       
    46 	TCallBack cb(TryToClose, this);
       
    47 	iIdleTimerEntry.Set(cb);
       
    48 	}
       
    49 
       
    50 CL2CAPProtocol::~CL2CAPProtocol()
       
    51 	{
       
    52 	LOG_FUNC
       
    53 	RemoveIdleTimerEntry();
       
    54 
       
    55 	delete iStateFactory;
       
    56 	delete iSigStateFactory;
       
    57 	
       
    58 	if(LowerProtocol())
       
    59 		{
       
    60 		LowerProtocol()->Close();
       
    61 		}
       
    62 
       
    63 	// Delete the Mux controller.
       
    64 	delete iMuxController;
       
    65 
       
    66 #ifdef _DEBUG
       
    67 	SBtTls* tls = static_cast<SBtTls*>(Dll::Tls());
       
    68 	CDebugControlInterface* ptr = tls->iDebugCtrlIF;
       
    69 	delete ptr;
       
    70 	tls->iDebugCtrlIF = NULL;
       
    71 #endif
       
    72 
       
    73 #ifdef __FLOG_ACTIVE
       
    74 	CLOSE_LOGGER
       
    75 #endif
       
    76 	}
       
    77 
       
    78 CL2CAPProtocol* CL2CAPProtocol::NewL(CBTSecMan& aSecMan, RBTControlPlane& aControlPlane, CBTCodServiceMan& aCodMan)
       
    79 	{
       
    80 #ifdef __FLOG_ACTIVE
       
    81 	CONNECT_LOGGER
       
    82 #endif
       
    83 	LOG_STATIC_FUNC
       
    84 	CL2CAPProtocol* prot = new (ELeave) CL2CAPProtocol(aSecMan, aControlPlane, aCodMan);
       
    85 	CleanupStack::PushL(prot);
       
    86 	prot->ConstructL();
       
    87 	CleanupStack::Pop();
       
    88 	return prot;
       
    89 	}
       
    90 
       
    91 void CL2CAPProtocol::ConstructL()
       
    92 	{
       
    93 	LOG_FUNC
       
    94 	iMuxController = new (ELeave) CL2CAPMuxController(*this);	
       
    95 	}
       
    96 
       
    97 void CL2CAPProtocol::InitL(TDesC& /*aTag*/)
       
    98 /**
       
    99 	Pre-binding initialise.
       
   100 	Allocate any objects we need here.
       
   101 	The socket ensures that this function will only be called once per
       
   102 	object of this class, regardless of how long it hangs around.
       
   103 **/
       
   104 	{
       
   105 	LOG_FUNC
       
   106 	// Init 
       
   107 	__ASSERT_DEBUG(!iClosePending, Panic(EL2CAPProtocolOpenedAfterClose));
       
   108 	__ASSERT_DEBUG(!iIdleEntryQueued, Panic(EL2CAPProtocolOpenedAfterClose));
       
   109 	__ASSERT_DEBUG(!iStateFactory, Panic(EL2CAPProtocolOpenedAfterClose));
       
   110 	__ASSERT_DEBUG(!iSigStateFactory, Panic(EL2CAPProtocolOpenedAfterClose));
       
   111 
       
   112 	// Create all the things we need now
       
   113 	LOG(_L("L2CAP : Initialising states"));
       
   114 	iStateFactory=CL2CAPSAPStateFactory::NewL();
       
   115 	iSigStateFactory=CL2CAPSignalStateFactory::NewL();
       
   116 	LOG(_L("L2CAP : Initialising complete"));
       
   117 
       
   118 #ifdef _DEBUG
       
   119 	SBtTls* tls = static_cast<SBtTls*>(Dll::Tls());
       
   120 	tls->iDebugCtrlIF = CDebugControlInterface::NewL();
       
   121 #endif
       
   122 	}
       
   123 
       
   124 
       
   125 void CL2CAPProtocol::StartL()
       
   126 /**
       
   127 	Binding complete.
       
   128 	Startup call from socket.  Do nothing
       
   129 **/
       
   130 	{
       
   131 	LOG_FUNC
       
   132 	}
       
   133 
       
   134 // From higher protocol
       
   135 void CL2CAPProtocol::BindL(CProtocolBase* /*aProtocol*/, TUint /*aId*/)
       
   136 	{
       
   137 	// Could register the protocol that's bound to us
       
   138 	LOG_FUNC
       
   139 	}
       
   140 
       
   141 void CL2CAPProtocol::BindToL(CProtocolBase* aProtocol)
       
   142 	{
       
   143 	LOG_FUNC
       
   144 #ifdef _DEBUG
       
   145 	TServerProtocolDesc prtDesc;
       
   146 	aProtocol->Identify(&prtDesc);
       
   147 
       
   148 	if(prtDesc.iAddrFamily!=KBTAddrFamily ||
       
   149 	   prtDesc.iProtocol!=KBTLinkManager)
       
   150 		{
       
   151 		LEAVEL(KErrBtEskError);
       
   152 		}
       
   153 #endif
       
   154 	aProtocol->BindL(this, 0);
       
   155 	aProtocol->Open();
       
   156 	iLowerProtocol = static_cast<CBluetoothProtocolBase*>(aProtocol);
       
   157 	}
       
   158 
       
   159 // Factory functions
       
   160 CServProviderBase* CL2CAPProtocol::NewSAPL(TUint aSockType)
       
   161 /** 
       
   162 	Create a new SAP.
       
   163 	The SAP returned is owned by the caller -- this protocol will not clean it up.
       
   164 	The socket uses this function to create a new SAP, and the socket will delete when it
       
   165 	is finished with it.
       
   166 **/
       
   167 	{
       
   168 	LOG_FUNC
       
   169 	
       
   170 	CL2CAPConnectionSAP* lsap = NULL;
       
   171 		
       
   172 	switch(aSockType)
       
   173 		{
       
   174 	case KSockSeqPacket:  // packet interface
       
   175 		lsap=CL2CAPConnectionSAP::NewL(*this);
       
   176 		break;
       
   177 	default:
       
   178 		LEAVEL(KErrNotSupported);
       
   179 		break;
       
   180 		}
       
   181 
       
   182 	return lsap;
       
   183 	}
       
   184 
       
   185 // Query functions
       
   186 
       
   187 void CL2CAPProtocol::Identify(TServerProtocolDesc *aDesc)const
       
   188 //
       
   189 // Identify request from SOCKET server
       
   190 //
       
   191 	{
       
   192 	LOG_FUNC
       
   193 	CL2CAPProtocol::ProtocolIdentity(aDesc);
       
   194 	}
       
   195 
       
   196 void CL2CAPProtocol::ProtocolIdentity(TServerProtocolDesc* aDesc)
       
   197 	{
       
   198 	LOG_STATIC_FUNC
       
   199 	_LIT(name,"L2CAP");
       
   200 	aDesc->iProtocol=KL2CAP;
       
   201 	aDesc->iName=name;
       
   202 	aDesc->iAddrFamily=KBTAddrFamily;
       
   203 	aDesc->iSockType=KSockSeqPacket;
       
   204 	
       
   205 	aDesc->iVersion=TVersion(KBTMajor,KBTMinor,KBTBuild);
       
   206 	aDesc->iByteOrder=ELittleEndian;
       
   207 	aDesc->iServiceInfo=KL2CAPSeqPacketServiceInfo;
       
   208 	aDesc->iNamingServices=0;
       
   209 	aDesc->iSecurity=KSocketNoSecurity;
       
   210 	aDesc->iMessageSize=KSocketMessageSizeNoLimit; //This is the MAX packet size.
       
   211 	aDesc->iServiceTypeInfo=ESocketSupport|ETransport|EPreferMBufChains|ENeedMBufs|EUseCanSend;
       
   212 	aDesc->iNumSockets=KL2CAPSockets;
       
   213 	}
       
   214 
       
   215 void CL2CAPProtocol::CloseNow()
       
   216 /**
       
   217 	Close command from base class.
       
   218 	Called when ref count reaches 0.
       
   219 	We don't actually have to close now, but when we finally
       
   220 	do, we must call CanClose (done within TryToClose). That will
       
   221 	actually delete us. In the mean time, if a new client tries
       
   222 	to connect to L2CAP, the socket will use this existing one and just
       
   223 	call Open on it.
       
   224 	What we do here, is queue an idle timer entry. It's expiry will
       
   225 	call TryToClose, which will actually do the close.
       
   226 **/
       
   227 	{
       
   228 	LOG_FUNC
       
   229 	iClosePending = ETrue;
       
   230 	QueIdleTimerEntry();
       
   231 	}
       
   232 
       
   233 void CL2CAPProtocol::Open()
       
   234 /**
       
   235 	Open L2CAP protocol.
       
   236 	Called every time a new client (of L2CAP) wants to use it.
       
   237 **/
       
   238 	{
       
   239 	LOG_FUNC
       
   240 	iClosePending = EFalse;
       
   241 	RemoveIdleTimerEntry();
       
   242 	CProtocolBase::Open();
       
   243 	}
       
   244 
       
   245 void CL2CAPProtocol::Close()
       
   246 	{
       
   247 	LOG_FUNC
       
   248 	CProtocolBase::Close();
       
   249 	}
       
   250 
       
   251 void CL2CAPProtocol::QueIdleTimerEntry()
       
   252 /**
       
   253 	Queue idle timer entry.
       
   254 	When this timer expires, it'll call TryToClose, which actually
       
   255 	causes the thing to finally close down.
       
   256 **/
       
   257 	{
       
   258 	LOG_FUNC
       
   259 	RemoveIdleTimerEntry();
       
   260 	iIdleEntryQueued = ETrue;
       
   261 	BTSocketTimer::Queue(KL2ProtocolIdleTimeout*KL2ProtocolSecondTimerMultiplier, iIdleTimerEntry);
       
   262 	}
       
   263 
       
   264 void CL2CAPProtocol::RemoveIdleTimerEntry()
       
   265 /**
       
   266 	Called whenever we're opened.
       
   267 	Checks there are no idle timer entries queued.
       
   268 **/
       
   269 	{
       
   270 	LOG_FUNC
       
   271 	if (!iIdleEntryQueued)
       
   272 		return;
       
   273 	BTSocketTimer::Remove(iIdleTimerEntry);
       
   274 	iIdleEntryQueued = EFalse;
       
   275 	}
       
   276 
       
   277 void CL2CAPProtocol::TryToClose()
       
   278 	{
       
   279 	LOG_FUNC
       
   280 	if (!iIdleEntryQueued && iClosePending && MuxController().CanProtocolClose())
       
   281 		{
       
   282 		CanClose();
       
   283 		}
       
   284 	}
       
   285 
       
   286 TInt CL2CAPProtocol::TryToClose(TAny* aProtocol)
       
   287 /*
       
   288 	Actually try to close the protocol.
       
   289 	Called after the idle timeout period by the BTSocketTimer. If
       
   290 	we're all set to close down, the thing is closed.
       
   291 */
       
   292 	{
       
   293 	LOG_STATIC_FUNC
       
   294 	CL2CAPProtocol* p=static_cast<CL2CAPProtocol*>(aProtocol);
       
   295 	p->iIdleEntryQueued = EFalse;
       
   296 	p->TryToClose();
       
   297 	return EFalse;
       
   298 	}
       
   299 
       
   300 CL2CAPSAPStateFactory& CL2CAPProtocol::StateFactory() const
       
   301 	{
       
   302 	LOG_FUNC
       
   303 	return *iStateFactory;
       
   304 	}
       
   305 
       
   306 CL2CAPSignalStateFactory& CL2CAPProtocol::SigStateFactory() const
       
   307 	{
       
   308 	LOG_FUNC
       
   309 	return *iSigStateFactory;
       
   310 	}
       
   311 
       
   312 TInt CL2CAPProtocol::BearerConnectComplete(const TBTDevAddr& aAddr, CServProviderBase* aSAP)
       
   313 	{
       
   314 	LOG_FUNC
       
   315 	return iMuxController->BearerConnectComplete(aAddr, aSAP);
       
   316 	}
       
   317 
       
   318 const TBTDevAddr& CL2CAPProtocol::LocalBTAddr() const
       
   319 	{
       
   320 	LOG_FUNC
       
   321 	return static_cast<CLinkMgrProtocol*>(iLowerProtocol)->LocalBTAddress();
       
   322 	}
       
   323 
       
   324 TInt CL2CAPProtocol::StartProtocolListening()
       
   325 // forward L2CAPs listening requirements to listener
       
   326 	{
       
   327 	LOG_FUNC
       
   328 	return CBluetoothProtocolBase::StartListening(EACLPortL2CAP,
       
   329 												  KSockBluetoothTypeACL,
       
   330 												  KL2CAPIncomingConnQueueSize,
       
   331 												  KUidServiceL2CAP);
       
   332 	}
       
   333 
       
   334