diff -r 000000000000 -r 29b1cd4cb562 bluetoothcommsprofiles/btpan/panagt/panlocalsdphelper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetoothcommsprofiles/btpan/panagt/panlocalsdphelper.cpp Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,281 @@ +// Copyright (c) 2004-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: +// panhelperlocalsdp.cpp +// +// + +#include "panlocalsdphelper.h" +#include "panagtutils.h" +#include "pancommon.h" // For KBnepPsm +#include "panprog.h" // For EOther + +using namespace PanAgent; + +const TSdpServRecordHandle KIllegalSdpRecordHandle = 0; + +CPanHelperLocalSdpRegistrar* CPanHelperLocalSdpRegistrar::NewL() +/** +Return a newly constructed local sdp registrar +*/ + { + CPanHelperLocalSdpRegistrar* self = new(ELeave) CPanHelperLocalSdpRegistrar(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CPanHelperLocalSdpRegistrar::CPanHelperLocalSdpRegistrar() +/** +do nothing +*/ + { } + +void CPanHelperLocalSdpRegistrar::ConstructL() +/** +Initialisation +*/ + { + User::LeaveIfError(iSdpServer.Connect()); + User::LeaveIfError(iSdpDatabase.Open(iSdpServer)); + for(TUint i=0;i(aRole) >= static_cast(EPanRoleU), PanAgentPanic(EPanRoleOutOfBounds)); + __ASSERT_DEBUG((static_cast(aRole) - static_cast(EPanRoleU)) <= KMaxPanRoles, PanAgentPanic(EPanRoleOutOfBounds)); + __ASSERT_DEBUG(((aRole==EPanRoleU)||(aRole==EPanRoleGn)||(aRole==EPanRoleNap)), PanAgentPanic(EAttemptToRegisterIllegalPanRoleInLocalSdpDatabase)); //<@note embeds knowledge of valid roles + + TUUID uuid(static_cast(aRole)); + + // Rebase the role to use role as index into array + TUint panRoleRecordHandleIndex = static_cast(aRole) - static_cast(EPanRoleU); + + // Check if the record is already registered. If so, no action is required. + if(iLocalSdpRecordHandles[panRoleRecordHandleIndex] == KIllegalSdpRecordHandle) + { + // Create the SDP record + iSdpDatabase.CreateServiceRecordL(uuid, iLocalSdpRecordHandles[panRoleRecordHandleIndex]); + + + TSdpServRecordHandle recordHandle = iLocalSdpRecordHandles[panRoleRecordHandleIndex]; + iSdpDatabase.UpdateAttributeL(recordHandle, + KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetProviderName, + KProviderName + ); + // + // Add attributes + // + CSdpAttrValue* attrVal = NULL; + CSdpAttrValueDES* attrValDES = NULL; + + // Service Class ID list is handled above when creating the record + // protocol descriptor list + attrValDES = CSdpAttrValueDES::NewDESL(0); + CleanupStack::PushL(attrValDES); + attrValDES->StartListL() + ->BuildDESL()->StartListL() + ->BuildUUIDL(TUUID(TUint16(KL2CAPUUID))) // UUID for protocol: L2CAP + ->BuildUintL(TSdpIntBuf(KBnepPsm)) // PSM: BNEP + ->EndListL() + ->BuildDESL()->StartListL() + ->BuildUUIDL(TUUID(TUint16(KBnepUUID))) // UUID for protocol: BNEP + ->BuildUintL(TSdpIntBuf(KBnepVersion)) // version: 0x0100 + ->BuildDESL()->StartListL() + ->BuildUintL(TSdpIntBuf(0x0800)) // ethernet protocol: IPv4 + ->BuildUintL(TSdpIntBuf(0x0806)) // ethernet protocol: ARP + ->BuildUintL(TSdpIntBuf(0x86dd)) // ethernet protocol: IPv6 + ->EndListL() + ->EndListL() + ->EndListL(); + iSdpDatabase.UpdateAttributeL(recordHandle, KSdpAttrIdProtocolDescriptorList, *attrValDES); + CleanupStack::PopAndDestroy(attrValDES); + + // language base attribute ID list + attrValDES = CSdpAttrValueDES::NewDESL(0); + CleanupStack::PushL(attrValDES); + attrValDES->StartListL() + ->BuildUintL(TSdpIntBuf(KLanguageEnglish)) + ->BuildUintL(TSdpIntBuf(KSdpAttrIdCharacterEncodingUTF8)) + ->BuildUintL(TSdpIntBuf(KSdpAttrIdBasePrimaryLanguage)) + ->EndListL(); + iSdpDatabase.UpdateAttributeL(recordHandle, KSdpAttrIdLanguageBaseAttributeIDList, *attrValDES); + CleanupStack::PopAndDestroy(attrValDES); + + // bluetooth profile descriptor list + attrValDES = CSdpAttrValueDES::NewDESL(0); + CleanupStack::PushL(attrValDES); + attrValDES->StartListL() + ->BuildDESL()->StartListL() + ->BuildUUIDL(uuid) // role: uuid of PAN role + ->BuildUintL(TSdpIntBuf(KPanRoleVersion)) // version: 0x0100 + ->EndListL() + ->EndListL(); + iSdpDatabase.UpdateAttributeL(recordHandle, KSdpAttrIdBluetoothProfileDescriptorList, *attrValDES); + CleanupStack::PopAndDestroy(attrValDES); + + // bluetooth browse list + attrValDES = CSdpAttrValueDES::NewDESL(0); + CleanupStack::PushL(attrValDES); + attrValDES->StartListL() + ->BuildUUIDL(TUUID(TUint32(KPublicBrowseGroupUUID))) // Public browse group + ->EndListL(); + iSdpDatabase.UpdateAttributeL(recordHandle, KSdpAttrIdBrowseGroupList, *attrValDES); + CleanupStack::PopAndDestroy(attrValDES); + + // service name + switch(aRole) + { + case EPanRoleU: + { + attrVal = CSdpAttrValueString::NewStringL(_L8("Personal Ad-hoc User Service")); + CleanupStack::PushL(attrVal); + iSdpDatabase.UpdateAttributeL(recordHandle, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceName, *attrVal); + CleanupStack::PopAndDestroy(attrVal); + break; + } + case EPanRoleGn: + { + attrVal = CSdpAttrValueString::NewStringL(_L8("Group Ad-hoc Network Service")); + CleanupStack::PushL(attrVal); + iSdpDatabase.UpdateAttributeL(recordHandle, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceName, *attrVal); + CleanupStack::PopAndDestroy(attrVal); + break; + } + case EPanRoleNap: + { + attrVal = CSdpAttrValueString::NewStringL(_L8("Network Access Point Service")); + CleanupStack::PushL(attrVal); + iSdpDatabase.UpdateAttributeL(recordHandle, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceName, *attrVal); + CleanupStack::PopAndDestroy(attrVal); + break; + } + default: + { + PanAgentPanic(EAttemptToRegisterIllegalPanRoleInLocalSdpDatabase); + } + } + + // service description + switch(aRole) + { + case EPanRoleU: + { + attrVal = CSdpAttrValueString::NewStringL(_L8("Personal Ad-hoc User Service")); + CleanupStack::PushL(attrVal); + iSdpDatabase.UpdateAttributeL(recordHandle, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceDescription, *attrVal); + CleanupStack::PopAndDestroy(attrVal); + break; + } + case EPanRoleGn: + { + attrVal = CSdpAttrValueString::NewStringL(_L8("Personal Group Ad-hoc Network Service")); + CleanupStack::PushL(attrVal); + iSdpDatabase.UpdateAttributeL(recordHandle, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceDescription, *attrVal); + CleanupStack::PopAndDestroy(attrVal); + break; + } + case EPanRoleNap: + { + attrVal = CSdpAttrValueString::NewStringL(_L8("Personal Ad-hoc Network Service which provides access to a network")); + CleanupStack::PushL(attrVal); + iSdpDatabase.UpdateAttributeL(recordHandle, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceDescription, *attrVal); + CleanupStack::PopAndDestroy(attrVal); + break; + } + default: + { + PanAgentPanic(EAttemptToRegisterIllegalPanRoleInLocalSdpDatabase); + } + } + + // Add NAP specific fields. + if(aRole == EPanRoleNap) + { + // Set the uplink type + attrVal = CSdpAttrValueInt::NewIntL(TSdpIntBuf(EOther)); // Access type set to 'other' + CleanupStack::PushL(attrVal); + iSdpDatabase.UpdateAttributeL(recordHandle, KSdpAttrIdNetAccessType, *attrVal); + CleanupStack::PopAndDestroy(attrVal); + + // Set the uplink maximum throughput + attrVal = CSdpAttrValueInt::NewIntL(TSdpIntBuf(KPanNapDefaultUplinkThroughput)); + CleanupStack::PushL(attrVal); + iSdpDatabase.UpdateAttributeL(recordHandle, KSdpAttrIdMaxNetAccessRate, *attrVal); + CleanupStack::PopAndDestroy(attrVal); + } + + // security description + attrVal = CSdpAttrValueUint::NewUintL(TSdpIntBuf(EServiceLevelSecurity)); // security type: service level + CleanupStack::PushL(attrVal); + iSdpDatabase.UpdateAttributeL(recordHandle, KSdpAttrIdSecurityDescription, *attrVal); + CleanupStack::PopAndDestroy(attrVal); + } + } + +void CPanHelperLocalSdpRegistrar::UnregisterLocalSdpRecord(TBluetoothPanRole aRole) +/** +Can be called to unregister an SDP record even if it is not registered. +Simplifies logic in PAN agent, so it doesn't need to keep track of which roles it has unregistered +*/ + { + // Make sure any array access is going to fall within the array bounds + __ASSERT_DEBUG(static_cast(aRole) >= static_cast(EPanRoleU), PanAgentPanic(EPanRoleOutOfBounds)); + __ASSERT_DEBUG((static_cast(aRole) - static_cast(EPanRoleU)) <= KMaxPanRoles, PanAgentPanic(EPanRoleOutOfBounds)); + __ASSERT_ALWAYS(((aRole==EPanRoleU)||(aRole==EPanRoleGn)||(aRole==EPanRoleNap)), PanAgentPanic(EAttemptToRegisterIllegalPanRoleInLocalSdpDatabase)); //<@note embeds knowledge of valid roles + + TInt arrayIndex = (static_cast(aRole) - static_cast(EPanRoleU)); + if(iLocalSdpRecordHandles[arrayIndex]!=KIllegalSdpRecordHandle) + { + iSdpDatabase.DeleteRecord(iLocalSdpRecordHandles[arrayIndex]); + iLocalSdpRecordHandles[arrayIndex] = KIllegalSdpRecordHandle; + } + }