javaextensions/bluetooth/omjbluetooth/src.s60/bluetoothdevicediscoverer.cpp
branchRCL_3
changeset 19 04becd199f91
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <string>
       
    20 #include <e32base.h>
       
    21 
       
    22 #include "logger.h"
       
    23 #include "fs_methodcall.h"
       
    24 #include "bluetoothconsts.h"
       
    25 #include "bluetoothdevicediscoverer.h"
       
    26 
       
    27 // Constants used to create device class
       
    28 #define SERVICE_CLASS_POS    13
       
    29 #define MAJOR_CLASS_POS       8
       
    30 #define MINOR_CLASS_POS       2
       
    31 
       
    32 #define SOCKETSERVER_CONNECTED 1
       
    33 
       
    34 namespace java
       
    35 {
       
    36 namespace bluetooth
       
    37 {
       
    38 
       
    39 _LIT(KBTLinkManagerTxt,"BTLinkManager");
       
    40 
       
    41 BluetoothDeviceDiscoverer* BluetoothDeviceDiscoverer::NewL(
       
    42     BluetoothFunctionServer *aFunctionServer)
       
    43 {
       
    44     JELOG2(EJavaBluetooth);
       
    45     BluetoothDeviceDiscoverer *self = new BluetoothDeviceDiscoverer(
       
    46         aFunctionServer);
       
    47     CleanupStack::PushL(self);
       
    48     self->ConstructL();
       
    49     CleanupStack::Pop(self);
       
    50     return self;
       
    51 }
       
    52 
       
    53 void BluetoothDeviceDiscoverer::ConstructL()
       
    54 {
       
    55     int result = -1;
       
    56     User::LeaveIfError(mSocketServerStatus = mSocketServer.Connect());
       
    57     mSocketServer.ShareAuto();
       
    58     mSocketServerStatus = SOCKETSERVER_CONNECTED;
       
    59 
       
    60     result = pthread_mutex_init(&mMutex, 0);
       
    61     if (result == 0)
       
    62     {
       
    63         result = pthread_cond_init(&mCondVar, 0);
       
    64     }
       
    65     if (0 != result)
       
    66     {
       
    67         User::Leave(result);
       
    68     }
       
    69 }
       
    70 
       
    71 BluetoothDeviceDiscoverer::BluetoothDeviceDiscoverer(
       
    72     BluetoothFunctionServer *aFunctionServer) :
       
    73         CActive(EPriorityStandard)
       
    74 {
       
    75     CActiveScheduler::Add(this);
       
    76     mFunctionServer = aFunctionServer;
       
    77 }
       
    78 
       
    79 BluetoothDeviceDiscoverer::~BluetoothDeviceDiscoverer()
       
    80 {
       
    81     JELOG2(EJavaBluetooth);
       
    82 
       
    83     mHostResolver.Close();
       
    84 
       
    85     if (SOCKETSERVER_CONNECTED == mSocketServerStatus)
       
    86         mSocketServer.Close();
       
    87 
       
    88     clearQueue();
       
    89     pthread_mutex_destroy(&mMutex);
       
    90     pthread_cond_destroy(&mCondVar);
       
    91 
       
    92 
       
    93 }
       
    94 
       
    95 /**
       
    96  * Searches for the next device.
       
    97  * If found, then returns the discovered device information
       
    98  * Otherwise, in case of error or completion, returns INQUIRY_COMAPLETED
       
    99  * and in case of cancele, returnsn INQUIRY_TERMINATED
       
   100  */
       
   101 int BluetoothDeviceDiscoverer::getNextDevice(
       
   102     DiscoveredDevice &aDiscoveredDevice)
       
   103 {
       
   104     JELOG2(EJavaBluetooth);
       
   105 
       
   106     dequeue(aDiscoveredDevice);
       
   107     return aDiscoveredDevice.mInquiryStatus;
       
   108 }
       
   109 
       
   110 /**
       
   111  * Starts the searching for the next device
       
   112  */
       
   113 void BluetoothDeviceDiscoverer::setNext()
       
   114 {
       
   115     JELOG2(EJavaBluetooth);
       
   116 
       
   117     if (!IsActive())
       
   118     {
       
   119         // Get next discovered device
       
   120         mHostResolver.Next(mNameEntry, iStatus);
       
   121         SetActive();
       
   122     }
       
   123 }
       
   124 
       
   125 /**
       
   126  * Initializes the device inquiry
       
   127  */
       
   128 void BluetoothDeviceDiscoverer::DiscoverDevicesL(int aAccessCode)
       
   129 {
       
   130     JELOG2(EJavaBluetooth);
       
   131 
       
   132     TInquirySockAddr inquirySockAddr;
       
   133 
       
   134     if (!IsActive())
       
   135     {
       
   136         LOG(EJavaBluetooth, EInfo,
       
   137             "+ BluetoothDeviceDiscoverer::DiscoverDevicesL Finding protocol");
       
   138         // Load protocol for discovery
       
   139         TProtocolDesc pdesc;
       
   140         User::LeaveIfError(mSocketServer.FindProtocol(KBTLinkManagerTxt(),
       
   141                            pdesc));
       
   142 
       
   143         // Initialize host resolver
       
   144         mHostResolver.Close();
       
   145 
       
   146         User::LeaveIfError(mHostResolver.Open(mSocketServer, pdesc.iAddrFamily,
       
   147                                               pdesc.iProtocol));
       
   148 
       
   149         // Start device discovery by invoking remote address lookup
       
   150         if (KGIAC == aAccessCode)
       
   151             LOG(EJavaBluetooth, EInfo,
       
   152                 "  BluetoothDeviceDiscoverer::DiscoverDevicesL GIAC");
       
   153         else if (KLIAC == aAccessCode)
       
   154             LOG(EJavaBluetooth, EInfo,
       
   155                 "  BluetoothDeviceDiscoverer::DiscoverDevicesL LIAC");
       
   156         else
       
   157             LOG1(EJavaBluetooth, EInfo,
       
   158                  "  BluetoothDeviceDiscoverer::DiscoverDevicesL Val: %X",
       
   159                  aAccessCode);
       
   160 
       
   161         inquirySockAddr.SetIAC(aAccessCode);
       
   162         inquirySockAddr.SetAction(KHostResInquiry | KHostResName
       
   163                                   | KHostResIgnoreCache);
       
   164 
       
   165         mHostResolver.GetByAddress(inquirySockAddr, mNameEntry, iStatus);
       
   166 
       
   167         SetActive();
       
   168     }
       
   169     else
       
   170     {
       
   171         ELOG(EJavaBluetooth,
       
   172              "- BluetoothDeviceDiscoverer::DiscoverDevicesL Leaving. Not ready!");
       
   173         User::Leave(KErrNotReady);
       
   174     }
       
   175 }
       
   176 
       
   177 void BluetoothDeviceDiscoverer::RunL()
       
   178 {
       
   179     JELOG2(EJavaBluetooth);
       
   180     bool continueFlag = false;
       
   181 
       
   182     DiscoveredDevice *discoveredDevice = new DiscoveredDevice();
       
   183 
       
   184     if (iStatus.Int() == KErrCancel)
       
   185     {
       
   186         RThread thread;
       
   187         int error = thread.Open(mThreadName, EOwnerProcess);
       
   188         if (error == KErrNone)
       
   189         {
       
   190             thread.RequestSignal();
       
   191         }
       
   192 
       
   193         clearQueue();
       
   194         discoveredDevice->mInquiryStatus = INQUIRY_TERMINATED;
       
   195     }
       
   196     else if (KErrNone == iStatus.Int())
       
   197     {
       
   198         fillDeviceInfo(*discoveredDevice);
       
   199         continueFlag = true;
       
   200     }
       
   201     else
       
   202     {
       
   203         discoveredDevice->mInquiryStatus = INQUIRY_COMPLETED;
       
   204     }
       
   205 
       
   206     discoveredDevice->mErrVal = iStatus.Int();
       
   207 
       
   208     enqueue(discoveredDevice);
       
   209 
       
   210     if (continueFlag)
       
   211     {
       
   212         setNext();
       
   213     }
       
   214 
       
   215 }
       
   216 
       
   217 void BluetoothDeviceDiscoverer::DoCancel()
       
   218 {
       
   219     JELOG2(EJavaBluetooth);
       
   220 
       
   221     RThread thread;
       
   222     thread.FullName(mThreadName);
       
   223     mHostResolver.Cancel();
       
   224 }
       
   225 
       
   226 /**
       
   227  * Fills the discovered device information into DiscoveredDevice object
       
   228  */
       
   229 void BluetoothDeviceDiscoverer::fillDeviceInfo(
       
   230     DiscoveredDevice &aDiscoveredDevice)
       
   231 {
       
   232     JELOG2(EJavaBluetooth);
       
   233 
       
   234     // Filling inquiry status
       
   235     aDiscoveredDevice.mInquiryStatus = STATUS_DEVICE_FOUND;
       
   236 
       
   237     // Filling device name
       
   238     std::wstring *deviceName = new std::wstring(
       
   239         (wchar_t*) mNameEntry().iName.Ptr());
       
   240     deviceName->resize(mNameEntry().iName.Length());
       
   241 
       
   242     aDiscoveredDevice.mDeviceName = deviceName;
       
   243 
       
   244     LOG1(EJavaBluetooth, EInfo,
       
   245          "  BluetoothDeviceDiscoverer::fillDeviceInfo Device Name %S",
       
   246          deviceName->c_str());
       
   247 
       
   248     // Filling device address
       
   249     TBTDevAddr add = static_cast<TBTSockAddr>(mNameEntry().iAddr).BTAddr();
       
   250     TBuf<20> buff;
       
   251 
       
   252     add.GetReadable(buff);
       
   253     std::wstring *deviceAddr = new std::wstring((wchar_t*) buff.Ptr());
       
   254     deviceAddr->resize(buff.Length());
       
   255 
       
   256     aDiscoveredDevice.mDeviceAddr = deviceAddr;
       
   257 
       
   258     LOG1(EJavaBluetooth, EInfo,
       
   259          "  BluetoothDeviceDiscoverer::fillDeviceInfo Device Address %S",
       
   260          deviceAddr->c_str());
       
   261 
       
   262     // Filling device class
       
   263     TInquirySockAddr& dev = TInquirySockAddr::Cast(mNameEntry().iAddr);
       
   264 
       
   265     int deviceClass = (dev.MajorServiceClass() << SERVICE_CLASS_POS)
       
   266                       | (dev.MajorClassOfDevice() << MAJOR_CLASS_POS)
       
   267                       | (dev.MajorClassOfDevice() << MINOR_CLASS_POS);
       
   268 
       
   269     aDiscoveredDevice.mDeviceClass = deviceClass;
       
   270 
       
   271     LOG1(EJavaBluetooth, EInfo,
       
   272          "  BluetoothDeviceDiscoverer::fillDeviceInfo DeviceClass %d",
       
   273          deviceClass);
       
   274 }
       
   275 
       
   276 void BluetoothDeviceDiscoverer::enqueue(DiscoveredDevice *aDiscoveredDevice)
       
   277 {
       
   278     JELOG2(EJavaBluetooth);
       
   279 
       
   280     pthread_mutex_lock(&mMutex);
       
   281 
       
   282     mDiscoveredDevicesQueue.push(aDiscoveredDevice);
       
   283     if (mWaiting)
       
   284     {
       
   285         LOG(EJavaBluetooth, EInfo,
       
   286             "- BluetoothDeviceDiscoverer::enqueue NOTIFYING");
       
   287         pthread_cond_signal(&mCondVar);
       
   288     }
       
   289     mWaiting = false;
       
   290     pthread_mutex_unlock(&mMutex);
       
   291 }
       
   292 
       
   293 void BluetoothDeviceDiscoverer::dequeue(DiscoveredDevice& aDiscoveredDevice)
       
   294 {
       
   295     JELOG2(EJavaBluetooth);
       
   296     LOG1(EJavaBluetooth, EInfo, "+ BluetoothDeviceDiscoverer::dequeue :%d",
       
   297          mDiscoveredDevicesQueue.empty());
       
   298     DiscoveredDevice ret;
       
   299 
       
   300     pthread_mutex_lock(&mMutex);
       
   301     if (mDiscoveredDevicesQueue.empty())
       
   302     {
       
   303         LOG(EJavaBluetooth, EInfo,
       
   304             "- BluetoothDeviceDiscoverer::dequeue WAITING");
       
   305         mWaiting = true;
       
   306 
       
   307         while (mWaiting)
       
   308         {
       
   309             pthread_cond_wait(&mCondVar, &mMutex);
       
   310         }
       
   311     }
       
   312 
       
   313     DiscoveredDevice *ptr = mDiscoveredDevicesQueue.front();
       
   314     aDiscoveredDevice = *ptr;
       
   315     delete ptr;   // pop doesn't invoke the destructor
       
   316     mDiscoveredDevicesQueue.pop();
       
   317     pthread_mutex_unlock(&mMutex);
       
   318 }
       
   319 
       
   320 void BluetoothDeviceDiscoverer::clearQueue()
       
   321 {
       
   322     JELOG2(EJavaBluetooth);
       
   323     pthread_mutex_lock(&mMutex);
       
   324 
       
   325     while (!mDiscoveredDevicesQueue.empty())
       
   326     {
       
   327         mDiscoveredDevicesQueue.pop();
       
   328     }
       
   329     pthread_mutex_unlock(&mMutex);
       
   330 }
       
   331 
       
   332 } //end namespace java
       
   333 } //end namespace bluetooth