--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javaextensions/bluetooth/omjbluetooth/src.s60/discoveryagent.cpp Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,450 @@
+/*
+* 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 "discoveryagent.h"
+#include "bluetoothdevicediscoverer.h"
+#include "fs_methodcall.h"
+#include "javajniutils.h"
+#include "exceptionbase.h"
+
+using namespace java::util;
+
+namespace java
+{
+namespace bluetooth
+{
+
+DiscoveryAgent::DiscoveryAgent(BluetoothFunctionServer* aServer)
+{
+ JELOG2(EJavaBluetooth);
+ // Initializing discovery agent data
+ mFunctionServer = aServer;
+ mSocketServerStatus = SOCKETSERVER_DISCONNECTED;
+
+ // Initializing device discovery data
+ mDeviceDiscoverer = NULL;
+}
+
+DiscoveryAgent::~DiscoveryAgent()
+{
+ JELOG2(EJavaBluetooth);
+ cleanupDeviceDiscoverer();
+}
+
+/**
+ * Starts the device inquiry. After starts the inquiry, call made to the java
+ * indicates that inquiry started.
+ *
+ * @param aJni
+ * @param aPeer
+ * @param aAccessCode Inquiry code
+ * @param aMonitor Monitor which waits for this operation to complete
+ */
+int DiscoveryAgent::startDeviceDiscovery(JNIEnv* aJni, jobject& aPeer,
+ int aAccessCode)
+{
+ JELOG2(EJavaBluetooth);
+
+ jclass peerClass = (*aJni).GetObjectClass(aPeer);
+
+ //Get Method ID of Device Discovered Callback
+ mDeviceDiscoveredMethod = aJni->GetMethodID(peerClass,
+ "deviceDiscoveredCallBack",
+ "(Ljava/lang/String;Ljava/lang/String;I)V");
+
+ //We call Device Inquiry Started Callback in BluetoothStackS60 itself
+ mDeviceDiscoveryStartedMethod = aJni->GetMethodID(peerClass,
+ "deviceInquiryStartedCallback", "()V");
+
+ //Check if all the JNI inits have succeeded
+ if (NULL == mDeviceDiscoveredMethod || NULL
+ == mDeviceDiscoveryStartedMethod)
+ {
+ //Error in initialization
+ ELOG(EJavaBluetooth,
+ "- DiscoveryAgent::startDeviceDiscovery Error in JNIInit");
+ return -1;
+ }
+
+ TRAPD(err, CallMethodL(this,
+ &java::bluetooth::DiscoveryAgent::discoverDevicesFsL, aAccessCode,
+ mFunctionServer));
+
+ if (KErrNone != err)
+ {
+ cleanupDeviceDiscoverer();
+
+ ELOG1(EJavaBluetooth,
+ "- DiscoveryAgent::startDeviceDiscovery Error %d", err);
+ return err;
+ }
+
+ LOG(EJavaBluetooth, EInfo,
+ " DiscoveryAgent::startDeviceDiscovery Started Callback");
+
+ startedDeviceDiscovery(aJni, aPeer);
+
+ return err;
+}
+
+void DiscoveryAgent::discoverDevicesFsL(int aAccessCode)
+{
+ mDeviceDiscoverer = BluetoothDeviceDiscoverer::NewL(mFunctionServer);
+ CleanupStack::PushL(mDeviceDiscoverer);
+ mDeviceDiscoverer->DiscoverDevicesL(aAccessCode);
+ CleanupStack::Pop(mDeviceDiscoverer);
+}
+
+/**
+ * Cancels the device inquiry
+ */
+bool DiscoveryAgent::cancelDeviceDiscovery()
+{
+ JELOG2(EJavaBluetooth);
+
+ if (mDeviceDiscoverer)
+ {
+ mDeviceDiscoverer->cancel();
+ }
+ return true;
+}
+
+/**
+ * Makes callback to Java indicates that the inquiry started.
+ */
+void DiscoveryAgent::startedDeviceDiscovery(JNIEnv* aJni, jobject& aPeer)
+{
+ JELOG2(EJavaBluetooth);
+ //Call method in Java here to notify that device discovery has been started
+ //This too happens in Function Server Context.
+
+ (*aJni).CallVoidMethod(aPeer, mDeviceDiscoveryStartedMethod);
+
+}
+
+/**
+ * Searching for the next device.
+ * Returns immediately, if already any device discovered;
+ * otherwise waits for the new device.
+ */
+int DiscoveryAgent::getNextDevice(DiscoveredDevice &aDiscoveredDevice)
+{
+ JELOG2(EJavaBluetooth);
+ int status = mDeviceDiscoverer->getNextDevice(aDiscoveredDevice);
+ if (STATUS_DEVICE_FOUND != status)
+ {
+ cleanupDeviceDiscoverer();
+ }
+ return status;
+}
+
+/**
+ * Makes callback to the Java only when new device found.
+ * Returns the inquiry status.
+ */
+int DiscoveryAgent::doDeviceDiscoveryCallback(JNIEnv* aJni, jobject& aPeer,
+ DiscoveredDevice &aDiscoveredDevice)
+{
+ JELOG2(EJavaBluetooth);
+
+ jstring devAddr = NULL;
+ jstring devName = NULL;
+ int deviceClass = 0;
+
+ if (STATUS_DEVICE_FOUND == aDiscoveredDevice.mInquiryStatus)
+ {
+ LOG(EJavaBluetooth, EInfo,
+ " DiscoveryAgent::doDeviceDiscoveryCallback: Device discovered callback");
+
+ if (NULL != aDiscoveredDevice.mDeviceAddr)
+ {
+ try
+ {
+ devAddr = java::util::JniUtils::wstringToJstring(aJni,
+ *(aDiscoveredDevice.mDeviceAddr));
+ }
+ catch (ExceptionBase ex)
+ {
+ // Nothing to handle
+ }
+ }
+ else
+ {
+ ELOG(EJavaBluetooth,
+ " DiscoveryAgent Really Serious Error: Address is NULL !!");
+ }
+
+ if (NULL != aDiscoveredDevice.mDeviceName)
+ {
+ try
+ {
+ devName = java::util::JniUtils::wstringToJstring(aJni,
+ *(aDiscoveredDevice.mDeviceName));
+ }
+ catch (ExceptionBase ex)
+ {
+ // Nothing to handle
+ }
+ }
+ else
+ {
+ ELOG(EJavaBluetooth,
+ " DiscoveryAgent::doDeviceDiscoveryCallback: Device Name is NULL");
+ }
+
+ deviceClass = aDiscoveredDevice.mDeviceClass;
+
+ (*aJni).CallVoidMethod(aPeer, mDeviceDiscoveredMethod, devAddr,
+ devName, deviceClass);
+ }
+
+ LOG1(EJavaBluetooth, EInfo,
+ "- DiscoveryAgent::doDeviceDiscoveryCallback: %d",
+ aDiscoveredDevice.mInquiryStatus);
+ return aDiscoveredDevice.mInquiryStatus;
+}
+
+/**
+ * Deletes the BluetoothDeviceDiscoverer
+ */
+void DiscoveryAgent::cleanupDeviceDiscoverer()
+{
+ JELOG2(EJavaBluetooth);
+ delete mDeviceDiscoverer;
+ mDeviceDiscoverer = NULL;
+}
+
+/**
+ * Starts lookup for the friendly name of the device
+ * On success, returns the friendly name of the device
+ * Otherwise NULL
+ *
+ * Note: Must free resultant friendly name, whenever not required.
+ */
+std::wstring* DiscoveryAgent::lookupFriendlyNameL(long long aDevAddr)
+{
+ JELOG2(EJavaBluetooth);
+ LOG1(EJavaBluetooth, EInfo,
+ "+ DiscoveryAgent::lookupFriendlyName DeviceAddress:%x", aDevAddr);
+
+ TInt64 devAddr = (TInt64) aDevAddr;
+ std::wstring* result = NULL;
+
+ CallMethodL(result, this, &java::bluetooth::DiscoveryAgent::nameLookupL,
+ devAddr, mFunctionServer);
+
+ return result;
+}
+
+/**
+ * Creates the BluetoothNameLookup object
+ */
+std::wstring* DiscoveryAgent::nameLookupL(TInt64 aDevAddr)
+{
+ JELOG2(EJavaBluetooth);
+ std::wstring* result = NULL;
+ BluetoothNameLookup * nameLookup = BluetoothNameLookup::NewL();
+ CleanupStack::PushL(nameLookup);
+ result = nameLookup->doDeviceNameLookupL(aDevAddr);
+ CleanupStack::Pop(nameLookup);
+ delete nameLookup;
+ return result;
+}
+
+/*
+ * ------- Service Search Methods --------
+ */
+int DiscoveryAgent::StartSearchServices(JNIEnv* aJni, jobject& aPeer,
+ TInt64 aRemoteAddress, TPtrC8 aUuidsDes, TPtrC16 aAttrIdsDes,
+ java::util::Monitor* aMonitor)
+{
+ JELOG2(EJavaBluetooth);
+
+ mServiceSearchMonitor = aMonitor;
+ mServiceSearchStatus = -1;
+
+ jclass peerClass = (*aJni).GetObjectClass(aPeer);
+
+ //Get Method ID of Service Search Started Callback
+ mServiceSearchStartedMethod = aJni->GetMethodID(peerClass,
+ "serviceSearchStartedCallback", "()V");
+
+ //Check if all the JNI inits have succeeded
+ if (NULL == mServiceSearchStartedMethod)
+ {
+ //Error in initialization
+ ELOG(EJavaBluetooth,
+ "- DiscoveryAgent::StartSearchServices: Error in JNIInit ");
+ return -1;
+ }
+
+ LOG(EJavaBluetooth, EInfo,
+ " DiscoveryAgent::StartSearchServices: Starting service search ");
+
+ TRAPD(err, CallMethodL(this,
+ &java::bluetooth::DiscoveryAgent::searchServiceFsL, aRemoteAddress,
+ aUuidsDes, aAttrIdsDes, mFunctionServer));
+
+ if (KErrNone == err)
+ {
+ StartedServiceSearch(aJni, aPeer);
+ }
+
+ return err;
+}
+
+void DiscoveryAgent::searchServiceFsL(TInt64 aRemoteAddress, TPtrC8 aUuidsDes,
+ TPtrC16 aAttrIdsDes)
+{
+ mServiceSearcher = BluetoothServiceSearcher::New(this, mFunctionServer);
+
+ TRAPD(err, mServiceSearcher->SearchServicesL(aRemoteAddress, aUuidsDes,
+ aAttrIdsDes));
+ if (KErrNone != err)
+ {
+ ELOG(EJavaBluetooth,
+ " DiscoveryAgent::SearchServiceFsL: Error occured!! ");
+ CleanupServiceSearcher();
+ User::LeaveIfError(err);
+ }
+}
+
+void DiscoveryAgent::StartedServiceSearch(JNIEnv* aJni, jobject& aPeer)
+{
+ JELOG2(EJavaBluetooth);
+ mIsServiceSearchOn = true;
+
+ (*aJni).CallVoidMethod(aPeer, mServiceSearchStartedMethod);
+
+}
+
+void DiscoveryAgent::ServiceSearchCompleted(int aStatus)
+{
+ JELOG2(EJavaBluetooth);
+ mIsServiceSearchOn = false;
+ mServiceSearchStatus = aStatus;
+ mServiceSearchMonitor->notify();
+ CleanupServiceSearcher();
+}
+
+bool DiscoveryAgent::CancelServiceSearch()
+{
+ JELOG2(EJavaBluetooth);
+ if (NULL != mServiceSearcher)
+ {
+ CallMethod(
+ this,
+ &java::bluetooth::DiscoveryAgent::cancelAndCleanupServiceSearchFs,
+ mFunctionServer);
+ }
+ CleanupAllServiceSearcherInfo();
+ mIsServiceSearchOn = false;
+ return true;
+}
+
+void DiscoveryAgent::cancelAndCleanupServiceSearchFs()
+{
+ mServiceSearcher->cancelServiceSearch();
+ CleanupServiceSearcher();
+}
+
+int DiscoveryAgent::getStatusOfCompletion()
+{
+ JELOG2(EJavaBluetooth);
+ LOG1(EJavaBluetooth, EInfo, "+ DiscoveryAgent::getStatusOfCompletion: %d",
+ mServiceSearchStatus);
+ return mServiceSearchStatus;
+}
+
+int DiscoveryAgent::PopulateServiceRecordAttrValue(JNIEnv* aJni,
+ jobject& aPeer, TInt64 aRemoteAddress, long aHandle,
+ TPtrC16 aAttrIdsDes, jobject aServiceRecordImpl,
+ java::util::Monitor* aMonitor)
+{
+ JELOG2(EJavaBluetooth);
+
+ mServiceSearchMonitor = aMonitor;
+
+ jclass peerClass = (*aJni).GetObjectClass(aPeer);
+
+ LOG(EJavaBluetooth, EInfo,
+ " DiscoveryAgent::PopulateServiceRecord: Starting populating service records ");
+ TRAPD(err, CallMethodL(this,
+ &java::bluetooth::DiscoveryAgent::populateServiceRecordAttrValueFs,
+ aRemoteAddress, aHandle, aAttrIdsDes, aServiceRecordImpl,
+ mFunctionServer));
+
+ return err;
+}
+
+void DiscoveryAgent::populateServiceRecordAttrValueFs(TInt64 aRemoteAddress,
+ long aHandle, TPtrC16 aAttrIdsDes, jobject aServiceRecordImpl)
+{
+ mServiceSearcher = BluetoothServiceSearcher::New(this, mFunctionServer);
+ mServiceSearcher->PopulateServiceRecordsL(aRemoteAddress, aHandle,
+ aAttrIdsDes, aServiceRecordImpl);
+}
+
+void DiscoveryAgent::PopulateRecordCompleted(int aStatus)
+{
+ JELOG2(EJavaBluetooth);
+ mPopulateRecordStatus = aStatus;
+ mServiceSearchMonitor->notify();
+ CleanupServiceSearcher();
+}
+
+int DiscoveryAgent::GetPopulateServiceRecordStatus()
+{
+ JELOG2(EJavaBluetooth);
+ return mPopulateRecordStatus;
+}
+
+bool DiscoveryAgent::CancelPopulateServiceRecordAttrValue()
+{
+ JELOG2(EJavaBluetooth);
+ mIsServiceSearchOn = false;
+ TRAP_IGNORE(CallMethodL(mServiceSearcher,
+ &java::bluetooth::BluetoothServiceSearcher::cancelServiceSearch,
+ mFunctionServer));
+
+ return true;
+}
+
+void DiscoveryAgent::CleanupServiceSearcher()
+{
+ JELOG2(EJavaBluetooth);
+ //Delete all contained objects
+ if (mServiceSearcher)
+ {
+ delete mServiceSearcher;
+ mServiceSearcher = NULL;
+ }
+}
+
+void DiscoveryAgent::CleanupAllServiceSearcherInfo()
+{
+ JELOG2(EJavaBluetooth);
+ // Clear all realted data
+ mServiceSearchStartedMethod = NULL;
+ mIsServiceSearchOn = false;
+ mPopulateRecordStatus = KErrNone;
+ mServiceSearchMonitor = NULL;
+}
+
+} //end namespace bluetooth
+} //end namespace java