javaextensions/bluetooth/omjbluetooth/src.s60/bluetoothservicesearcher.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 <bluetooth/hci/hcierrors.h>
       
    20 
       
    21 #include "bluetoothconsts.h"
       
    22 #include "bluetoothservicesearcher.h"
       
    23 #include "discoveryagent.h"
       
    24 
       
    25 namespace java
       
    26 {
       
    27 namespace bluetooth
       
    28 {
       
    29 
       
    30 #define GET_VALID_HCI_ERR_CODE(err_no) (((err_no) < KHCIErrorBase) ? \
       
    31                                         (KHCIErrorBase - (err_no)) : \
       
    32                                         (err_no))
       
    33 
       
    34 BluetoothServiceSearcher* BluetoothServiceSearcher::New(
       
    35     DiscoveryAgent *aDiscoveryAgent, BluetoothFunctionServer* aServer)
       
    36 {
       
    37     JELOG2(EJavaBluetooth);
       
    38     BluetoothServiceSearcher* searcher = new BluetoothServiceSearcher();
       
    39     searcher->Construct(aDiscoveryAgent, aServer);
       
    40     return searcher;
       
    41 }
       
    42 
       
    43 BluetoothServiceSearcher::BluetoothServiceSearcher()
       
    44 {
       
    45 }
       
    46 
       
    47 void BluetoothServiceSearcher::Construct(DiscoveryAgent *aDiscoveryAgent,
       
    48         BluetoothFunctionServer* aServer)
       
    49 {
       
    50     JELOG2(EJavaBluetooth);
       
    51     mDiscoveryAgent = aDiscoveryAgent;
       
    52     mServer = aServer;
       
    53     mSDPAgent = NULL;
       
    54     mSpat = NULL;
       
    55     mAttributeList = NULL;
       
    56     mSrPopulator = NULL;
       
    57     mFoundServiceRecord = false;
       
    58     mIsPopulateRecordMode = false;
       
    59 
       
    60     mJni = mServer->getValidJniEnv();
       
    61     mPeer = mServer->getPeer();
       
    62 
       
    63     jclass peerClass = mJni->GetObjectClass(mPeer);
       
    64     mCreateServiceRecordMethod
       
    65     = mJni->GetMethodID(peerClass, "createServiceRecord",
       
    66                         "(J)Lcom/intel/bluetooth/ServiceRecordImpl;");
       
    67 
       
    68     mServiceRecordImplClass = mJni->FindClass(
       
    69                                   "com/intel/bluetooth/ServiceRecordImpl");
       
    70 
       
    71 }
       
    72 
       
    73 BluetoothServiceSearcher::~BluetoothServiceSearcher()
       
    74 {
       
    75     JELOG2(EJavaBluetooth);
       
    76     Cleanup();
       
    77 }
       
    78 
       
    79 void BluetoothServiceSearcher::SearchServicesL(TInt64 aRemoteAddress,
       
    80         TPtrC8 aUuidsDes, TPtrC16 aAttrIdsDes)
       
    81 {
       
    82     JELOG2(EJavaBluetooth);
       
    83     LOG1(EJavaBluetooth, EInfo,
       
    84          "+ BluetoothServiceSearcher:: SearchServices:%X",
       
    85          (long) aRemoteAddress);
       
    86 
       
    87     mIsPopulateRecordMode = false;
       
    88 
       
    89     TBTDevAddr devAddr(aRemoteAddress);
       
    90 
       
    91     FillSearchPatternL(aUuidsDes);
       
    92 
       
    93     FillAttributeListL(aAttrIdsDes);
       
    94 
       
    95     LOG(
       
    96         EJavaBluetooth,
       
    97         EInfo,
       
    98         "  BluetoothServiceSearcher::SearchServicesOnDeviceL: Clearing SDPAgent if any...");
       
    99     // Init new service discovery agent
       
   100     if (mSDPAgent)
       
   101     {
       
   102         delete mSDPAgent;
       
   103         mSDPAgent = NULL;
       
   104     }
       
   105     mSDPAgent = CSdpAgent::NewL(*this, devAddr);
       
   106 
       
   107     mSDPAgent->SetRecordFilterL(*mSpat);
       
   108 
       
   109     mSDPAgent->NextRecordRequestL();
       
   110 
       
   111 }
       
   112 
       
   113 void BluetoothServiceSearcher::cancelServiceSearch()
       
   114 {
       
   115     JELOG2(EJavaBluetooth);
       
   116     DiscoveryAgent* tempDiscoveryAgent = mDiscoveryAgent;
       
   117     Cleanup();
       
   118     if (NULL == tempDiscoveryAgent)
       
   119         return;
       
   120     if (!mIsPopulateRecordMode)
       
   121     {
       
   122         tempDiscoveryAgent->ServiceSearchCompleted(SERVICE_SEARCH_TERMINATED);
       
   123     }
       
   124     else
       
   125     {
       
   126         tempDiscoveryAgent->PopulateRecordCompleted(SERVICE_SEARCH_TERMINATED);
       
   127     }
       
   128 }
       
   129 
       
   130 void BluetoothServiceSearcher::Cleanup()
       
   131 {
       
   132     JELOG2(EJavaBluetooth);
       
   133     if (mSDPAgent)
       
   134     {
       
   135         delete mSDPAgent;
       
   136         mSDPAgent = NULL;
       
   137     }
       
   138     if (mSpat)
       
   139     {
       
   140         mSpat->Reset();
       
   141         delete mSpat;
       
   142         mSpat = NULL;
       
   143     }
       
   144     if (mAttributeList)
       
   145     {
       
   146         delete mAttributeList;
       
   147         mAttributeList = NULL;
       
   148     }
       
   149     if (mSrPopulator)
       
   150     {
       
   151         delete mSrPopulator;
       
   152         mSrPopulator = NULL;
       
   153     }
       
   154 
       
   155     mDiscoveryAgent = NULL;
       
   156 }
       
   157 
       
   158 void BluetoothServiceSearcher::NextRecordRequestComplete(TInt aError,
       
   159         TSdpServRecordHandle aHandle, TInt /*aTotalRecordsCount*/)
       
   160 {
       
   161     JELOG2(EJavaBluetooth);
       
   162     LOG1(
       
   163         EJavaBluetooth,
       
   164         EInfo,
       
   165         "  BluetoothServiceSearcher::NextRecordRequestComplete aError=%d",
       
   166         aError);
       
   167 
       
   168     if (KErrEof == aError && !mFoundServiceRecord)
       
   169     {
       
   170         LOG(
       
   171             EJavaBluetooth,
       
   172             EInfo,
       
   173             "  BluetoothServiceSearcher::NextRecordRequestComplete SERVICE_SEARCH_NO_RECORDS");
       
   174         mDiscoveryAgent->ServiceSearchCompleted(SERVICE_SEARCH_NO_RECORDS);
       
   175     }
       
   176     else if (KErrNone == aError)
       
   177     {
       
   178         TInt64 servRecHandle = MAKE_TINT64(0, aHandle);
       
   179         mServiceRecordImpl = (*mJni).CallObjectMethod(mPeer,
       
   180                              mCreateServiceRecordMethod, servRecHandle);
       
   181         if (NULL == mServiceRecordImpl)
       
   182         {
       
   183             LOG(EJavaBluetooth, EInfo,
       
   184                 "  BluetoothServiceSearcher::NextRecordRequestComplete SERVICE_SEARCH_ERROR");
       
   185             mDiscoveryAgent->ServiceSearchCompleted(SERVICE_SEARCH_ERROR);
       
   186         }
       
   187         else
       
   188         {
       
   189             LOG(EJavaBluetooth, EInfo,
       
   190                 "  BluetoothServiceSearcher::NextRecordRequestComplete Populating record");
       
   191             delete mSrPopulator;
       
   192             mSrPopulator = BTServiceRecordPopulator::New(mJni,
       
   193                            mServiceRecordImpl);
       
   194             TRAPD(attrRequestErr, mSDPAgent->AttributeRequestL(mSrPopulator,
       
   195                     aHandle, *mAttributeList));
       
   196             if (KErrNone != attrRequestErr)
       
   197             {
       
   198                 delete mSrPopulator;
       
   199                 mSrPopulator = NULL;
       
   200                 mDiscoveryAgent->ServiceSearchCompleted(SERVICE_SEARCH_ERROR);
       
   201             }
       
   202         }
       
   203     }
       
   204     else if (EPageTimedOut == GET_VALID_HCI_ERR_CODE(aError))
       
   205     {
       
   206         LOG(
       
   207             EJavaBluetooth,
       
   208             EInfo,
       
   209             "  BluetoothServiceSearcher::NextRecordRequestComplete SERVICE_SEARCH_DEVICE_NOT_REACHABLE");
       
   210         mDiscoveryAgent->ServiceSearchCompleted(
       
   211             SERVICE_SEARCH_DEVICE_NOT_REACHABLE);
       
   212     }
       
   213     else
       
   214     {
       
   215         LOG1(
       
   216             EJavaBluetooth,
       
   217             EInfo,
       
   218             "  BluetoothServiceSearcher::NextRecordRequestComplete SERVICE_SEARCH_COMPLETED %d",
       
   219             aError);
       
   220         mDiscoveryAgent->ServiceSearchCompleted(SERVICE_SEARCH_COMPLETED);
       
   221     }
       
   222 }
       
   223 
       
   224 void BluetoothServiceSearcher::PopulateServiceRecordsL(TInt64 aRemoteAddress,
       
   225         long aHandle, TPtrC16 aAttrIdsDes, jobject aServiceRecordImpl)
       
   226 {
       
   227     JELOG2(EJavaBluetooth);
       
   228 
       
   229     mIsPopulateRecordMode = true;
       
   230 
       
   231     TBTDevAddr devAddr(aRemoteAddress);
       
   232 
       
   233     FillAttributeListL(aAttrIdsDes);
       
   234 
       
   235     LOG(
       
   236         EJavaBluetooth,
       
   237         EInfo,
       
   238         "  BluetoothServiceSearcher::PopulateServiceRecords: Clearing SDPAgent if any...");
       
   239 
       
   240     if (mSDPAgent)
       
   241     {
       
   242         mSDPAgent->Cancel();
       
   243         delete mSDPAgent;
       
   244         mSDPAgent = NULL;
       
   245     }
       
   246     mSDPAgent = CSdpAgent::NewL(*this, devAddr);
       
   247 
       
   248     mServiceRecordImpl = aServiceRecordImpl;
       
   249 
       
   250     delete mSrPopulator;
       
   251     mSrPopulator = BTServiceRecordPopulator::New(mJni, mServiceRecordImpl);
       
   252 
       
   253     mSDPAgent->AttributeRequestL(mSrPopulator, aHandle, *mAttributeList);
       
   254 }
       
   255 
       
   256 void BluetoothServiceSearcher::AttributeRequestResult(
       
   257     TSdpServRecordHandle /*aHandle*/, TSdpAttributeID /*aAttrID*/,
       
   258     CSdpAttrValue* /*aAttrValue*/)
       
   259 {
       
   260     // No implementation required...
       
   261 }
       
   262 
       
   263 void BluetoothServiceSearcher::AttributeRequestComplete(
       
   264     TSdpServRecordHandle /*aHandle*/, TInt aError)
       
   265 {
       
   266     JELOG2(EJavaBluetooth);
       
   267     LOG1(EJavaBluetooth, EInfo,
       
   268          "  BluetoothServiceSearcher::AttributeRequestComplete aError=%d",
       
   269          aError);
       
   270 
       
   271     int status = 0;
       
   272     bool attributeFound = mSrPopulator->isAttributesFound();
       
   273 
       
   274     delete mSrPopulator;
       
   275     mSrPopulator = NULL;
       
   276 
       
   277     if (KErrNone == aError && !mIsPopulateRecordMode)
       
   278     {
       
   279         mFoundServiceRecord = true;
       
   280         LOG(
       
   281             EJavaBluetooth,
       
   282             EInfo,
       
   283             "  BluetoothServiceSearcher::AttributeRequestComplete Callback serviceDiscoveredCallback");
       
   284         jclass peerClass = mJni->GetObjectClass(mPeer);
       
   285         jmethodID serviceDiscoveredMethod = mJni->GetMethodID(peerClass,
       
   286                                             "serviceDiscoveredCallback",
       
   287                                             "(Lcom/intel/bluetooth/ServiceRecordImpl;)V");
       
   288         (*mJni).CallVoidMethod(mPeer, serviceDiscoveredMethod,
       
   289                                mServiceRecordImpl);
       
   290 
       
   291         LOG(
       
   292             EJavaBluetooth,
       
   293             EInfo,
       
   294             "  BluetoothServiceSearcher::AttributeRequestComplete. Trying for the next record if any");
       
   295 
       
   296         // In case of any leave, then this will terminates the search for the next record.
       
   297         TRAP_IGNORE(mSDPAgent->NextRecordRequestL());
       
   298     }
       
   299     else
       
   300     {
       
   301         if (KErrNone == aError)
       
   302         {
       
   303             mFoundServiceRecord = true;
       
   304             status = SERVICE_SEARCH_COMPLETED;
       
   305         }
       
   306         else if (EPageTimedOut == GET_VALID_HCI_ERR_CODE(aError))
       
   307         {
       
   308             LOG(
       
   309                 EJavaBluetooth,
       
   310                 EInfo,
       
   311                 "  BluetoothServiceSearcher::AttributeRequestComplete SERVICE_SEARCH_DEVICE_NOT_REACHABLE");
       
   312             status = SERVICE_SEARCH_DEVICE_NOT_REACHABLE;
       
   313         }
       
   314         else
       
   315         {
       
   316             LOG(EJavaBluetooth, EInfo,
       
   317                 "  BluetoothServiceSearcher::AttributeRequestComplete SERVICE_SEARCH_ERROR");
       
   318             status = SERVICE_SEARCH_ERROR;
       
   319         }
       
   320 
       
   321         if (!mIsPopulateRecordMode)
       
   322         {
       
   323             mDiscoveryAgent->ServiceSearchCompleted(status);
       
   324         }
       
   325         else
       
   326         {
       
   327             if (false == attributeFound)
       
   328                 status = SERVICE_SEARCH_NO_RECORDS;
       
   329             mDiscoveryAgent->PopulateRecordCompleted(status);
       
   330         }
       
   331     }
       
   332 }
       
   333 
       
   334 void BluetoothServiceSearcher::BluetoothServiceSearcher::FillSearchPatternL(
       
   335     TDesC8& uuidsBytes)
       
   336 {
       
   337     JELOG2(EJavaBluetooth);
       
   338 
       
   339     const TInt numBytes = uuidsBytes.Length();
       
   340     const TInt numberOfUUIDs = numBytes / KSdpUUIDMaxLength;
       
   341 
       
   342     TInt uuidsConverted = 0;
       
   343     TInt startByte = 0;
       
   344 
       
   345     if (mSpat)
       
   346     {
       
   347         mSpat->Reset();
       
   348         delete mSpat;
       
   349         mSpat = NULL;
       
   350     }
       
   351     mSpat = CSdpSearchPattern::NewL();
       
   352     CleanupStack::PushL(mSpat);
       
   353 
       
   354     while (uuidsConverted < numberOfUUIDs)
       
   355     {
       
   356         TUUID uuid;
       
   357         uuid.SetL(uuidsBytes.Mid(startByte, KSdpUUIDMaxLength));
       
   358 
       
   359         mSpat->AddL(uuid);
       
   360         startByte += KSdpUUIDMaxLength;
       
   361         uuidsConverted++;
       
   362     }
       
   363     CleanupStack::Pop(mSpat);
       
   364 }
       
   365 
       
   366 void BluetoothServiceSearcher::BluetoothServiceSearcher::FillAttributeListL(
       
   367     TDesC16& attrIds)
       
   368 {
       
   369     JELOG2(EJavaBluetooth);
       
   370     delete mAttributeList;
       
   371     mAttributeList = NULL;
       
   372     mAttributeList = CSdpAttrIdMatchList::NewL();
       
   373     CleanupStack::PushL(mAttributeList);
       
   374 
       
   375     TInt numElements = attrIds.Length();
       
   376 
       
   377     for (TInt attrIndex = 0; attrIndex < numElements; attrIndex += 2)
       
   378     {
       
   379         const TUint16* attrIdStartPtr = (attrIds.Mid(attrIndex, 2)).Ptr();
       
   380         const TInt* attrId = reinterpret_cast<const TInt*>(attrIdStartPtr);
       
   381         const TUint16 attrId16 = static_cast<TUint16>(*attrId);
       
   382         TAttrRange attrRange(static_cast<TSdpAttributeID>(attrId16));
       
   383 
       
   384         mAttributeList->AddL(attrRange);
       
   385     }
       
   386     CleanupStack::Pop(mAttributeList);
       
   387 
       
   388 }
       
   389 
       
   390 } //end namespace bluetooth
       
   391 } //end namespace java