diff -r 000000000000 -r 29b1cd4cb562 bluetooth/btstack/common/codman.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetooth/btstack/common/codman.cpp Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,228 @@ +// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Class of Device (CoD) Service Manager. +// Manages the Service bit settings in the composite CoD word. +// The CoD is a 24 bit word, of which the upper eleven bits describe the Service class +// profiles a Bluetooth device supports. Since these Services can be offered by transitory +// applications, we need to provide mechanisms that allow applications to set the Service +// bits accordingly. Bits 2 to 12 are the Service class and these are sub-divided into major +// and minor classifications. Bits 0 and 1 are currently always zero. +// 23 13 12 8 7 2 1 0 +// |<--- Service class -->|<--- Device class ---> +// [ . . . . . . . ][ . . . . . . . ][ . . . . . .0.0] +// The Services are identified by the following table. +// 23 13 +// v v +// Service LimitedDiscoverableMode 00000000001 ......this is not used +// reserved 00000000010 +// reserved 00000000100 +// Service Positioning 00000001000 +// Service Networking 00000010000 +// Service Rendering 00000100000 +// Service Capturing 00001000000 +// Service ObjectTransfer 00010000000 +// Service Audio 00100000000 +// Service Telephony 01000000000 +// Service Information 10000000000 +// Because the Symbian OS handles data in 32bit and 16bit sizes, the CoD word is always +// transported using an unsigned 32bit type. The MS byte is ignored. +// In order to correctly process the Service bits, they are right-shifted 13 bit positions +// and then they are managed in a 16 bit type. +// Its feasible that multiple applications will offer the same service, therefore the +// CoD Service Manager must keep a separate count (iServRefCount[]) of each Service bit set +// and the bit is only removed from the CoD when the counter is decremented to zero. +// The practical implementation is that the CSM privately owns an array of eleven counters. +// Each SAP has an iCodServiceBits (16bit type), inherited from the base class which is a +// record of the Service bits set by that SAP. So the SAPs are know their individual Service +// bit settings and the CSM knows the totals. +// As a further precaution against mis-use, each SAP will be allowed one shot at setting +// the bits. This is controlled by assigning the msb (of iCodServiceBits) as a flag which +// will be TRUE when the Service bit(s) have been set. This is defined as KBTCodBitsRegdFlag. +// The action of the Publish and Suscribe interface (P&S) for writing the CoD remains, but is +// now sub-ordinate to the SAP managed Service bits. The P&S execution path has been diverted +// from Linkmgr to the CSM. The P&S sets the CoD Device class bits as before, but its +// Service bit(s) are ORed with the SAP settings before writing the CoD. +// +// + + +#include +#include "codman.h" +#include "linkmgr.h" + +#ifdef __FLOG_ACTIVE +_LIT8(KLogComponent, LOG_COMPONENT_IN_CONN_LISTENER); +#endif + +//------------------------------------------------------------------------// +//class CBTCodServiceMan +//------------------------------------------------------------------------// + +void Panic(TBTCodPanic aPanic) + { + LOG_STATIC_FUNC + User::Panic(KBTCodPanic, aPanic); + } + +CBTCodServiceMan* CBTCodServiceMan::NewL() + { +#ifdef __FLOG_ACTIVE + CONNECT_LOGGER +#endif + LOG_STATIC_FUNC + CBTCodServiceMan* self = new(ELeave) CBTCodServiceMan(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +CBTCodServiceMan::CBTCodServiceMan() + { + LOG_FUNC + iServRefCount.Reset(); + } + +void CBTCodServiceMan::ConstructL() + { + LOG_FUNC + } + +CBTCodServiceMan::~CBTCodServiceMan() + { + LOG_FUNC + __ASSERT_DEBUG(ResolveServiceBits()==NULL, Panic(EBTCodServiceBits)); +#ifdef __FLOG_ACTIVE + CLOSE_LOGGER +#endif + } + +void CBTCodServiceMan::Initialise() + { + LOG_FUNC + iPandSCod = iLinkMgr->iLocalDeviceSettings.DeviceClass(); // iPandSCod now has valid CoD + } + +TInt CBTCodServiceMan::RegisterCodService(TUint16 aCodService) +/* + This method is called via the base class (CBluetoothSAP), when an L2CAPSAP + or RFCommSAP becomes active. It keeps a count of the Service bits being set. +*/ + { + LOG_FUNC + TInt err = KErrNone; + TUint index = 0; + + while (aCodService != 0) + { + if (aCodService & KBTCodServiceLSB) + { + iServRefCount[index]++; + } + index++; + aCodService >>= 1; + } + + TRAP(err, WriteCoDL()); + return err; + } + + +TInt CBTCodServiceMan::RemoveCodService(TUint16 aCodService) + { +/* + This method is called via the base class (CBluetoothSAP), when an L2CAPSAP + or RFCommSAP closes. It decrements the service bit counters and if any reach + zero, the CoD will be written and delete the bit(s). +*/ + LOG_FUNC + TInt err = KErrNone; + TUint index = 0; + TBool removeService = EFalse; + + while (aCodService != 0) + { + if (aCodService & KBTCodServiceLSB) + { + __ASSERT_DEBUG(iServRefCount[index] > 0, Panic(EBTCodBadCount)); + if(iServRefCount[index]) + { + if (--iServRefCount[index] == 0) + { + removeService = ETrue; + } + } + } + aCodService >>= 1; + index++; + } + + if (removeService) + { + TRAP(err, WriteCoDL()); + } + return err; + } + + +TUint16 CBTCodServiceMan::ResolveServiceBits() + { +/* + This private method will sweep through the iServRefCounts and return + a tally of the Service bit positions currently set. +*/ + LOG_FUNC + TUint16 serviceBits = 0; + + for (TUint i=0; iWriteClassOfDeviceL(sapServiceBits | iPandSCod); // write Cod with managed Service bits + } +