bluetooth/btstack/common/codman.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2005-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 // Class of Device (CoD) Service Manager.
       
    15 // Manages the Service bit settings in the composite CoD word.
       
    16 // The CoD is a 24 bit word, of which the upper eleven bits describe the Service class 
       
    17 // profiles a Bluetooth device supports. Since these Services can be offered by transitory
       
    18 // applications, we need to provide mechanisms that allow applications to set the Service
       
    19 // bits accordingly. Bits 2 to 12 are the Service class and these are sub-divided into major 
       
    20 // and minor classifications. Bits 0 and 1 are currently always zero.
       
    21 // 23                  13 12      8  7         2 1 0
       
    22 // |<--- Service class -->|<--- Device class --->
       
    23 // [ . . . . . . . ][ . . . . . . . ][ . . . . . .0.0]
       
    24 // The Services are identified by the following table.
       
    25 // 23        13	
       
    26 // v         v
       
    27 // Service LimitedDiscoverableMode     00000000001 ......this is not used
       
    28 // reserved                            00000000010
       
    29 // reserved                            00000000100
       
    30 // Service Positioning                 00000001000
       
    31 // Service Networking                  00000010000
       
    32 // Service Rendering                   00000100000
       
    33 // Service Capturing                   00001000000
       
    34 // Service ObjectTransfer              00010000000
       
    35 // Service Audio                       00100000000
       
    36 // Service Telephony                   01000000000
       
    37 // Service Information                 10000000000
       
    38 // Because the Symbian OS handles data in 32bit and 16bit sizes, the CoD word is always
       
    39 // transported using an unsigned 32bit type. The MS byte is ignored. 
       
    40 // In order to correctly process the Service bits, they are right-shifted 13 bit positions
       
    41 // and then they are managed in a 16 bit type.
       
    42 // Its feasible that multiple applications will offer the same service, therefore the 
       
    43 // CoD Service Manager must keep a separate count (iServRefCount[]) of each Service bit set 
       
    44 // and the bit is only removed from the CoD when the counter is decremented to zero.
       
    45 // The practical implementation is that the CSM privately owns an array of eleven counters.
       
    46 // Each SAP has an iCodServiceBits (16bit type), inherited from the base class which is a
       
    47 // record of the Service bits set by that SAP. So the SAPs are know their individual Service
       
    48 // bit settings and the CSM knows the totals.
       
    49 // As a further precaution against mis-use, each SAP will be allowed one shot at setting
       
    50 // the bits. This is controlled by assigning the msb (of iCodServiceBits) as a flag which
       
    51 // will be TRUE when the Service bit(s) have been set. This is defined as KBTCodBitsRegdFlag.
       
    52 // The action of the Publish and Suscribe interface (P&S) for writing the CoD remains, but is 
       
    53 // now sub-ordinate to the SAP managed Service bits. The P&S execution path has been diverted
       
    54 // from Linkmgr to the CSM. The P&S sets the CoD Device class bits as before, but its
       
    55 // Service bit(s) are ORed with the SAP settings before writing the CoD.   
       
    56 // 
       
    57 //
       
    58 
       
    59 
       
    60 #include <bluetooth/logger.h>
       
    61 #include "codman.h"
       
    62 #include "linkmgr.h"
       
    63 
       
    64 #ifdef __FLOG_ACTIVE
       
    65 _LIT8(KLogComponent, LOG_COMPONENT_IN_CONN_LISTENER);
       
    66 #endif
       
    67 
       
    68 //------------------------------------------------------------------------//
       
    69 //class CBTCodServiceMan
       
    70 //------------------------------------------------------------------------//
       
    71 
       
    72 void Panic(TBTCodPanic aPanic)
       
    73 	{
       
    74 	LOG_STATIC_FUNC
       
    75 	User::Panic(KBTCodPanic, aPanic);
       
    76 	}
       
    77 
       
    78 CBTCodServiceMan* CBTCodServiceMan::NewL()
       
    79 	{
       
    80 #ifdef __FLOG_ACTIVE
       
    81 	CONNECT_LOGGER
       
    82 #endif
       
    83 	LOG_STATIC_FUNC
       
    84 	CBTCodServiceMan* self = new(ELeave) CBTCodServiceMan();
       
    85 	CleanupStack::PushL(self);
       
    86 	self->ConstructL();
       
    87 	CleanupStack::Pop();
       
    88 	return self;
       
    89 	}
       
    90 
       
    91 CBTCodServiceMan::CBTCodServiceMan()
       
    92 	{
       
    93 	LOG_FUNC
       
    94 	iServRefCount.Reset();
       
    95 	}
       
    96 
       
    97 void CBTCodServiceMan::ConstructL()
       
    98 	{
       
    99 	LOG_FUNC
       
   100 	}
       
   101 
       
   102 CBTCodServiceMan::~CBTCodServiceMan()
       
   103 	{
       
   104 	LOG_FUNC
       
   105 	__ASSERT_DEBUG(ResolveServiceBits()==NULL, Panic(EBTCodServiceBits));
       
   106 #ifdef __FLOG_ACTIVE
       
   107 	CLOSE_LOGGER
       
   108 #endif
       
   109 	}
       
   110 
       
   111 void CBTCodServiceMan::Initialise()
       
   112 	{
       
   113 	LOG_FUNC
       
   114 	iPandSCod = iLinkMgr->iLocalDeviceSettings.DeviceClass();	// iPandSCod now has valid CoD 
       
   115 	}
       
   116 
       
   117 TInt CBTCodServiceMan::RegisterCodService(TUint16 aCodService)
       
   118 /*
       
   119    This method is called via the base class (CBluetoothSAP), when an L2CAPSAP 
       
   120    or RFCommSAP becomes active. It keeps a count of the Service bits being set.
       
   121 */
       
   122 	{
       
   123 	LOG_FUNC
       
   124 	TInt err = KErrNone;
       
   125 	TUint index = 0;
       
   126 	
       
   127 	while (aCodService != 0)
       
   128 		{
       
   129 		if (aCodService & KBTCodServiceLSB)
       
   130 			{
       
   131 			iServRefCount[index]++;
       
   132 			}
       
   133 		index++;
       
   134 		aCodService >>= 1;
       
   135 		}
       
   136 
       
   137 	TRAP(err, WriteCoDL());
       
   138 	return err;
       
   139 	}
       
   140 
       
   141 	
       
   142 TInt CBTCodServiceMan::RemoveCodService(TUint16 aCodService)
       
   143 	{
       
   144 /*
       
   145    This method is called via the base class (CBluetoothSAP), when an L2CAPSAP 
       
   146    or RFCommSAP closes. It decrements the service bit counters and if any reach
       
   147    zero, the CoD will be written and delete the bit(s).
       
   148 */
       
   149 	LOG_FUNC
       
   150 	TInt err = KErrNone;
       
   151 	TUint index = 0;
       
   152 	TBool removeService = EFalse;
       
   153 		
       
   154 	while (aCodService != 0)
       
   155 		{
       
   156 		if (aCodService & KBTCodServiceLSB)
       
   157 			{
       
   158 			__ASSERT_DEBUG(iServRefCount[index] > 0, Panic(EBTCodBadCount));
       
   159 			if(iServRefCount[index])
       
   160 				{
       
   161 				if (--iServRefCount[index] == 0)
       
   162 					{
       
   163 					removeService = ETrue;
       
   164 					}
       
   165 				}
       
   166 			}
       
   167 		aCodService >>= 1;
       
   168 		index++;
       
   169 		}
       
   170 
       
   171 	if (removeService)
       
   172 		{
       
   173 		TRAP(err, WriteCoDL());
       
   174 		}
       
   175 	return err;
       
   176 	}
       
   177 	
       
   178 	
       
   179 TUint16 CBTCodServiceMan::ResolveServiceBits()
       
   180 	{
       
   181 /*
       
   182    This private method will sweep through the iServRefCounts and return
       
   183    a tally of the Service bit positions currently set.
       
   184 */
       
   185 	LOG_FUNC
       
   186 	TUint16 serviceBits = 0;
       
   187 
       
   188 	for (TUint i=0; i<KBTMaxCodServices; i++)
       
   189 		{
       
   190 		if (iServRefCount[i])
       
   191 			{
       
   192 			serviceBits |= 1<<i;
       
   193 			}
       
   194 		}
       
   195 	return serviceBits;
       
   196 	}
       
   197 
       
   198 
       
   199 TInt CBTCodServiceMan::PandSCodHandler(TUint32 aCod)
       
   200 	{
       
   201 	LOG_FUNC
       
   202 	// The P&S interface wants to write the CoD value
       
   203 	TInt err = KErrNone;
       
   204 
       
   205 	aCod &= KBTCodMask;							// ensure upper unused byte is clear
       
   206 	iPandSCod = aCod;							// save new P&S CoD word
       
   207 	TRAP(err, WriteCoDL());
       
   208 	return err;
       
   209 	}
       
   210 
       
   211 
       
   212 void CBTCodServiceMan::WriteCoDL()
       
   213 	{
       
   214 /*
       
   215    This private method is called whenever SAP services bits require updating.
       
   216    These bits are obtained from the iServRefCounts and ORed with P&S service
       
   217    settings before being written to the CoD.
       
   218 */
       
   219 	LOG_FUNC
       
   220 	TUint32 sapServiceBits;
       
   221 
       
   222 	sapServiceBits = ResolveServiceBits();		// sweep through the iServRefCounts 
       
   223 	sapServiceBits <<= KBTCodServiceOffset;		// re-position the service bits
       
   224 
       
   225 	__ASSERT_ALWAYS(iLinkMgr, Panic(EBTCodBadLinkmgr));
       
   226 	iLinkMgr->WriteClassOfDeviceL(sapServiceBits | iPandSCod);	// write Cod with managed Service bits 
       
   227 	}
       
   228