/*
* Copyright (c) 2002 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: SyncML Obex client
*
*/
#include "NSmlBTServiceSearcher.h"
//============================================================
// CNSmlBTServiceSearcher definition
//============================================================
//------------------------------------------------------------
// CNSmlBTServiceSearcher::CNSmlBTServiceSearcher()
//------------------------------------------------------------
CNSmlBTServiceSearcher::CNSmlBTServiceSearcher( const TBTConnInfo& aBTConnInfo )
: iIsDeviceSelectorConnected(EFalse),
iBTConnInfo( aBTConnInfo )
{
iResponse().SetDeviceAddress( aBTConnInfo.iDevAddr );
}
//------------------------------------------------------------
// CNSmlBTServiceSearcher::~CNSmlBTServiceSearcher()
//------------------------------------------------------------
CNSmlBTServiceSearcher::~CNSmlBTServiceSearcher()
{
if( iIsDeviceSelectorConnected )
{
iDeviceSelector.CancelNotifier( KDeviceSelectionNotifierUid );
iDeviceSelector.Close();
}
Finished();
delete iSdpSearchPattern;
iSdpSearchPattern = NULL;
delete iAgent;
iAgent = NULL;
}
//------------------------------------------------------------
// CNSmlBTServiceSearcher::SelectDeviceByDiscoveryL( TRequestStatus& aObserverRequestStatus )
//------------------------------------------------------------
void CNSmlBTServiceSearcher::SelectDeviceByDiscoveryL( TRequestStatus& aObserverRequestStatus )
{
if( !iIsDeviceSelectorConnected )
{
User::LeaveIfError( iDeviceSelector.Connect() );
iIsDeviceSelectorConnected = ETrue;
}
// Request a device selection
TBTDeviceClass deviceClass(0 ,0 ,0);
TBTDeviceSelectionParams parameters;
parameters.SetDeviceClass(deviceClass);
TBTDeviceSelectionParamsPckg pckg(parameters);
pckg().SetUUID( iBTConnInfo.iServiceClass );
iDeviceSelector.StartNotifierAndGetResponse(
aObserverRequestStatus,
KDeviceSelectionNotifierUid,
/*selectionFilter*/pckg,
iResponse);
}
//------------------------------------------------------------
// CNSmlBTServiceSearcher::FindServiceL( TRequestStatus& aObserverRequestStatus )
//------------------------------------------------------------
void CNSmlBTServiceSearcher::FindServiceL( TRequestStatus& aObserverRequestStatus )
{
if( !iResponse().IsValidBDAddr() )
{
User::Leave( KErrNotFound );
}
iHasFoundService = EFalse;
// delete any existing agent and search pattern
delete iSdpSearchPattern;
iSdpSearchPattern = NULL;
delete iAgent;
iAgent = NULL;
iAgent = CSdpAgent::NewL( *this, BTDevAddr() );
iSdpSearchPattern = CSdpSearchPattern::NewL();
iSdpSearchPattern->AddL( iBTConnInfo.iServiceClass );
iAgent->SetRecordFilterL( *iSdpSearchPattern );
iStatusObserver = &aObserverRequestStatus;
iAgent->NextRecordRequestL();
}
//------------------------------------------------------------
// CNSmlBTServiceSearcher::NextRecordRequestComplete( TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount )
//------------------------------------------------------------
void CNSmlBTServiceSearcher::NextRecordRequestComplete( TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount )
{
TRAPD( error, NextRecordRequestCompleteL( aError, aHandle, aTotalRecordsCount) );
if ( error != KErrNone )
{
Panic( EBTServiceSearcherNextRecordRequestComplete );
}
}
//------------------------------------------------------------
// CNSmlBTServiceSearcher::NextRecordRequestCompleteL( TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount )
//------------------------------------------------------------
void CNSmlBTServiceSearcher::NextRecordRequestCompleteL( TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount )
{
if ( aError == KErrEof )
{
Finished();
return;
}
if ( aError != KErrNone )
{
Finished( aError );
return;
}
if ( aTotalRecordsCount == 0 )
{
Finished( KErrNotFound );
return;
}
// Request its attributes
iAgent->AttributeRequestL( aHandle, KSdpAttrIdProtocolDescriptorList );
}
//------------------------------------------------------------
// CNSmlBTServiceSearcher::AttributeRequestResult()
//------------------------------------------------------------
void CNSmlBTServiceSearcher::AttributeRequestResult(
TSdpServRecordHandle aHandle,
TSdpAttributeID aAttrID,
CSdpAttrValue* aAttrValue)
{
TRAPD( error, AttributeRequestResultL( aHandle, aAttrID, aAttrValue ) );
//deleted because ownership has been transferred
delete aAttrValue;
aAttrValue = NULL;
if( error != KErrNone )
{
Panic(EBTServiceSearcherAttributeRequestResult);
}
}
//------------------------------------------------------------
// CNSmlBTServiceSearcher::AttributeRequestResultL()
//------------------------------------------------------------
void CNSmlBTServiceSearcher::AttributeRequestResultL(
TSdpServRecordHandle /*aHandle*/,
TSdpAttributeID aAttrID,
CSdpAttrValue* aAttrValue)
{
ASSERT( aAttrID == KSdpAttrIdProtocolDescriptorList );
TSdpAttributeParser parser( ProtocolList(), *this );
// Validate the attribute value, and extract the RFCOMM channel
aAttrValue->AcceptVisitorL( parser );
if ( parser.HasFinished() )
{
// Found a suitable record so change state
iHasFoundService = ETrue;
}
}
//------------------------------------------------------------
// CNSmlBTServiceSearcher::AttributeRequestComplete()
//------------------------------------------------------------
void CNSmlBTServiceSearcher::AttributeRequestComplete(TSdpServRecordHandle aHandle, TInt aError)
{
TRAPD( error, AttributeRequestCompleteL( aHandle, aError ) );
if( error != KErrNone )
{
Panic( EBTServiceSearcherAttributeRequestComplete );
}
}
//------------------------------------------------------------
// CNSmlBTServiceSearcher::AttributeRequestCompleteL()
//------------------------------------------------------------
void CNSmlBTServiceSearcher::AttributeRequestCompleteL(TSdpServRecordHandle /*aHandle*/, TInt aError)
{
if ( aError != KErrNone )
{
}
else if( !HasFinishedSearching() )
{
// have not found a suitable record so request another
iAgent->NextRecordRequestL();
}
else
{
Finished();
}
}
//------------------------------------------------------------
// CNSmlBTServiceSearcher::Finished()
//------------------------------------------------------------
void CNSmlBTServiceSearcher::Finished(TInt aError /* default = KErrNone */)
{
if( aError == KErrNone && !HasFoundService() )
{
aError = KErrNotFound;
}
if ( iStatusObserver )
{
if ( *iStatusObserver == KRequestPending )
{
User::RequestComplete( iStatusObserver, aError );
}
}
}
//------------------------------------------------------------
// CNSmlBTServiceSearcher::HasFinishedSearching()
//------------------------------------------------------------
TBool CNSmlBTServiceSearcher::HasFinishedSearching() const
{
return EFalse;
}
//------------------------------------------------------------
// CNSmlBTServiceSearcher::BTDevAddr()
//------------------------------------------------------------
const TBTDevAddr& CNSmlBTServiceSearcher::BTDevAddr()
{
return iResponse().BDAddr();
}
//------------------------------------------------------------
// CNSmlBTServiceSearcher::ResponseParams()
//------------------------------------------------------------
const TBTDeviceResponseParams& CNSmlBTServiceSearcher::ResponseParams()
{
return iResponse();
}
//------------------------------------------------------------
// CNSmlBTServiceSearcher::HasFoundService()
//------------------------------------------------------------
TBool CNSmlBTServiceSearcher::HasFoundService() const
{
return iHasFoundService;
}