bluetoothmgmt/bluetoothclientlib/btlib/eir.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2007-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 // 0
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @publishedAll
       
    20  @released
       
    21  @file
       
    22 */
       
    23 
       
    24 #include <utf.h>
       
    25 #include <bluetooth/logger.h>
       
    26 #include "bttypes.h" 
       
    27 
       
    28 #ifdef __FLOG_ACTIVE
       
    29 _LIT8(KLogComponent, LOG_COMPONENT_BTLIB);
       
    30 #endif
       
    31 
       
    32 void Panic(TEirWrapperPanics aCode)
       
    33 	{
       
    34 	User::Panic(KEirWrapperPanicName, aCode);
       
    35 	}
       
    36 
       
    37 
       
    38 // Size of 16/128 bit UUIDs in bytes
       
    39 const TUint8 KSizeOf16BitUUID = 2;
       
    40 const TUint8 KSizeOf128BitUUID = 16;
       
    41 
       
    42 // Size of TxPowerLevel data in bytes
       
    43 #define KSizeOfTxPowerLevelData 1
       
    44 
       
    45 
       
    46 /** 
       
    47  Constructs an TBluetoothNameRecordWrapper object from an TNameRecord object.
       
    48  The reference of aNameRecord is stored in the object.
       
    49  This will contain sensible data only if KHostResEir was used in the Inquiry
       
    50  @param aNameRecord for Device Name and Extended Inquiry Response 
       
    51  */
       
    52 EXPORT_C TBluetoothNameRecordWrapper::TBluetoothNameRecordWrapper(const TNameRecord& aNameRecord)
       
    53 : iEirCodec(aNameRecord)
       
    54 	{
       
    55 	LOG_FUNC
       
    56 	}
       
    57 
       
    58 /**
       
    59  Obtain the Device Name from inquiry response. This may be a complete or partial name depending on what is available.
       
    60  @param aName is where the Device Name converted into Unicode format is to be stored
       
    61  @param aIsComplete indicates whether the name is complete or partial.
       
    62  @return an error code (KErrNotFound means no name is present in this EIR packet)
       
    63  */
       
    64 EXPORT_C TInt TBluetoothNameRecordWrapper::GetDeviceName(TDes16& aName, TBool& aIsComplete) const
       
    65 	{
       
    66 	LOG_FUNC
       
    67 	TPtrC8 name;
       
    68 	aIsComplete = EFalse;
       
    69 	TInt error = iEirCodec.GetDeviceName(name);
       
    70 	if(error >= KErrNone)
       
    71 		{
       
    72 		if(error == EDataComplete)
       
    73 
       
    74 			{
       
    75 			aIsComplete = ETrue;
       
    76 			}
       
    77 		}
       
    78 		
       
    79 	if(error >= KErrNone)
       
    80 		{
       
    81 		error = CnvUtfConverter::ConvertToUnicodeFromUtf8(aName, name);
       
    82 		}
       
    83 		
       
    84 	// in case of an error from GetData or conversion, return null name and mark it's partial
       
    85 	if(error != KErrNone)
       
    86 		{
       
    87 		// indicate client the name is partial to invite a name request.
       
    88 		aIsComplete = EFalse;
       
    89 		aName.Zero();
       
    90 		}
       
    91 
       
    92 	return error;
       
    93 	}
       
    94 
       
    95 /**
       
    96  Retrieve the full list of UUIDs contained in this EIR. Please note that all types of UUID will be merged together in the single array.
       
    97  @param aUuidContainer CUuidContainer object where all UUIDs found are to be stored, including 16, 32 and 128 bit uuids
       
    98  @return an error code
       
    99  */
       
   100 EXPORT_C TInt TBluetoothNameRecordWrapper::GetServiceClassUuids(RExtendedInquiryResponseUUIDContainer& aEIRContainer) const
       
   101 	{
       
   102 	LOG_FUNC
       
   103 	TPtrC8 uuids;
       
   104 	TInt error = KErrNone;
       
   105 	// 16 bit UUID
       
   106 	error = iEirCodec.GetData(EEirUUID16Complete, uuids);
       
   107 	if(error != KErrNone)
       
   108 		{
       
   109 		// can't find complete tag, try partial one
       
   110 		error = iEirCodec.GetData(EEirUUID16Partial, uuids);
       
   111 		// find partial tag, set uuid
       
   112 		// or we can't find either parital or complete tag, no 16 bit uuid exists in this eir packet
       
   113 		// set complete to partial, this indicates the client there might be uuids in sdp database,
       
   114 		// so client might want to do a sdp service discovery.
       
   115 		aEIRContainer.SetCompleteness(RExtendedInquiryResponseUUIDContainer::EUUID16, EFalse);
       
   116 		if(error == KErrNone)
       
   117 			{
       
   118 			// Add the uuid into the container
       
   119 			error = AddUuids16(aEIRContainer, uuids);
       
   120 			}
       
   121 		else
       
   122 			{
       
   123 			// can't find either parital or complete tag, no 16 bit uuid exists in this eir packet
       
   124 			// set complete to partial, this indicates the client there might be uuids in sdp database,
       
   125 			// so client might want to do a sdp service discovery.
       
   126 			aEIRContainer.SetCompleteness(RExtendedInquiryResponseUUIDContainer::EUUID16, EFalse);
       
   127 			error = KErrNone;
       
   128 			}
       
   129 		}
       
   130 	else
       
   131 		{
       
   132 		// find complete tag, set uuid
       
   133 		aEIRContainer.SetCompleteness(RExtendedInquiryResponseUUIDContainer::EUUID16, ETrue);
       
   134 		// Add the uuid into the container
       
   135 		error = AddUuids16(aEIRContainer, uuids);
       
   136 		}
       
   137 
       
   138 	// 128 bit UUID
       
   139 	if(error == KErrNone)
       
   140 		{
       
   141 		// There hasn't been any error in previous adding 16 bit UUID action
       
   142 		error = iEirCodec.GetData(EEirUUID128Complete, uuids);
       
   143 		if(error != KErrNone)
       
   144 			{
       
   145 			// can't find complete tag, try partial one
       
   146 			error = iEirCodec.GetData(EEirUUID128Partial, uuids);
       
   147 			// find partial tag, set uuid
       
   148 			// or we can't find either parital or complete tag, no 128 bit uuid exists in this eir packet.
       
   149 			// set complete to partial, this indicates the client there might be uuids in sdp database,
       
   150 			// so client might want to do a sdp service discovery.
       
   151 			aEIRContainer.SetCompleteness(RExtendedInquiryResponseUUIDContainer::EUUID128, EFalse);
       
   152 			if(error == KErrNone)
       
   153 				{
       
   154 				// Add the uuid into the container
       
   155 				error = AddUuids128(aEIRContainer, uuids);
       
   156 				}
       
   157 			else
       
   158 				{
       
   159 				// can't find either parital or complete tag, no 128 bit uuid exists in this eir packet.
       
   160 				// set complete to partial, this indicates the client there might be uuids in sdp database,
       
   161 				// so client might want to do a sdp service discovery.
       
   162 				aEIRContainer.SetCompleteness(RExtendedInquiryResponseUUIDContainer::EUUID128, EFalse);
       
   163 				error = KErrNone;
       
   164 				}
       
   165 			}
       
   166 		else
       
   167 			{
       
   168 			// find complete tag, set uuid
       
   169 			aEIRContainer.SetCompleteness(RExtendedInquiryResponseUUIDContainer::EUUID128, ETrue);
       
   170 			// Add the uuid into the container
       
   171 			error = AddUuids128(aEIRContainer, uuids);
       
   172 			}
       
   173 		}
       
   174 
       
   175 	return error;
       
   176 	}
       
   177 
       
   178 /**
       
   179  Retrieve the vendor specific data from this EIR. 
       
   180  @param aDest Array where the vendor specific data is to be stored
       
   181  @return An error code (KErrNotFound means no Manufacturer Specific Data is present in this EIR packet)
       
   182  */
       
   183 EXPORT_C TInt TBluetoothNameRecordWrapper::GetVendorSpecificData(TDes8& aVendorSpecificData) const
       
   184 	{
       
   185 	LOG_FUNC
       
   186 	TPtrC8 vendorSpecificData;
       
   187 	TInt error = iEirCodec.GetData(EEirVendorSpecific, vendorSpecificData);
       
   188 	if(error != KErrNone)
       
   189 		{
       
   190 		vendorSpecificData.Set(KNullDesC8());
       
   191 		}
       
   192 	else
       
   193 		{
       
   194 		aVendorSpecificData.Copy(vendorSpecificData);
       
   195 		}
       
   196 	return error;
       
   197 	}
       
   198 
       
   199 /**
       
   200  Retrieve the Transmission Power Level from EIR. 
       
   201  @param aTxPowerLevel where the Transmission Power Level from this EIR is to be stored
       
   202  @return an error code (KErrNotFound means no Transmission Power Level is present in this EIR packet)
       
   203  */
       
   204 EXPORT_C TInt TBluetoothNameRecordWrapper::GetTxPowerLevel(TInt8& aTxPowerLevel) const
       
   205 	{
       
   206 	LOG_FUNC
       
   207 	TPtrC8 txPowerLevelPtr;
       
   208 	TInt error = iEirCodec.GetData(EEirTxPowerLevel, txPowerLevelPtr);
       
   209 	// if txPowerLevelPtr is longer than 1 byte, error KErrCorrupt
       
   210 	if(error == KErrNone && (txPowerLevelPtr.Length() != KSizeOfTxPowerLevelData))
       
   211 		{
       
   212 		error = KErrCorrupt;
       
   213 		}
       
   214 	else if(error == KErrNone && (txPowerLevelPtr.Length() == KSizeOfTxPowerLevelData))
       
   215 		{
       
   216 		aTxPowerLevel = static_cast <TInt8>(txPowerLevelPtr[0]);
       
   217 		}
       
   218 	else
       
   219 		{
       
   220 		aTxPowerLevel = 0;
       
   221 		}
       
   222 	return error;
       
   223 	}
       
   224 
       
   225 /**
       
   226  Obtain the Flags from EIR if present. 
       
   227  @param aFlags a descriptor where the Flags is to be stored
       
   228  @return an error code (KErrNotFound means no Flags is present in this EIR packet)
       
   229  */
       
   230 EXPORT_C TInt TBluetoothNameRecordWrapper::GetFlags(TDes8& aFlags) const
       
   231 	{
       
   232 	LOG_FUNC
       
   233 	TPtrC8 flags;
       
   234 	TInt error = iEirCodec.GetData(EEirFlags, flags);
       
   235 	if(error != KErrNone)
       
   236 		{
       
   237 		flags.Set(KNullDesC8());
       
   238 		}
       
   239 	else
       
   240 		{
       
   241 		aFlags.Copy(flags);
       
   242 		error = KErrNone;
       
   243 		}
       
   244 	return error;
       
   245 	}
       
   246 
       
   247 /**
       
   248  Obtain the length for Device Name in EIR if present. 
       
   249  This function should be called before GetDeviceName() to initialize size of the buffer,
       
   250  whose reference will be passed into GetDeviceName() as an argument.
       
   251  @return the length of Device Name
       
   252  */
       
   253 EXPORT_C TInt TBluetoothNameRecordWrapper::GetDeviceNameLength() const
       
   254 	{
       
   255 	LOG_FUNC
       
   256 	TPtrC8 name;
       
   257 	TInt ret = iEirCodec.GetDeviceName(name);
       
   258 	if(ret >= KErrNone)
       
   259 		{
       
   260 		ret = name.Length();
       
   261 		}
       
   262 	else
       
   263 		{
       
   264 		ret = 0;
       
   265 		}
       
   266 	return  ret;
       
   267 	}
       
   268 
       
   269 /**
       
   270  Obtain the length for Manufacturer Specific Data in EIR if present. 
       
   271  This function should be called before GetVendorSpecificData() to initialize size of the buffer,
       
   272  whose reference will be passed into GetVendorSpecificData() as an argument.
       
   273  @return the length of Manufacturer Specific Data
       
   274  */
       
   275 EXPORT_C TInt TBluetoothNameRecordWrapper::GetVendorSpecificDataLength() const
       
   276 	{
       
   277 	LOG_FUNC
       
   278 	TPtrC8 vendorSpecificData;
       
   279 	TInt ret = iEirCodec.GetData(EEirVendorSpecific, vendorSpecificData);
       
   280 	if(ret == KErrNone)
       
   281 		{
       
   282 		ret = vendorSpecificData.Length();
       
   283 		}
       
   284 	else
       
   285 		{
       
   286 		ret = 0;
       
   287 		}
       
   288 	return ret;
       
   289 	}
       
   290 
       
   291 /**
       
   292  Obtain the length for Flags in EIR if present. 
       
   293  This function should be called before GetFlags() to initialize size of the buffer,
       
   294  whose reference will be passed into GetFlags() as an argument.
       
   295  @return the length of Flags
       
   296  */
       
   297 EXPORT_C TInt TBluetoothNameRecordWrapper::GetFlagsLength() const
       
   298 	{
       
   299 	LOG_FUNC
       
   300 	TPtrC8 flags;
       
   301 	TInt ret = iEirCodec.GetData(EEirFlags, flags);
       
   302 	if(ret == KErrNone)
       
   303 		{
       
   304 		ret = flags.Length();
       
   305 		}
       
   306 	else
       
   307 		{
       
   308 		ret = 0;
       
   309 		}
       
   310 	return ret;
       
   311 	}
       
   312 
       
   313 TInt TBluetoothNameRecordWrapper::AddUuids16(RExtendedInquiryResponseUUIDContainer& aEIRContainer, TPtrC8& aUuids) const
       
   314 	{
       
   315 	TInt error = KErrNone;
       
   316 	TInt length = aUuids.Length() / KSizeOf16BitUUID;
       
   317 	TUUID uuid;
       
   318 	
       
   319 	for(TInt i = 0; i < length; i++)
       
   320 		{
       
   321 		__ASSERT_DEBUG(((aUuids.Length() - i*KSizeOf16BitUUID)% KSizeOf16BitUUID) == 0, Panic(EEirBadUuid16List));
       
   322 		TRAP(error, uuid.SetFromLittleEndianL(aUuids.Mid(i*KSizeOf16BitUUID, KSizeOf16BitUUID)));
       
   323 		if(error == KErrNone)
       
   324 			{
       
   325 			error = aEIRContainer.UUIDs().Add(uuid);
       
   326 			}
       
   327 		else
       
   328 			{
       
   329 			break;
       
   330 			}
       
   331 		}
       
   332 	
       
   333 	return error;
       
   334 	}
       
   335 
       
   336 TInt TBluetoothNameRecordWrapper::AddUuids128(RExtendedInquiryResponseUUIDContainer& aEIRContainer, TPtrC8& aUuids) const
       
   337 	{
       
   338 	TInt error = KErrNone;
       
   339 	TInt length = aUuids.Length() / KSizeOf128BitUUID;
       
   340 	TUUID uuid;
       
   341 	
       
   342 	for(TInt i = 0; i < length; i++)
       
   343 		{
       
   344 		__ASSERT_DEBUG(((aUuids.Length() - i*KSizeOf128BitUUID)% KSizeOf128BitUUID) == 0, Panic(EEirBadUuid128List));
       
   345 		TRAP(error, uuid.SetFromLittleEndianL(aUuids.Mid(i*KSizeOf128BitUUID, KSizeOf128BitUUID)));
       
   346 		if(error == KErrNone)
       
   347 			{
       
   348 			error = aEIRContainer.UUIDs().Add(uuid);
       
   349 			}
       
   350 		else
       
   351 			{
       
   352 			break;
       
   353 			}
       
   354 		}
       
   355 	
       
   356 	return error;
       
   357 	}