diff -r 22de2e391156 -r 20ac952a623c remotecontrol/avrcp/remconbeareravrcp/src/avrcpsdputils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/remotecontrol/avrcp/remconbeareravrcp/src/avrcpsdputils.cpp Wed Oct 13 16:20:29 2010 +0300 @@ -0,0 +1,181 @@ +// Copyright (c) 2008-2010 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: +// + +#include + +#include "avrcpsdputils.h" + +static void AddCommonServiceRecordAttributesL(RSdpDatabase& aSdpDatabase, TSdpServRecordHandle aRecHandle) + { + // Provider Name + aSdpDatabase.UpdateAttributeL(aRecHandle, + KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetProviderName, + AvrcpSdp::KAvrcpProviderName + ); + + // Service Description + aSdpDatabase.UpdateAttributeL(aRecHandle, + KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceDescription, + AvrcpSdp::KAvrcpServiceDescription + ); + + // Add to public browse group + CSdpAttrValueDES *attrValDES = CSdpAttrValueDES::NewDESL(0); + CleanupStack::PushL(attrValDES); + attrValDES->StartListL() + ->BuildUUIDL(TUUID(TUint16(KPublicBrowseGroupUUID))) + ->EndListL(); + aSdpDatabase.UpdateAttributeL(aRecHandle, KSdpAttrIdBrowseGroupList, *attrValDES); + CleanupStack::PopAndDestroy(attrValDES); + } + +static CSdpAttrValueDES* GenerateControllerServiceClassListLC(TUint16 aProfileVersion) + { + // New service record with service class attribute containing + // 0x110e (for A/V Remote Control) and potentially also 0x110f + CSdpAttrValueDES* serviceClassUuids = CSdpAttrValueDES::NewDESL(NULL); + CleanupStack::PushL(serviceClassUuids); + + // Unfortunately in earlier releases of the specification the controller service class UUID + // was the same as the the profile UUID - meaning that searching for records with this UUID + // would return both controller and target records (since they both belong to the same profile). + // This was corrected by adding a specific service class UUID for the controller role - both + // the specific UUID and the old "profile" UUID are provided in the list of service classes (for + // backwards compatibility). + // + // This new SDP record structure was introduced in AVRCP 1.4 and so if we conform to AVRCP 1.4 we + // can use the new SDP record structure - if we are presenting ourselves as an earlier version + // we must restrain ourselves and use the previously specified structure. + if(aProfileVersion == AvrcpSdp::KAvrcpProfileVersion13) + { + serviceClassUuids->StartListL() + ->BuildUUIDL(TUUID(TUint16(KAVRemoteControlUUID))) + ->EndListL(); + } + else + { + serviceClassUuids->StartListL() + ->BuildUUIDL(TUUID(TUint16(KAVRemoteControlUUID))) + ->BuildUUIDL(TUUID(TUint16(KAVRemoteControlControllerUUID))) + ->EndListL(); + } + + return serviceClassUuids; + } + +void AvrcpSdpUtils::CreateTargetServiceRecordL(RSdpDatabase& aSdpDatabase, TSdpServRecordHandle& aRecHandle) + { + // New service record with service class attribute containing + // 0x110c (for A/V Remote Control Target) + aSdpDatabase.CreateServiceRecordL(KAVRemoteControlTargetUUID, aRecHandle); + + aSdpDatabase.UpdateAttributeL(aRecHandle, + KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceName, + AvrcpSdp::KAvrcpTargetServiceName + ); + + AddCommonServiceRecordAttributesL(aSdpDatabase, aRecHandle); + } + +void AvrcpSdpUtils::CreateControllerServiceRecordL(RSdpDatabase& aSdpDatabase, TSdpServRecordHandle& aRecHandle, TUint16 aProfileVersion) + { + // New service record with service class attribute containing + // 0x110e (for A/V Remote Control) + CSdpAttrValueDES* serviceClassUuids = GenerateControllerServiceClassListLC(aProfileVersion); + + aSdpDatabase.CreateServiceRecordL(*serviceClassUuids, aRecHandle); + CleanupStack::PopAndDestroy(serviceClassUuids); + + aSdpDatabase.UpdateAttributeL(aRecHandle, + KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceName, + AvrcpSdp::KAvrcpControllerServiceName + ); + + AddCommonServiceRecordAttributesL(aSdpDatabase, aRecHandle); + } + +void AvrcpSdpUtils::UpdateControllerServiceClassListL(RSdpDatabase& aSdpDatabase, TSdpServRecordHandle& aRecHandle, TUint16 aProfileVersion) + { + CSdpAttrValueDES* serviceClassUuids = GenerateControllerServiceClassListLC(aProfileVersion); + + aSdpDatabase.UpdateAttributeL(aRecHandle, KSdpAttrIdServiceClassIDList, *serviceClassUuids); + CleanupStack::PopAndDestroy(serviceClassUuids); + } + +void AvrcpSdpUtils::UpdateProtocolDescriptorListL(RSdpDatabase& aSdpDatabase, TSdpServRecordHandle& aRecHandle, TUint16 aProtocolVersion) + { + CSdpAttrValueDES *attrValDES = CSdpAttrValueDES::NewDESL(0); + CleanupStack::PushL(attrValDES); + attrValDES->StartListL() + ->BuildDESL()->StartListL() + ->BuildUUIDL(TUUID(TUint16(KL2CAP))) // L2CAP + ->BuildUintL(TSdpIntBuf(KAVCTP)) // PSM = AVCTP + ->EndListL() + ->BuildDESL()->StartListL() + ->BuildUUIDL(TUUID(TUint16(KAVCTP))) // AVCTP + ->BuildUintL(TSdpIntBuf(aProtocolVersion)) + ->EndListL() + ->EndListL(); + aSdpDatabase.UpdateAttributeL(aRecHandle, KSdpAttrIdProtocolDescriptorList, *attrValDES); + CleanupStack::PopAndDestroy(attrValDES); + } + +void AvrcpSdpUtils::UpdateAdditionalProtocolDescriptorListL(RSdpDatabase& aSdpDatabase, TSdpServRecordHandle& aRecHandle) + { + CSdpAttrValueDES *attrValDES = CSdpAttrValueDES::NewDESL(0); + CleanupStack::PushL(attrValDES); + attrValDES->StartListL() + ->BuildDESL()->StartListL() + ->BuildUUIDL(TUUID(TUint16(KL2CAP))) // L2CAP + ->BuildUintL(TSdpIntBuf(0x1b)) // PSM = AVCTP_browse + ->EndListL() + ->BuildDESL()->StartListL() + ->BuildUUIDL(TUUID(TUint16(KAVCTP))) // AVCTP + ->BuildUintL(TSdpIntBuf(AvrcpSdp::KAvctpProtocolVersion13))// 0x0103 + ->EndListL() + ->EndListL(); + aSdpDatabase.UpdateAttributeL(aRecHandle, KSdpAttrIdAdditionalProtocolDescriptorList, *attrValDES); + CleanupStack::PopAndDestroy(attrValDES); + } + +void AvrcpSdpUtils::UpdateProfileDescriptorListL(RSdpDatabase& aSdpDatabase, TSdpServRecordHandle& aRecHandle, TUint16 aProfileVersion) + { + CSdpAttrValueDES *attrValDES = CSdpAttrValueDES::NewDESL(0); + CleanupStack::PushL(attrValDES); + attrValDES->StartListL() + ->BuildDESL()->StartListL() + //In the profile descriptor list the Control UUID is used + //for BOTH controller and target + ->BuildUUIDL(KAVRemoteControlUUID) + ->BuildUintL(TSdpIntBuf(aProfileVersion)) + ->EndListL() + ->EndListL(); + aSdpDatabase.UpdateAttributeL(aRecHandle, KSdpAttrIdBluetoothProfileDescriptorList, *attrValDES); + CleanupStack::PopAndDestroy(attrValDES); + } + +void AvrcpSdpUtils::UpdateSupportedFeaturesL(RSdpDatabase& aSdpDatabase, TSdpServRecordHandle& aRecHandle, AvrcpSdp::TRecordType aType, TUint16 aFeatures) + { + // Supported Features + // For both target and controller roles if we support that role then + // indicate support for all categories that are available within that + // role. + CSdpAttrValue* attrVal = NULL; + TSdpIntBuf featureBuf = (aType==AvrcpSdp::ERemoteControl) ? AvrcpSdp::KAvrcpBaseCtFeatures | aFeatures : AvrcpSdp::KAvrcpBaseTgFeatures | aFeatures; + attrVal = CSdpAttrValueUint::NewUintL(featureBuf); + CleanupStack::PushL(attrVal); + aSdpDatabase.UpdateAttributeL(aRecHandle, KSdpAttrIdSupportedFeatures, *attrVal); + CleanupStack::PopAndDestroy(attrVal); + }