bluetoothengine/bteng/btengdiscovery/src/btengdevicesearch.cpp
changeset 0 f63038272f30
child 22 613943a21004
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/bteng/btengdiscovery/src/btengdevicesearch.cpp	Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,337 @@
+/*
+* Copyright (c) 2006 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:  Helper class implementation for performing device discovery.
+*
+*/
+
+
+#include "btengdevicesearch.h"
+#include "btengdiscovery.h"
+#include "debug.h"
+
+/**
+ * the request ID for device search using RNotifer.
+ */
+const TInt KDevSearchAoReqId = 40;
+
+/*
+ * the request ID for EIR service uuids using host resolver
+ */
+const TInt KDevEirServiceListAoReqId = 41;
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// C++ default constructor
+// ---------------------------------------------------------------------------
+//
+CBTEngDeviceSearch::CBTEngDeviceSearch()
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// Symbian 2nd-phase constructor
+// ---------------------------------------------------------------------------
+//
+void CBTEngDeviceSearch::ConstructL()
+    {
+    User::LeaveIfError( iNotifier.Connect() );
+    iActive = CBTEngActive::NewL( *this, KDevSearchAoReqId, 
+                                   CActive::EPriorityStandard );
+    }
+
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CBTEngDeviceSearch* CBTEngDeviceSearch::NewL()
+    {
+    CBTEngDeviceSearch* self = new( ELeave ) CBTEngDeviceSearch();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CBTEngDeviceSearch::~CBTEngDeviceSearch()
+    {
+    if( iNotifier.Handle()&& iActive->IsActive())
+       {
+       iNotifier.CancelNotifier( KDeviceSelectionNotifierUid );
+       iActive->CancelRequest();
+       }
+    delete iActive;
+    iNotifier.Close();
+    iHostResolver.Close();
+    iSocketServer.Close();
+    }
+
+// ---------------------------------------------------------------------------
+// Start the device discovery notifier.
+// ---------------------------------------------------------------------------
+//
+TInt CBTEngDeviceSearch::StartSearch( CBTDevice* aDevice, TNameEntry* aNameEntry,
+    const TBTDeviceClass& aDeviceClass, MBTEngSdpResultReceiver* aNotifier )
+    {
+    TRACE_FUNC_ENTRY
+    TInt err ( KErrNone );
+    if( iActive->IsActive() )
+        {
+        err = KErrInUse;
+        }
+    if( !err && !iNotifier.Handle() )
+        {
+        err = iNotifier.Connect();
+        }
+    if( !err )
+        {
+        iClientReq = EDeviceSearch;
+        iResultNotifier = aNotifier;
+        iNameEntry = aNameEntry;
+        iDevice = aDevice;
+            // Selection parameters
+        TBTDeviceSelectionParams params;
+        params.SetDeviceClass( aDeviceClass );
+        iSelectionPckg = TBTDeviceSelectionParamsPckg( params );
+            // Response parameters
+        TBTDeviceResponseParams result;
+        iResponsePckg = TBTDeviceResponseParamsPckg( result );
+        iActive->SetRequestId( KDevSearchAoReqId );
+        iNotifier.StartNotifierAndGetResponse( iActive->RequestStatus(), 
+                                                KDeviceSelectionNotifierUid, 
+                                                iSelectionPckg, iResponsePckg );
+        iActive->GoActive();
+        }
+    TRACE_FUNC_EXIT
+    return err;
+    }
+
+// ---------------------------------------------------------------------------
+// Cancel an ongoing device discovery.
+// ---------------------------------------------------------------------------
+//
+void CBTEngDeviceSearch::CancelSearch()
+    {
+    TRACE_FUNC_ENTRY
+    if( iActive->IsActive() && iClientReq == EDeviceSearch)
+        {
+        if (iActive->RequestId() == KDevSearchAoReqId)
+            {
+            iNotifier.CancelNotifier( KDeviceSelectionNotifierUid );
+            iActive->CancelRequest();
+            iNotifier.Close();
+            NotifyClient(KErrAbort);
+            }
+        else if (iActive->RequestId() == KDevEirServiceListAoReqId)
+            {
+            iHostResolver.Cancel();
+            iHostResolver.Close();
+            }
+        }
+    
+    TRACE_FUNC_EXIT
+    }
+
+// ---------------------------------------------------------------------------
+// Get cached EIR data from host resolver and extract service uuids
+// ---------------------------------------------------------------------------
+//
+TInt CBTEngDeviceSearch::GetEirServiceUUIDs( const TBTDevAddr& aAddr, 
+        TNameEntry* aNameEntry, MBTEngSdpResultReceiver* aNotifier)
+    {
+    TRACE_FUNC_ENTRY
+    TInt err = KErrNone;
+    if( iActive->IsActive() )
+        {
+        err = KErrInUse;
+        }
+    if (!err)
+        {
+        iClientReq = EGetDeviceEir;
+        iResultNotifier = aNotifier;
+        iNameEntry = aNameEntry;
+        err = DoGetDeviceEir(aAddr);
+        }
+    TRACE_FUNC_EXIT
+    return err;
+    }
+
+// ---------------------------------------------------------------------------
+// Cancel an ongoing EIR services retieval.
+// ---------------------------------------------------------------------------
+//
+void CBTEngDeviceSearch::CancelGetEirServiceUUIDs()
+    {
+    TRACE_FUNC_ENTRY
+    if( iActive->IsActive() && iClientReq == EGetDeviceEir)
+        {
+        iHostResolver.Cancel();
+        iHostResolver.Close();
+        }
+    TRACE_FUNC_EXIT
+    }
+
+// ---------------------------------------------------------------------------
+// From class MBTEngActiveObserver.
+// Callback to notify that an outstanding request has completed.
+// ---------------------------------------------------------------------------
+//
+void CBTEngDeviceSearch::RequestCompletedL( CBTEngActive* aActive, TInt aId, 
+    TInt aStatus )
+    {
+    TRACE_FUNC_ARG( ( _L( "status: %d") , aStatus ) )
+    (void) aActive;
+    if ( aId == KDevSearchAoReqId )
+        {
+        HandleDeviceSelectionResultL(aStatus);
+        }
+    else if (aId == KDevEirServiceListAoReqId)
+        {
+        HandleDeviceEirDataResult( aStatus );
+        }
+    TRACE_FUNC_EXIT
+    }
+
+// ---------------------------------------------------------------------------
+// From class MBTEngActiveObserver.
+// Callback to notify that an error has occurred in RunL.
+// ---------------------------------------------------------------------------
+//
+void CBTEngDeviceSearch::HandleError( CBTEngActive* aActive, TInt aId, 
+    TInt aError )
+    {
+    TRACE_FUNC_ARG( ( _L( "error: %d") , aError ) )
+    (void) aActive;
+    (void) aId;
+    iNotifier.Close();
+    iHostResolver.Close();
+    NotifyClient(aError);
+    }
+
+// ---------------------------------------------------------------------------
+// get device eir from cache
+// ---------------------------------------------------------------------------
+//
+TInt CBTEngDeviceSearch::DoGetDeviceEir(const TBTDevAddr& aAddr)
+    {
+    TRACE_FUNC_ENTRY
+    TInt err (KErrNone);
+    if (!iSocketServer.Handle())
+        {
+        err = iSocketServer.Connect();
+        }
+    
+    TProtocolDesc pInfo;
+    if (!err)
+        {
+        _LIT(KBTLinkManagerProtocol, "BTLinkManager");
+        err =  iSocketServer.FindProtocol( KBTLinkManagerProtocol(), pInfo );
+        }
+    if (!err)
+        {
+        err = iHostResolver.Open(iSocketServer, pInfo.iAddrFamily, pInfo.iProtocol);
+        }
+    if( !err )
+        {
+        iInquirySockAddr = TInquirySockAddr();
+        iInquirySockAddr.SetBTAddr(aAddr );
+        iInquirySockAddr.SetAction( KHostResCache );
+        iActive->SetRequestId( KDevEirServiceListAoReqId );
+        iHostResolver.GetByAddress( iInquirySockAddr, *iNameEntry, iActive->RequestStatus() );
+        iActive->GoActive();
+        }
+    TRACE_FUNC_EXIT
+    return err;
+    }
+
+void CBTEngDeviceSearch::HandleDeviceSelectionResultL(TInt aErr)
+    {
+    TRACE_FUNC_ENTRY
+    TInt err (aErr);
+    iNotifier.Close();
+    if (!err)
+        {
+        // Copy information to returned device
+        iDevice->SetDeviceAddress( iResponsePckg().BDAddr() );
+        iDevice->SetDeviceNameL( BTDeviceNameConverter::ToUTF8L( 
+                                                iResponsePckg().DeviceName() ) );
+        iDevice->SetDeviceClass( iResponsePckg().DeviceClass() );  
+        }
+    if (!err && iNameEntry)
+        {
+        err = DoGetDeviceEir(iResponsePckg().BDAddr());
+        }
+    // if an error happens, or the caller doesn't need the EIR part, complete
+    // the request. Otherwise the client will be called after getting EIR 
+    // completes.
+    if (err || !iNameEntry)
+        {
+        NotifyClient(err);
+        }
+    TRACE_FUNC_EXIT
+    }
+
+// ---------------------------------------------------------------------------
+// extracting service uuids from the device EIR data returned by host resolver
+// ---------------------------------------------------------------------------
+//
+void CBTEngDeviceSearch::HandleDeviceEirDataResult(TInt aErr)
+    {
+    TRACE_FUNC_ENTRY
+    iHostResolver.Close();
+    
+    if ( iClientReq == EDeviceSearch)
+        {
+        // Device search has already completed correctly, so 
+        // we don't pass GetEir error 
+        NotifyClient( KErrNone );
+        }
+    else
+        {
+        NotifyClient( aErr );
+        }
+    TRACE_FUNC_EXIT
+    }
+
+// ---------------------------------------------------------------------------
+// Callback to notify that the caller's request has completed.
+// ---------------------------------------------------------------------------
+//
+void CBTEngDeviceSearch::NotifyClient(TInt aErr)
+    {
+    TRACE_FUNC_ENTRY
+    if( iResultNotifier && iClientReq == EDeviceSearch)
+        {
+        if (iNameEntry)
+            {
+            iResultNotifier->DeviceSearchComplete( iDevice, iNameEntry, aErr );
+            }
+        else
+            {
+            iResultNotifier->DeviceSearchComplete( iDevice, aErr );
+            }
+        }
+    if (iResultNotifier && iClientReq == EGetDeviceEir)
+        {
+        iResultNotifier->GetEirServiceUUIDsComplete(iNameEntry, aErr);
+        }
+    TRACE_FUNC_EXIT
+    }
+