diff -r f5050f1da672 -r 04becd199f91 javaextensions/bluetooth/omjbluetooth/src.s60/discoveryagent.cpp --- /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