--- /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
+ }
+