diff -r 000000000000 -r 9cfd9a3ee49c datasourcemodules/bluetoothgpspositioningmodule/btgpspsy/src/Utils/btgpsdiscovery.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/datasourcemodules/bluetoothgpspositioningmodule/btgpspsy/src/Utils/btgpsdiscovery.cpp Tue Feb 02 01:50:39 2010 +0200 @@ -0,0 +1,218 @@ +// Copyright (c) 2008-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: +// btgpsdiscovery implementation +// +// + +/** + @file btgpsdiscovery.cpp + @internal technology +*/ + +#include "btgpsdiscovery.h" +#include "btgpssimstubs.h" + + +CBTGPSDiscovery::CBTGPSDiscovery (MBTGPSSdpResultReceiver* aBTEngSdpResultReceiver) + { + iBTSdpResultReceiver = aBTEngSdpResultReceiver; + iChannel = 0; + iValid = EFalse; + } + +CBTGPSDiscovery* CBTGPSDiscovery::NewLC (MBTGPSSdpResultReceiver* aBTEngSdpResultReceiver) + { + CBTGPSDiscovery* self = new ( ELeave ) CBTGPSDiscovery(aBTEngSdpResultReceiver); + CleanupStack::PushL (self); + return self; + } + +CBTGPSDiscovery* CBTGPSDiscovery::NewL(MBTGPSSdpResultReceiver* aBTEngSdpResultReceiver) + { + CBTGPSDiscovery* self = CBTGPSDiscovery::NewLC (aBTEngSdpResultReceiver); + CleanupStack::Pop (self); + return self; + } + +CBTGPSDiscovery::~CBTGPSDiscovery () + { + delete iSdpAgent; +#ifdef LBS_BTGPSPSY_SIM + delete iSdpAgentSim; +#endif + } + +/** + * Starts an SDP query. The remote SDP database is searched for the value + * of the ProtocolDescriptorList attribute in a service record containing + * the specified UUID, the equivalent of an SDP ServiceAttributeSearch + * transaction with ProtocolDescriptorList as attribute. This can e.g. be + * used to search the remote RFCOMM channel. When completed, the results + * are passed back to the client through the callback interface method + * MBTEngSdpResultReceiver::AttributeSearchComplete(). + * @param aAddr Target Bluetooth device address for the SDP query. + * @param aService The UUID to search for. + * @return KErrNone if successful, otherwise the error code indicating the error situation. + */ +TInt CBTGPSDiscovery::RemoteProtocolChannelQueryL(const TBTDevAddr& aAddr, TInt aService) + { + if(iSdpAgent) + { + return KErrInUse; + } + +#ifdef LBS_BTGPSPSY_SIM + // See if the device is simulated, in which case use the simulated SdpAgent. + // otherwise use the regular one. + iSdpAgentSim = CSdpAgentSim::NewL(*this); + if (iSdpAgentSim->GetChannelStart(aAddr, iChannel) != KErrNone) +#endif + { + CSdpAgent* sdpAgent = CSdpAgent::NewL(*this, aAddr); + CleanupStack::PushL(sdpAgent); + + // create the attribute ID list to match against + CSdpSearchPattern* searchPattern = CSdpSearchPattern::NewL(); + CleanupStack::PushL(searchPattern); + + // search for BNEP, as it's the common field in all PAN records + searchPattern->AddL(aService); + + // Set Record Filter copies searchPattern + sdpAgent->SetRecordFilterL(*searchPattern); + CleanupStack::PopAndDestroy(searchPattern); + + sdpAgent->NextRecordRequestL(); + + // Now we have successfully issued the request we know that it will later be + // completed, so we can keep sdpAgent and it will be deleted on request + // completion. + CleanupStack::Pop(sdpAgent); + iSdpAgent = sdpAgent; + } + + return KErrNone; + } + +/** + * This function to return the protocol channel number from the + * result array of a ServiceAttributeSearch. This value can be used to + * obtain e.g. the remote RFCOMM channel after a RemoteProtocolChannelQueryL + * has completed. + * @param aResultArray The array containing the SDP attribute. + * @param aType On return, contains the channel number. + * @return KerrNone if successful, KerrArgument if the SDP attribute is not + * of type ProtocolDescriptorLis + */ +TInt CBTGPSDiscovery::ParseRfcommChannel(TInt& aType) + { + aType = iChannel; + return KErrNone; + } + +/** Called when an service record request (CSdpAgent::NextRecordRequestComplete()) +operation completes. + +@param aError KErrNone if successful; + KErrEof if there are no more SDP records left to be read; or an SDP error. +@param aHandle Service record for which the query was made +@param aTotalRecordsCount Total number of matching records +@see CSdpAgent::NextRecordRequestL() */ +void CBTGPSDiscovery::NextRecordRequestComplete(TInt aError, TSdpServRecordHandle aHandle, TInt /*aTotalRecordsCount*/) + { + TInt err = aError; + + if(err == KErrNone) //more results available + { + iMatchesFound = ETrue; + // Check the attributes of the returned record to see if it's a U, GN, or NAP record + TRAP(err,iSdpAgent->AttributeRequestL(aHandle, KSdpAttrIdProtocolDescriptorList)); + + if(err == KErrNone) + { + return; + } + } + + //Request has completed or error has occured + if(err != KErrEof) + { + // A 'real' error has occured, cancel the query + if(iSdpAgent) + { + iSdpAgent->Cancel(); + } + iBTSdpResultReceiver->ServiceAttributeSearchComplete(err); + } + else + { + iBTSdpResultReceiver->ServiceAttributeSearchComplete(KErrEof); + } + } + +/** Called when an attribute request (CSdpAgent::AttributeRequestL()) wants to +pass up a result. + +@param aHandle Service record for which the query was made +@param aAttrID ID of the attribute obtained +@param aAttrValue Attribute value obtained +@see CSdpAgent::AttributeRequestL() */ +void CBTGPSDiscovery::AttributeRequestResult(TSdpServRecordHandle /*aHandle*/, TSdpAttributeID aAttrID, CSdpAttrValue* aAttrValue) + { + if((aAttrID == KSdpAttrIdProtocolDescriptorList) && (aAttrValue->Type()==ETypeDES)) + { + CSdpAttrValueDES* sdpProfileDesList = static_cast(aAttrValue); + // cycle through the contents of the DES to find the remote role + TRAPD(err, sdpProfileDesList->AcceptVisitorL(*this)); + if(KErrNone == err) + { + // Delete the attribute value now that we've finished with it + delete aAttrValue; + // there shouldn't be another profile descriptor list, so we should now get AttributeRequestComplete() called + } + } + } + +/** Called when an attribute request (CSdpAgent::AttributeRequestL()) wants to +signal the completion of a attribute request. + +@param aHandle Service record for which the query was made +@param aError an error +@see CSdpAgent::AttributeRequestL() */ +void CBTGPSDiscovery::AttributeRequestComplete(TSdpServRecordHandle /*aHandle*/, TInt /*aError*/) + { + // examine the next record returned + TRAP_IGNORE(iSdpAgent->NextRecordRequestL()); + } + +void CBTGPSDiscovery::VisitAttributeValueL(CSdpAttrValue &aValue, TSdpElementType aType) + { + if(iValid) + { + if(aType==ETypeUint) + { + iChannel = aValue.Uint(); + iBTSdpResultReceiver->ServiceAttributeSearchComplete( KErrNone); + } + iValid = EFalse; + } + + if(aType==ETypeUUID) + { + if(aValue.UUID() == KRFCommUUID) + { + iValid = ETrue; + } + } + }