⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 e32btclientengine.cpp

📁 symbian s60上的GPS
💻 CPP
字号:
//system include
#include <BtExtNotifiers.h>
#include <BtManClient.h>
#include <E32Math.h>
#include <F32File.h>

//use include
#include "E32BtClientEngine.h"
#include "BtDataListener.h"

const TInt KSerialUUID = 0x1101; //GPS UID

_LIT( KRFCap, "RFCOMM" );

enum TState 
{
	EStateNotConnected,
	EStateDiscovering,
	EStateQuerying,
	EStateQueried,
	EStateConnecting,
	EStateReadingData
};


CE32BtClientEngine * CE32BtClientEngine::NewL( void ) 
{
	CE32BtClientEngine * self = new ( ELeave ) CE32BtClientEngine( );
	CleanupStack::PushL( self );
	self->ConstructL( );
	CleanupStack::Pop( );
	return( self );
}

CE32BtClientEngine::CE32BtClientEngine( void ) 
:CActive( EPriorityStandard ) 
{
	iStateMachine		= EStateNotConnected;
	iRemoteChannel		= 255;
}

CE32BtClientEngine::~CE32BtClientEngine( void ) 
{
	Cancel();
	iFs.Close();
	iTimer.Close();
	iSocket.Close();

	delete( iSdpAgent );
}



void CE32BtClientEngine::ConstructL( void ) 
{
	//连接到系统服务
	User::LeaveIfError( iFs.Connect() );
	User::LeaveIfError( iSocketServ.Connect() );

	//定时器检测数据文件
	iTimer.CreateLocal();

	CActiveScheduler::Add( this );

	//寻找GPS设备
	DiscoverRemoteL();
}



void CE32BtClientEngine::RunL( void ) 
{
	//状态机
	switch( iStateMachine )
	{
	case EStateDiscovering:
		DiscoveredRemoteL( );
		QueryRemoteL( );
		break;
	case EStateQueried:
		ConnectRemoteL( );
		break;
	case EStateConnecting:
		ReadDataL( );
		break;
	case EStateReadingData:
		NotifyListener( );
		ReadDataL( );
		break;
	}
}



void CE32BtClientEngine::DoCancel( void ) 
{
	iTimer.Cancel( );
}



void CE32BtClientEngine::DiscoverRemoteL( void ) 
{
	// Connect to the RNotifier
	User::LeaveIfError( iNotifier.Connect( ) );

	// Look for devices with services with our UUID
	TBTDeviceSelectionParams filterParams;
	TBTDeviceSelectionParamsPckg fpPckg( filterParams );
	TUUID targetServiceClass( KSerialUUID );
	filterParams.SetUUID( targetServiceClass );

	// Start the notifier. The response will be in iDiscoveryResponse
	iNotifier.StartNotifierAndGetResponse( iStatus,
		KDeviceSelectionNotifierUid, fpPckg, iDiscoveryResponse );

	// Change the state
	iStateMachine = EStateDiscovering;

	SetActive();
}



void CE32BtClientEngine::DiscoveredRemoteL( void ) 
{
	// Close the notifier
	iNotifier.CancelNotifier( KDeviceSelectionNotifierUid );
	iNotifier.Close( );

	// If the result is not a valid Bluetooth address,
	// leave with KErrGeneral. Otherwise copy the address
	// of the remote device.
	if( iDiscoveryResponse( ).IsValidBDAddr( ) )
		iRemoteAddr.SetBTAddr( iDiscoveryResponse( ).BDAddr( ) );
	else
		User::Leave( KErrGeneral );
}



void CE32BtClientEngine::QueryRemoteL( void ) 
{
	// Create agent.
	iSdpAgent = CSdpAgent::NewL( *this, iRemoteAddr.BTAddr( ) );

	// Create a search pattern and add a service classes to it
	CSdpSearchPattern * list = CSdpSearchPattern::NewL( );
	  list->AddL( KSerialUUID );

	// Set the search pattern on the agent
	iSdpAgent->SetRecordFilterL( *list );

	// Get first search result: results in call back to this
	iSdpAgent->NextRecordRequestL( );

	// Advance the state machine
	iStateMachine = EStateQuerying;
}



