diff -r 000000000000 -r 29b1cd4cb562 bluetoothmgmt/bluetoothclientlib/btlib/eir.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetoothmgmt/bluetoothclientlib/btlib/eir.cpp Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,357 @@ +// Copyright (c) 2007-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: +// 0 +// +// + +/** + @publishedAll + @released + @file +*/ + +#include +#include +#include "bttypes.h" + +#ifdef __FLOG_ACTIVE +_LIT8(KLogComponent, LOG_COMPONENT_BTLIB); +#endif + +void Panic(TEirWrapperPanics aCode) + { + User::Panic(KEirWrapperPanicName, aCode); + } + + +// Size of 16/128 bit UUIDs in bytes +const TUint8 KSizeOf16BitUUID = 2; +const TUint8 KSizeOf128BitUUID = 16; + +// Size of TxPowerLevel data in bytes +#define KSizeOfTxPowerLevelData 1 + + +/** + Constructs an TBluetoothNameRecordWrapper object from an TNameRecord object. + The reference of aNameRecord is stored in the object. + This will contain sensible data only if KHostResEir was used in the Inquiry + @param aNameRecord for Device Name and Extended Inquiry Response + */ +EXPORT_C TBluetoothNameRecordWrapper::TBluetoothNameRecordWrapper(const TNameRecord& aNameRecord) +: iEirCodec(aNameRecord) + { + LOG_FUNC + } + +/** + Obtain the Device Name from inquiry response. This may be a complete or partial name depending on what is available. + @param aName is where the Device Name converted into Unicode format is to be stored + @param aIsComplete indicates whether the name is complete or partial. + @return an error code (KErrNotFound means no name is present in this EIR packet) + */ +EXPORT_C TInt TBluetoothNameRecordWrapper::GetDeviceName(TDes16& aName, TBool& aIsComplete) const + { + LOG_FUNC + TPtrC8 name; + aIsComplete = EFalse; + TInt error = iEirCodec.GetDeviceName(name); + if(error >= KErrNone) + { + if(error == EDataComplete) + + { + aIsComplete = ETrue; + } + } + + if(error >= KErrNone) + { + error = CnvUtfConverter::ConvertToUnicodeFromUtf8(aName, name); + } + + // in case of an error from GetData or conversion, return null name and mark it's partial + if(error != KErrNone) + { + // indicate client the name is partial to invite a name request. + aIsComplete = EFalse; + aName.Zero(); + } + + return error; + } + +/** + 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. + @param aUuidContainer CUuidContainer object where all UUIDs found are to be stored, including 16, 32 and 128 bit uuids + @return an error code + */ +EXPORT_C TInt TBluetoothNameRecordWrapper::GetServiceClassUuids(RExtendedInquiryResponseUUIDContainer& aEIRContainer) const + { + LOG_FUNC + TPtrC8 uuids; + TInt error = KErrNone; + // 16 bit UUID + error = iEirCodec.GetData(EEirUUID16Complete, uuids); + if(error != KErrNone) + { + // can't find complete tag, try partial one + error = iEirCodec.GetData(EEirUUID16Partial, uuids); + // find partial tag, set uuid + // or we can't find either parital or complete tag, no 16 bit uuid exists in this eir packet + // set complete to partial, this indicates the client there might be uuids in sdp database, + // so client might want to do a sdp service discovery. + aEIRContainer.SetCompleteness(RExtendedInquiryResponseUUIDContainer::EUUID16, EFalse); + if(error == KErrNone) + { + // Add the uuid into the container + error = AddUuids16(aEIRContainer, uuids); + } + else + { + // can't find either parital or complete tag, no 16 bit uuid exists in this eir packet + // set complete to partial, this indicates the client there might be uuids in sdp database, + // so client might want to do a sdp service discovery. + aEIRContainer.SetCompleteness(RExtendedInquiryResponseUUIDContainer::EUUID16, EFalse); + error = KErrNone; + } + } + else + { + // find complete tag, set uuid + aEIRContainer.SetCompleteness(RExtendedInquiryResponseUUIDContainer::EUUID16, ETrue); + // Add the uuid into the container + error = AddUuids16(aEIRContainer, uuids); + } + + // 128 bit UUID + if(error == KErrNone) + { + // There hasn't been any error in previous adding 16 bit UUID action + error = iEirCodec.GetData(EEirUUID128Complete, uuids); + if(error != KErrNone) + { + // can't find complete tag, try partial one + error = iEirCodec.GetData(EEirUUID128Partial, uuids); + // find partial tag, set uuid + // or we can't find either parital or complete tag, no 128 bit uuid exists in this eir packet. + // set complete to partial, this indicates the client there might be uuids in sdp database, + // so client might want to do a sdp service discovery. + aEIRContainer.SetCompleteness(RExtendedInquiryResponseUUIDContainer::EUUID128, EFalse); + if(error == KErrNone) + { + // Add the uuid into the container + error = AddUuids128(aEIRContainer, uuids); + } + else + { + // can't find either parital or complete tag, no 128 bit uuid exists in this eir packet. + // set complete to partial, this indicates the client there might be uuids in sdp database, + // so client might want to do a sdp service discovery. + aEIRContainer.SetCompleteness(RExtendedInquiryResponseUUIDContainer::EUUID128, EFalse); + error = KErrNone; + } + } + else + { + // find complete tag, set uuid + aEIRContainer.SetCompleteness(RExtendedInquiryResponseUUIDContainer::EUUID128, ETrue); + // Add the uuid into the container + error = AddUuids128(aEIRContainer, uuids); + } + } + + return error; + } + +/** + Retrieve the vendor specific data from this EIR. + @param aDest Array where the vendor specific data is to be stored + @return An error code (KErrNotFound means no Manufacturer Specific Data is present in this EIR packet) + */ +EXPORT_C TInt TBluetoothNameRecordWrapper::GetVendorSpecificData(TDes8& aVendorSpecificData) const + { + LOG_FUNC + TPtrC8 vendorSpecificData; + TInt error = iEirCodec.GetData(EEirVendorSpecific, vendorSpecificData); + if(error != KErrNone) + { + vendorSpecificData.Set(KNullDesC8()); + } + else + { + aVendorSpecificData.Copy(vendorSpecificData); + } + return error; + } + +/** + Retrieve the Transmission Power Level from EIR. + @param aTxPowerLevel where the Transmission Power Level from this EIR is to be stored + @return an error code (KErrNotFound means no Transmission Power Level is present in this EIR packet) + */ +EXPORT_C TInt TBluetoothNameRecordWrapper::GetTxPowerLevel(TInt8& aTxPowerLevel) const + { + LOG_FUNC + TPtrC8 txPowerLevelPtr; + TInt error = iEirCodec.GetData(EEirTxPowerLevel, txPowerLevelPtr); + // if txPowerLevelPtr is longer than 1 byte, error KErrCorrupt + if(error == KErrNone && (txPowerLevelPtr.Length() != KSizeOfTxPowerLevelData)) + { + error = KErrCorrupt; + } + else if(error == KErrNone && (txPowerLevelPtr.Length() == KSizeOfTxPowerLevelData)) + { + aTxPowerLevel = static_cast (txPowerLevelPtr[0]); + } + else + { + aTxPowerLevel = 0; + } + return error; + } + +/** + Obtain the Flags from EIR if present. + @param aFlags a descriptor where the Flags is to be stored + @return an error code (KErrNotFound means no Flags is present in this EIR packet) + */ +EXPORT_C TInt TBluetoothNameRecordWrapper::GetFlags(TDes8& aFlags) const + { + LOG_FUNC + TPtrC8 flags; + TInt error = iEirCodec.GetData(EEirFlags, flags); + if(error != KErrNone) + { + flags.Set(KNullDesC8()); + } + else + { + aFlags.Copy(flags); + error = KErrNone; + } + return error; + } + +/** + Obtain the length for Device Name in EIR if present. + This function should be called before GetDeviceName() to initialize size of the buffer, + whose reference will be passed into GetDeviceName() as an argument. + @return the length of Device Name + */ +EXPORT_C TInt TBluetoothNameRecordWrapper::GetDeviceNameLength() const + { + LOG_FUNC + TPtrC8 name; + TInt ret = iEirCodec.GetDeviceName(name); + if(ret >= KErrNone) + { + ret = name.Length(); + } + else + { + ret = 0; + } + return ret; + } + +/** + Obtain the length for Manufacturer Specific Data in EIR if present. + This function should be called before GetVendorSpecificData() to initialize size of the buffer, + whose reference will be passed into GetVendorSpecificData() as an argument. + @return the length of Manufacturer Specific Data + */ +EXPORT_C TInt TBluetoothNameRecordWrapper::GetVendorSpecificDataLength() const + { + LOG_FUNC + TPtrC8 vendorSpecificData; + TInt ret = iEirCodec.GetData(EEirVendorSpecific, vendorSpecificData); + if(ret == KErrNone) + { + ret = vendorSpecificData.Length(); + } + else + { + ret = 0; + } + return ret; + } + +/** + Obtain the length for Flags in EIR if present. + This function should be called before GetFlags() to initialize size of the buffer, + whose reference will be passed into GetFlags() as an argument. + @return the length of Flags + */ +EXPORT_C TInt TBluetoothNameRecordWrapper::GetFlagsLength() const + { + LOG_FUNC + TPtrC8 flags; + TInt ret = iEirCodec.GetData(EEirFlags, flags); + if(ret == KErrNone) + { + ret = flags.Length(); + } + else + { + ret = 0; + } + return ret; + } + +TInt TBluetoothNameRecordWrapper::AddUuids16(RExtendedInquiryResponseUUIDContainer& aEIRContainer, TPtrC8& aUuids) const + { + TInt error = KErrNone; + TInt length = aUuids.Length() / KSizeOf16BitUUID; + TUUID uuid; + + for(TInt i = 0; i < length; i++) + { + __ASSERT_DEBUG(((aUuids.Length() - i*KSizeOf16BitUUID)% KSizeOf16BitUUID) == 0, Panic(EEirBadUuid16List)); + TRAP(error, uuid.SetFromLittleEndianL(aUuids.Mid(i*KSizeOf16BitUUID, KSizeOf16BitUUID))); + if(error == KErrNone) + { + error = aEIRContainer.UUIDs().Add(uuid); + } + else + { + break; + } + } + + return error; + } + +TInt TBluetoothNameRecordWrapper::AddUuids128(RExtendedInquiryResponseUUIDContainer& aEIRContainer, TPtrC8& aUuids) const + { + TInt error = KErrNone; + TInt length = aUuids.Length() / KSizeOf128BitUUID; + TUUID uuid; + + for(TInt i = 0; i < length; i++) + { + __ASSERT_DEBUG(((aUuids.Length() - i*KSizeOf128BitUUID)% KSizeOf128BitUUID) == 0, Panic(EEirBadUuid128List)); + TRAP(error, uuid.SetFromLittleEndianL(aUuids.Mid(i*KSizeOf128BitUUID, KSizeOf128BitUUID))); + if(error == KErrNone) + { + error = aEIRContainer.UUIDs().Add(uuid); + } + else + { + break; + } + } + + return error; + }