diff -r 000000000000 -r f63038272f30 bluetoothengine/bteng/btengdiscovery/src/btengdevicesearch.cpp --- /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 + } +