javaextensions/bluetooth/omjbluetooth/src.s60/bluetoothdevicediscoverer.cpp
branchRCL_3
changeset 19 04becd199f91
--- /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