void CE32BtClientEngine::QueriedRemote( void ) 
{
	// Just advance the state machine
	iStateMachine = EStateQueried;

	// Continue immediately
	SetActive();

	TRequestStatus * status = &iStatus;
	User::RequestComplete( status, KErrNone );
}



void CE32BtClientEngine::ConnectRemoteL( void ) 
{
	// If we have a proper remote channel, connect to the remote.
	if( iRemoteChannel != 255 ) {

		TProtocolDesc protocolDesc;

		// Get protocol information on RFCOMM
		User::LeaveIfError( iSocketServ.FindProtocol( KRFCap( ), protocolDesc ) );

		// Open socket
		User::LeaveIfError( iSocket.Open( iSocketServ, protocolDesc.iAddrFamily, 
			protocolDesc.iSockType, protocolDesc.iProtocol ) );

		// Connect to remote
		iRemoteAddr.SetPort( iRemoteChannel );
		iSocket.Connect( iRemoteAddr, iStatus );

		// Advance state machine
		iStateMachine = EStateConnecting;
		SetActive( );
	}
}



void CE32BtClientEngine::ReadDataL( void ) 
{
	// If the connect went fine, iStatus will contain KErrNone.
	if( iStatus == KErrNone ) 
	{

        // Allocate memory for the actual data and wait for it.
		iSocket.RecvOneOrMore( iDataBuffer, 0, iStatus, iDataLength );

        // Advance the state machine
        iStateMachine = EStateReadingData;
        SetActive();
	}
}



void CE32BtClientEngine::NotifyListener( void ) 
{
	// If the read went fine, iStatus will contain KErrNone.
	if( iStatus == KErrNone )
		iListener->DataUpdate( iDataBuffer );
}



void CE32BtClientEngine::CloseRemoteL( void ) 
{
	// Close the remote channel.
	// Also removes the data file.
	iSocket.Close( );
}



void CE32BtClientEngine::NextRecordRequestComplete( TInt aError, TSdpServRecordHandle aHandle, TInt /*aTotalRecordsCount*/ ) 
{
	// We got a service record.
	if ( aError != KErrNone ) 
	{
		// Some error
		QueriedRemote( );
	} 
	else 
	{
		// Ask for the contents of the record

		// Create a match list
		CSdpAttrIdMatchList * matchList = CSdpAttrIdMatchList::NewL( );
		CleanupStack::PushL( matchList );

		// Add an attribute ID to get
		matchList->AddL( TAttrRange( KSdpAttrIdProtocolDescriptorList ) );

		// Set the match list on the agent
		iSdpAgent->AttributeRequestL( aHandle, KSdpAttrIdProtocolDescriptorList );

		CleanupStack::PopAndDestroy( ); // matchList
	}
}



void CE32BtClientEngine::AttributeRequestResult( TSdpServRecordHandle /*aHandle*/, TSdpAttributeID aAttrID, CSdpAttrValue * aAttrValue) 
{
	// We got the contents. Use an attribute visitor to parse the results.
	if( aAttrID == KSdpAttrIdProtocolDescriptorList )
		aAttrValue->AcceptVisitorL( *this );
}

void CE32BtClientEngine::AttributeRequestComplete(	TSdpServRecordHandle /*aHandle*/, TInt /*aError*/ ) 
{

	// Request complete. Announce that we're done
	// to the state machine.
	QueriedRemote( );
}

void CE32BtClientEngine::VisitAttributeValueL( CSdpAttrValue & aValue, TSdpElementType aType ) 
{
	// This will be called for each attribute received. It just waits for attributes
	// of certain type and parses them. All other attributes are ignored.
	switch( aType ) 
	{
	case ETypeUUID:
		iPreviousUUID = aValue.UUID();
		break;
	case ETypeUint:
		if( iPreviousUUID == KRFCOMM )
			iRemoteChannel = aValue.Uint();
		break;
	default:
		break;
	}
}



void CE32BtClientEngine::StartListL( CSdpAttrValueList & /*aList*/ ) 
{
	// We don't need to know about lists
}



void CE32BtClientEngine::EndListL( ) 
{
	// We don't need to know about lists
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -