--- /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 <bluetooth/hci/hcierrors.h>
+
+#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<const TInt*>(attrIdStartPtr);
+ const TUint16 attrId16 = static_cast<TUint16>(*attrId);
+ TAttrRange attrRange(static_cast<TSdpAttributeID>(attrId16));
+
+ mAttributeList->AddL(attrRange);
+ }
+ CleanupStack::Pop(mAttributeList);
+
+}
+
+} //end namespace bluetooth
+} //end namespace java