--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javaextensions/bluetooth/omjbluetooth/src.s60/bluetoothdevicediscoverer.cpp Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,333 @@
+/*
+* 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 <string>
+#include <e32base.h>
+
+#include "logger.h"
+#include "fs_methodcall.h"
+#include "bluetoothconsts.h"
+#include "bluetoothdevicediscoverer.h"
+
+// Constants used to create device class
+#define SERVICE_CLASS_POS 13
+#define MAJOR_CLASS_POS 8
+#define MINOR_CLASS_POS 2
+
+#define SOCKETSERVER_CONNECTED 1
+
+namespace java
+{
+namespace bluetooth
+{
+
+_LIT(KBTLinkManagerTxt,"BTLinkManager");
+
+BluetoothDeviceDiscoverer* BluetoothDeviceDiscoverer::NewL(
+ BluetoothFunctionServer *aFunctionServer)
+{
+ JELOG2(EJavaBluetooth);
+ BluetoothDeviceDiscoverer *self = new BluetoothDeviceDiscoverer(
+ aFunctionServer);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+}
+
+void BluetoothDeviceDiscoverer::ConstructL()
+{
+ int result = -1;
+ User::LeaveIfError(mSocketServerStatus = mSocketServer.Connect());
+ mSocketServer.ShareAuto();
+ mSocketServerStatus = SOCKETSERVER_CONNECTED;
+
+ result = pthread_mutex_init(&mMutex, 0);
+ if (result == 0)
+ {
+ result = pthread_cond_init(&mCondVar, 0);
+ }
+ if (0 != result)
+ {
+ User::Leave(result);
+ }
+}
+
+BluetoothDeviceDiscoverer::BluetoothDeviceDiscoverer(
+ BluetoothFunctionServer *aFunctionServer) :
+ CActive(EPriorityStandard)
+{
+ CActiveScheduler::Add(this);
+ mFunctionServer = aFunctionServer;
+}
+
+BluetoothDeviceDiscoverer::~BluetoothDeviceDiscoverer()
+{
+ JELOG2(EJavaBluetooth);
+
+ mHostResolver.Close();
+
+ if (SOCKETSERVER_CONNECTED == mSocketServerStatus)
+ mSocketServer.Close();
+
+ clearQueue();
+ pthread_mutex_destroy(&mMutex);
+ pthread_cond_destroy(&mCondVar);
+
+
+}
+
+/**
+ * Searches for the next device.
+ * If found, then returns the discovered device information
+ * Otherwise, in case of error or completion, returns INQUIRY_COMAPLETED
+ * and in case of cancele, returnsn INQUIRY_TERMINATED
+ */
+int BluetoothDeviceDiscoverer::getNextDevice(
+ DiscoveredDevice &aDiscoveredDevice)
+{
+ JELOG2(EJavaBluetooth);
+
+ dequeue(aDiscoveredDevice);
+ return aDiscoveredDevice.mInquiryStatus;
+}
+
+/**
+ * Starts the searching for the next device
+ */
+void BluetoothDeviceDiscoverer::setNext()
+{
+ JELOG2(EJavaBluetooth);
+
+ if (!IsActive())
+ {
+ // Get next discovered device
+ mHostResolver.Next(mNameEntry, iStatus);
+ SetActive();
+ }
+}
+
+/**
+ * Initializes the device inquiry
+ */
+void BluetoothDeviceDiscoverer::DiscoverDevicesL(int aAccessCode)
+{
+ JELOG2(EJavaBluetooth);
+
+ TInquirySockAddr inquirySockAddr;
+
+ if (!IsActive())
+ {
+ LOG(EJavaBluetooth, EInfo,
+ "+ BluetoothDeviceDiscoverer::DiscoverDevicesL Finding protocol");
+ // Load protocol for discovery
+ TProtocolDesc pdesc;
+ User::LeaveIfError(mSocketServer.FindProtocol(KBTLinkManagerTxt(),
+ pdesc));
+
+ // Initialize host resolver
+ mHostResolver.Close();
+
+ User::LeaveIfError(mHostResolver.Open(mSocketServer, pdesc.iAddrFamily,
+ pdesc.iProtocol));
+
+ // Start device discovery by invoking remote address lookup
+ if (KGIAC == aAccessCode)
+ LOG(EJavaBluetooth, EInfo,
+ " BluetoothDeviceDiscoverer::DiscoverDevicesL GIAC");
+ else if (KLIAC == aAccessCode)
+ LOG(EJavaBluetooth, EInfo,
+ " BluetoothDeviceDiscoverer::DiscoverDevicesL LIAC");
+ else
+ LOG1(EJavaBluetooth, EInfo,
+ " BluetoothDeviceDiscoverer::DiscoverDevicesL Val: %X",
+ aAccessCode);
+
+ inquirySockAddr.SetIAC(aAccessCode);
+ inquirySockAddr.SetAction(KHostResInquiry | KHostResName
+ | KHostResIgnoreCache);
+
+ mHostResolver.GetByAddress(inquirySockAddr, mNameEntry, iStatus);
+
+ SetActive();
+ }
+ else
+ {
+ ELOG(EJavaBluetooth,
+ "- BluetoothDeviceDiscoverer::DiscoverDevicesL Leaving. Not ready!");
+ User::Leave(KErrNotReady);
+ }
+}
+
+void BluetoothDeviceDiscoverer::RunL()
+{
+ JELOG2(EJavaBluetooth);
+ bool continueFlag = false;
+
+ DiscoveredDevice *discoveredDevice = new DiscoveredDevice();
+
+ if (iStatus.Int() == KErrCancel)
+ {
+ RThread thread;
+ int error = thread.Open(mThreadName, EOwnerProcess);
+ if (error == KErrNone)
+ {
+ thread.RequestSignal();
+ }
+
+ clearQueue();
+ discoveredDevice->mInquiryStatus = INQUIRY_TERMINATED;
+ }
+ else if (KErrNone == iStatus.Int())
+ {
+ fillDeviceInfo(*discoveredDevice);
+ continueFlag = true;
+ }
+ else
+ {
+ discoveredDevice->mInquiryStatus = INQUIRY_COMPLETED;
+ }
+
+ discoveredDevice->mErrVal = iStatus.Int();
+
+ enqueue(discoveredDevice);
+
+ if (continueFlag)
+ {
+ setNext();
+ }
+
+}
+
+void BluetoothDeviceDiscoverer::DoCancel()
+{
+ JELOG2(EJavaBluetooth);
+
+ RThread thread;
+ thread.FullName(mThreadName);
+ mHostResolver.Cancel();
+}
+
+/**
+ * Fills the discovered device information into DiscoveredDevice object
+ */
+void BluetoothDeviceDiscoverer::fillDeviceInfo(
+ DiscoveredDevice &aDiscoveredDevice)
+{
+ JELOG2(EJavaBluetooth);
+
+ // Filling inquiry status
+ aDiscoveredDevice.mInquiryStatus = STATUS_DEVICE_FOUND;
+
+ // Filling device name
+ std::wstring *deviceName = new std::wstring(
+ (wchar_t*) mNameEntry().iName.Ptr());
+ deviceName->resize(mNameEntry().iName.Length());
+
+ aDiscoveredDevice.mDeviceName = deviceName;
+
+ LOG1(EJavaBluetooth, EInfo,
+ " BluetoothDeviceDiscoverer::fillDeviceInfo Device Name %S",
+ deviceName->c_str());
+
+ // Filling device address
+ TBTDevAddr add = static_cast<TBTSockAddr>(mNameEntry().iAddr).BTAddr();
+ TBuf<20> buff;
+
+ add.GetReadable(buff);
+ std::wstring *deviceAddr = new std::wstring((wchar_t*) buff.Ptr());
+ deviceAddr->resize(buff.Length());
+
+ aDiscoveredDevice.mDeviceAddr = deviceAddr;
+
+ LOG1(EJavaBluetooth, EInfo,
+ " BluetoothDeviceDiscoverer::fillDeviceInfo Device Address %S",
+ deviceAddr->c_str());
+
+ // Filling device class
+ TInquirySockAddr& dev = TInquirySockAddr::Cast(mNameEntry().iAddr);
+
+ int deviceClass = (dev.MajorServiceClass() << SERVICE_CLASS_POS)
+ | (dev.MajorClassOfDevice() << MAJOR_CLASS_POS)
+ | (dev.MajorClassOfDevice() << MINOR_CLASS_POS);
+
+ aDiscoveredDevice.mDeviceClass = deviceClass;
+
+ LOG1(EJavaBluetooth, EInfo,
+ " BluetoothDeviceDiscoverer::fillDeviceInfo DeviceClass %d",
+ deviceClass);
+}
+
+void BluetoothDeviceDiscoverer::enqueue(DiscoveredDevice *aDiscoveredDevice)
+{
+ JELOG2(EJavaBluetooth);
+
+ pthread_mutex_lock(&mMutex);
+
+ mDiscoveredDevicesQueue.push(aDiscoveredDevice);
+ if (mWaiting)
+ {
+ LOG(EJavaBluetooth, EInfo,
+ "- BluetoothDeviceDiscoverer::enqueue NOTIFYING");
+ pthread_cond_signal(&mCondVar);
+ }
+ mWaiting = false;
+ pthread_mutex_unlock(&mMutex);
+}
+
+void BluetoothDeviceDiscoverer::dequeue(DiscoveredDevice& aDiscoveredDevice)
+{
+ JELOG2(EJavaBluetooth);
+ LOG1(EJavaBluetooth, EInfo, "+ BluetoothDeviceDiscoverer::dequeue :%d",
+ mDiscoveredDevicesQueue.empty());
+ DiscoveredDevice ret;
+
+ pthread_mutex_lock(&mMutex);
+ if (mDiscoveredDevicesQueue.empty())
+ {
+ LOG(EJavaBluetooth, EInfo,
+ "- BluetoothDeviceDiscoverer::dequeue WAITING");
+ mWaiting = true;
+
+ while (mWaiting)
+ {
+ pthread_cond_wait(&mCondVar, &mMutex);
+ }
+ }
+
+ DiscoveredDevice *ptr = mDiscoveredDevicesQueue.front();
+ aDiscoveredDevice = *ptr;
+ delete ptr; // pop doesn't invoke the destructor
+ mDiscoveredDevicesQueue.pop();
+ pthread_mutex_unlock(&mMutex);
+}
+
+void BluetoothDeviceDiscoverer::clearQueue()
+{
+ JELOG2(EJavaBluetooth);
+ pthread_mutex_lock(&mMutex);
+
+ while (!mDiscoveredDevicesQueue.empty())
+ {
+ mDiscoveredDevicesQueue.pop();
+ }
+ pthread_mutex_unlock(&mMutex);
+}
+
+} //end namespace java
+} //end namespace bluetooth