diff -r f5050f1da672 -r 04becd199f91 javaextensions/bluetooth/omjbluetooth/src.s60/bluetoothservicesearcher.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaextensions/bluetooth/omjbluetooth/src.s60/bluetoothservicesearcher.cpp Tue Apr 27 16:30:29 2010 +0300 @@ -0,0 +1,391 @@ +/* +* Copyright (c) 2008 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 "bluetoothconsts.h" +#include "bluetoothservicesearcher.h" +#include "discoveryagent.h" + +namespace java +{ +namespace bluetooth +{ + +#define GET_VALID_HCI_ERR_CODE(err_no) (((err_no) < KHCIErrorBase) ? \ + (KHCIErrorBase - (err_no)) : \ + (err_no)) + +BluetoothServiceSearcher* BluetoothServiceSearcher::New( + DiscoveryAgent *aDiscoveryAgent, BluetoothFunctionServer* aServer) +{ + JELOG2(EJavaBluetooth); + BluetoothServiceSearcher* searcher = new BluetoothServiceSearcher(); + searcher->Construct(aDiscoveryAgent, aServer); + return searcher; +} + +BluetoothServiceSearcher::BluetoothServiceSearcher() +{ +} + +void BluetoothServiceSearcher::Construct(DiscoveryAgent *aDiscoveryAgent, + BluetoothFunctionServer* aServer) +{ + JELOG2(EJavaBluetooth); + mDiscoveryAgent = aDiscoveryAgent; + mServer = aServer; + mSDPAgent = NULL; + mSpat = NULL; + mAttributeList = NULL; + mSrPopulator = NULL; + mFoundServiceRecord = false; + mIsPopulateRecordMode = false; + + mJni = mServer->getValidJniEnv(); + mPeer = mServer->getPeer(); + + jclass peerClass = mJni->GetObjectClass(mPeer); + mCreateServiceRecordMethod + = mJni->GetMethodID(peerClass, "createServiceRecord", + "(J)Lcom/intel/bluetooth/ServiceRecordImpl;"); + + mServiceRecordImplClass = mJni->FindClass( + "com/intel/bluetooth/ServiceRecordImpl"); + +} + +BluetoothServiceSearcher::~BluetoothServiceSearcher() +{ + JELOG2(EJavaBluetooth); + Cleanup(); +} + +void BluetoothServiceSearcher::SearchServicesL(TInt64 aRemoteAddress, + TPtrC8 aUuidsDes, TPtrC16 aAttrIdsDes) +{ + JELOG2(EJavaBluetooth); + LOG1(EJavaBluetooth, EInfo, + "+ BluetoothServiceSearcher:: SearchServices:%X", + (long) aRemoteAddress); + + mIsPopulateRecordMode = false; + + TBTDevAddr devAddr(aRemoteAddress); + + FillSearchPatternL(aUuidsDes); + + FillAttributeListL(aAttrIdsDes); + + LOG( + EJavaBluetooth, + EInfo, + " BluetoothServiceSearcher::SearchServicesOnDeviceL: Clearing SDPAgent if any..."); + // Init new service discovery agent + if (mSDPAgent) + { + delete mSDPAgent; + mSDPAgent = NULL; + } + mSDPAgent = CSdpAgent::NewL(*this, devAddr); + + mSDPAgent->SetRecordFilterL(*mSpat); + + mSDPAgent->NextRecordRequestL(); + +} + +void BluetoothServiceSearcher::cancelServiceSearch() +{ + JELOG2(EJavaBluetooth); + DiscoveryAgent* tempDiscoveryAgent = mDiscoveryAgent; + Cleanup(); + if (NULL == tempDiscoveryAgent) + return; + if (!mIsPopulateRecordMode) + { + tempDiscoveryAgent->ServiceSearchCompleted(SERVICE_SEARCH_TERMINATED); + } + else + { + tempDiscoveryAgent->PopulateRecordCompleted(SERVICE_SEARCH_TERMINATED); + } +} + +void BluetoothServiceSearcher::Cleanup() +{ + JELOG2(EJavaBluetooth); + if (mSDPAgent) + { + delete mSDPAgent; + mSDPAgent = NULL; + } + if (mSpat) + { + mSpat->Reset(); + delete mSpat; + mSpat = NULL; + } + if (mAttributeList) + { + delete mAttributeList; + mAttributeList = NULL; + } + if (mSrPopulator) + { + delete mSrPopulator; + mSrPopulator = NULL; + } + + mDiscoveryAgent = NULL; +} + +void BluetoothServiceSearcher::NextRecordRequestComplete(TInt aError, + TSdpServRecordHandle aHandle, TInt /*aTotalRecordsCount*/) +{ + JELOG2(EJavaBluetooth); + LOG1( + EJavaBluetooth, + EInfo, + " BluetoothServiceSearcher::NextRecordRequestComplete aError=%d", + aError); + + if (KErrEof == aError && !mFoundServiceRecord) + { + LOG( + EJavaBluetooth, + EInfo, + " BluetoothServiceSearcher::NextRecordRequestComplete SERVICE_SEARCH_NO_RECORDS"); + mDiscoveryAgent->ServiceSearchCompleted(SERVICE_SEARCH_NO_RECORDS); + } + else if (KErrNone == aError) + { + TInt64 servRecHandle = MAKE_TINT64(0, aHandle); + mServiceRecordImpl = (*mJni).CallObjectMethod(mPeer, + mCreateServiceRecordMethod, servRecHandle); + if (NULL == mServiceRecordImpl) + { + LOG(EJavaBluetooth, EInfo, + " BluetoothServiceSearcher::NextRecordRequestComplete SERVICE_SEARCH_ERROR"); + mDiscoveryAgent->ServiceSearchCompleted(SERVICE_SEARCH_ERROR); + } + else + { + LOG(EJavaBluetooth, EInfo, + " BluetoothServiceSearcher::NextRecordRequestComplete Populating record"); + delete mSrPopulator; + mSrPopulator = BTServiceRecordPopulator::New(mJni, + mServiceRecordImpl); + TRAPD(attrRequestErr, mSDPAgent->AttributeRequestL(mSrPopulator, + aHandle, *mAttributeList)); + if (KErrNone != attrRequestErr) + { + delete mSrPopulator; + mSrPopulator = NULL; + mDiscoveryAgent->ServiceSearchCompleted(SERVICE_SEARCH_ERROR); + } + } + } + else if (EPageTimedOut == GET_VALID_HCI_ERR_CODE(aError)) + { + LOG( + EJavaBluetooth, + EInfo, + " BluetoothServiceSearcher::NextRecordRequestComplete SERVICE_SEARCH_DEVICE_NOT_REACHABLE"); + mDiscoveryAgent->ServiceSearchCompleted( + SERVICE_SEARCH_DEVICE_NOT_REACHABLE); + } + else + { + LOG1( + EJavaBluetooth, + EInfo, + " BluetoothServiceSearcher::NextRecordRequestComplete SERVICE_SEARCH_COMPLETED %d", + aError); + mDiscoveryAgent->ServiceSearchCompleted(SERVICE_SEARCH_COMPLETED); + } +} + +void BluetoothServiceSearcher::PopulateServiceRecordsL(TInt64 aRemoteAddress, + long aHandle, TPtrC16 aAttrIdsDes, jobject aServiceRecordImpl) +{ + JELOG2(EJavaBluetooth); + + mIsPopulateRecordMode = true; + + TBTDevAddr devAddr(aRemoteAddress); + + FillAttributeListL(aAttrIdsDes); + + LOG( + EJavaBluetooth, + EInfo, + " BluetoothServiceSearcher::PopulateServiceRecords: Clearing SDPAgent if any..."); + + if (mSDPAgent) + { + mSDPAgent->Cancel(); + delete mSDPAgent; + mSDPAgent = NULL; + } + mSDPAgent = CSdpAgent::NewL(*this, devAddr); + + mServiceRecordImpl = aServiceRecordImpl; + + delete mSrPopulator; + mSrPopulator = BTServiceRecordPopulator::New(mJni, mServiceRecordImpl); + + mSDPAgent->AttributeRequestL(mSrPopulator, aHandle, *mAttributeList); +} + +void BluetoothServiceSearcher::AttributeRequestResult( + TSdpServRecordHandle /*aHandle*/, TSdpAttributeID /*aAttrID*/, + CSdpAttrValue* /*aAttrValue*/) +{ + // No implementation required... +} + +void BluetoothServiceSearcher::AttributeRequestComplete( + TSdpServRecordHandle /*aHandle*/, TInt aError) +{ + JELOG2(EJavaBluetooth); + LOG1(EJavaBluetooth, EInfo, + " BluetoothServiceSearcher::AttributeRequestComplete aError=%d", + aError); + + int status = 0; + bool attributeFound = mSrPopulator->isAttributesFound(); + + delete mSrPopulator; + mSrPopulator = NULL; + + if (KErrNone == aError && !mIsPopulateRecordMode) + { + mFoundServiceRecord = true; + LOG( + EJavaBluetooth, + EInfo, + " BluetoothServiceSearcher::AttributeRequestComplete Callback serviceDiscoveredCallback"); + jclass peerClass = mJni->GetObjectClass(mPeer); + jmethodID serviceDiscoveredMethod = mJni->GetMethodID(peerClass, + "serviceDiscoveredCallback", + "(Lcom/intel/bluetooth/ServiceRecordImpl;)V"); + (*mJni).CallVoidMethod(mPeer, serviceDiscoveredMethod, + mServiceRecordImpl); + + LOG( + EJavaBluetooth, + EInfo, + " BluetoothServiceSearcher::AttributeRequestComplete. Trying for the next record if any"); + + // In case of any leave, then this will terminates the search for the next record. + TRAP_IGNORE(mSDPAgent->NextRecordRequestL()); + } + else + { + if (KErrNone == aError) + { + mFoundServiceRecord = true; + status = SERVICE_SEARCH_COMPLETED; + } + else if (EPageTimedOut == GET_VALID_HCI_ERR_CODE(aError)) + { + LOG( + EJavaBluetooth, + EInfo, + " BluetoothServiceSearcher::AttributeRequestComplete SERVICE_SEARCH_DEVICE_NOT_REACHABLE"); + status = SERVICE_SEARCH_DEVICE_NOT_REACHABLE; + } + else + { + LOG(EJavaBluetooth, EInfo, + " BluetoothServiceSearcher::AttributeRequestComplete SERVICE_SEARCH_ERROR"); + status = SERVICE_SEARCH_ERROR; + } + + if (!mIsPopulateRecordMode) + { + mDiscoveryAgent->ServiceSearchCompleted(status); + } + else + { + if (false == attributeFound) + status = SERVICE_SEARCH_NO_RECORDS; + mDiscoveryAgent->PopulateRecordCompleted(status); + } + } +} + +void BluetoothServiceSearcher::BluetoothServiceSearcher::FillSearchPatternL( + TDesC8& uuidsBytes) +{ + JELOG2(EJavaBluetooth); + + const TInt numBytes = uuidsBytes.Length(); + const TInt numberOfUUIDs = numBytes / KSdpUUIDMaxLength; + + TInt uuidsConverted = 0; + TInt startByte = 0; + + if (mSpat) + { + mSpat->Reset(); + delete mSpat; + mSpat = NULL; + } + mSpat = CSdpSearchPattern::NewL(); + CleanupStack::PushL(mSpat); + + while (uuidsConverted < numberOfUUIDs) + { + TUUID uuid; + uuid.SetL(uuidsBytes.Mid(startByte, KSdpUUIDMaxLength)); + + mSpat->AddL(uuid); + startByte += KSdpUUIDMaxLength; + uuidsConverted++; + } + CleanupStack::Pop(mSpat); +} + +void BluetoothServiceSearcher::BluetoothServiceSearcher::FillAttributeListL( + TDesC16& attrIds) +{ + JELOG2(EJavaBluetooth); + delete mAttributeList; + mAttributeList = NULL; + mAttributeList = CSdpAttrIdMatchList::NewL(); + CleanupStack::PushL(mAttributeList); + + TInt numElements = attrIds.Length(); + + for (TInt attrIndex = 0; attrIndex < numElements; attrIndex += 2) + { + const TUint16* attrIdStartPtr = (attrIds.Mid(attrIndex, 2)).Ptr(); + const TInt* attrId = reinterpret_cast(attrIdStartPtr); + const TUint16 attrId16 = static_cast(*attrId); + TAttrRange attrRange(static_cast(attrId16)); + + mAttributeList->AddL(attrRange); + } + CleanupStack::Pop(mAttributeList); + +} + +} //end namespace bluetooth +} //end namespace java