diff -r 02103bf20ee5 -r 90dbfc0435e3 bluetoothengine/headsetsimulator/remotecontroller/src/hsremotecontroller.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetoothengine/headsetsimulator/remotecontroller/src/hsremotecontroller.cpp Wed Sep 15 15:59:44 2010 +0200 @@ -0,0 +1,522 @@ +/* + * Component Name: Headset Simulator + * Author: Comarch S.A. + * Version: 1.0 + * Copyright (c) 2010 Comarch S.A. + * + * This Software is submitted by Comarch S.A. to Symbian Foundation Limited on + * the basis of the Member Contribution Agreement entered between Comarch S.A. + * and Symbian Foundation Limited on 5th June 2009 (“Agreement”) and may be + * used only in accordance with the terms and conditions of the Agreement. + * Any other usage, duplication or redistribution of this Software is not + * allowed without written permission of Comarch S.A. + * + */ + +#include "hsremotecontroller.h" +#include "hsrcbttools.h" +#include "hsrccommand.h" +#include "debug.h" + +EXPORT_C CHsRemoteController* CHsRemoteController::NewL( + MHsRCObserver* aObserver ) + { + CHsRemoteController* self = CHsRemoteController::NewLC( aObserver ); + CleanupStack::Pop( self ); + return self; + } + +EXPORT_C CHsRemoteController* CHsRemoteController::NewLC( + MHsRCObserver* aObserver ) + { + CHsRemoteController* self = new ( ELeave ) CHsRemoteController( aObserver ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +EXPORT_C CHsRemoteController::~CHsRemoteController() + { + TRACE_FUNC_ENTRY + if ( iBTManager ) + { + delete iBTManager; + } + + if ( iSocket ) + { + if ( iConnected ) + { + iSocket->CancelAll(); + // Return value may be ignored + iSocket->Shutdown( RSocket::EImmediate ); + } + delete iSocket; + } + + iSocketServ.Close(); + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsRemoteController::ConnectHsDevAddrL( + const TBTDevAddr& aDevAddr, const TUUID& aService ) + { + TRACE_FUNC_ENTRY + if ( iConnected ) + { + User::Leave( KErrInUse ); + } + if ( iObserver ) + { + iObserver->HandleConnectingToHs(); + } + iBTManager->SetService( aService ); + + iBTManager->ConnectDevAddrL( aDevAddr ); + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsRemoteController::ConnectHsDevNameL( const TDesC& aHsName, + const TUUID& aService ) + { + TRACE_FUNC_ENTRY + if ( iConnected ) + { + User::Leave( KErrInUse ); + } + if ( iObserver ) + { + iObserver->HandleConnectingToHs(); + } + iBTManager->SetService( aService ); + iBTManager->ConnectDevNameL( aHsName ); + + TRACE_FUNC_EXIT + + } + +EXPORT_C void CHsRemoteController::CancelConnectingToHs() + { + TRACE_FUNC_ENTRY + if ( iBTManager ) + { + iBTManager->CancelConnecting(); + } + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsRemoteController::DisconnectFromHs() + { + TRACE_FUNC_ENTRY + if ( iSocket ) + { + if ( iConnected ) + { + iSocket->CancelAll(); + // Return value may be ignored + iSocket->Shutdown( RSocket::EImmediate ); + } + delete iSocket; + iSocket = NULL; + iConnected = EFalse; + if ( iObserver ) + { + iObserver->HandleDisconnectedFromHs( KErrNone ); + } + + } + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsRemoteController::ReqTurnOnHs( const TDesC& aPluginCod, + const TDesC& aPluginSdp, const TDesC& aPluginProfile ) + { + TRACE_FUNC_ENTRY + + __ASSERT_ALWAYS( iConnected, + User::Panic(KHSRemoteControllerNotConnectedPanicMsg, KErrNotReady)); + + RBuf buf; + TRAPD(err, buf.CreateL( aPluginCod.Length() + aPluginSdp.Length() + + aPluginProfile.Length() + 4 ) ); + if ( err == KErrNone ) + { + TBuf <2> sep; + CnvUtfConverter::ConvertToUnicodeFromUtf8( sep, + KHsRemoteRequestParamSeparator ); + + buf.Copy( aPluginCod ); + buf.Append( sep ); + buf.Append( aPluginSdp ); + buf.Append( sep ); + buf.Append( aPluginProfile ); + + SendRequest( EHsTurnOn, buf ); + } + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsRemoteController::ReqTurnOffHs() + { + TRACE_FUNC_ENTRY + + __ASSERT_ALWAYS( iConnected, + User::Panic(KHSRemoteControllerNotConnectedPanicMsg, KErrNotReady)); + + SendRequest( EHsTurnOff ); + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsRemoteController::ReqConnectWithDevAddr( + const TBTDevAddr& aDevAddr ) + { + TRACE_FUNC_ENTRY + + __ASSERT_ALWAYS( iConnected, + User::Panic(KHSRemoteControllerNotConnectedPanicMsg, KErrNotReady)); + + TBuf devAddrBuf; + aDevAddr.GetReadable( devAddrBuf ); + SendRequest( EHsConnectDevAddress, devAddrBuf ); + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsRemoteController::ReqConnectWithDevName( + const TDesC& aDevName ) + { + TRACE_FUNC_ENTRY + + __ASSERT_ALWAYS( iConnected, + User::Panic(KHSRemoteControllerNotConnectedPanicMsg, KErrNotReady)); + SendRequest( EHsConnectName, aDevName ); + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsRemoteController::ReqConnectWithLastConnected() + { + TRACE_FUNC_ENTRY + + __ASSERT_ALWAYS( iConnected, + User::Panic(KHSRemoteControllerNotConnectedPanicMsg, KErrNotReady)); + + SendRequest( EHsConnectLastconnected ); + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsRemoteController::ReqAcceptCall() + { + TRACE_FUNC_ENTRY + + __ASSERT_ALWAYS( iConnected, + User::Panic(KHSRemoteControllerNotConnectedPanicMsg, KErrNotReady)); + SendRequest( EHsAcceptCall ); + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsRemoteController::ReqReleaseCall() + { + TRACE_FUNC_ENTRY + + __ASSERT_ALWAYS( iConnected, + User::Panic(KHSRemoteControllerNotConnectedPanicMsg, KErrNotReady)); + SendRequest( EHsReleaseCall ); + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsRemoteController::ReqSetMicGain( const TDesC& aValue ) + { + TRACE_FUNC_ENTRY + + __ASSERT_ALWAYS( iConnected, + User::Panic(KHSRemoteControllerNotConnectedPanicMsg, KErrNotReady)); + SendRequest( EHsSetMicVolume, aValue ); + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsRemoteController::ReqSetSpeakerVolume( const TDesC& aValue ) + { + TRACE_FUNC_ENTRY + + __ASSERT_ALWAYS( iConnected, + User::Panic(KHSRemoteControllerNotConnectedPanicMsg, KErrNotReady)); + + SendRequest( EHsSetSpeakerVolume, aValue ); + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsRemoteController::ReqSendAnyAt( const TDesC& aValue ) + { + TRACE_FUNC_ENTRY + + __ASSERT_ALWAYS( iConnected, + User::Panic(KHSRemoteControllerNotConnectedPanicMsg, KErrNotReady)); + SendRequest( EHsSendAnyAt, aValue ); + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsRemoteController::ReqDisconnectAG() + { + TRACE_FUNC_ENTRY + + __ASSERT_ALWAYS( iConnected, + User::Panic(KHSRemoteControllerNotConnectedPanicMsg, KErrNotReady)); + SendRequest( EHsDisconnectAGs ); + + TRACE_FUNC_EXIT + } + +CHsRemoteController::CHsRemoteController( MHsRCObserver* aObserver ) : + iObserver( aObserver ) + { + + } + +void CHsRemoteController::ConstructL() + { + User::LeaveIfError( iSocketServ.Connect() ); + User::LeaveIfError( CreateBTManager() ); + } + +void CHsRemoteController::SendRequest( + const THsRemoteControlCommandType aCommandType, const TDesC& aData ) + { + TRACE_FUNC_ENTRY + + THsRCCommandData data( KNullDesC8 ); + TInt err = CnvUtfConverter::ConvertFromUnicodeToUtf8( data, aData ); + if ( err == KErrNone ) + { + THsRCCommand cmd( data, aCommandType ); + cmd.ToDes8( iSendDataBuffer ); + + err = Send( iSendDataBuffer ); + if ( ( err == KErrNone ) && iObserver ) + { + iObserver->HandleRequestSent( aCommandType ); + } + } + TRACE_FUNC_EXIT + } + +TInt CHsRemoteController::Send( const TDesC8& aData ) + { + TRACE_FUNC_ENTRY + TRACE_INFO( ( _L8("Data to be send: [%S]"), &aData) ) + + if ( !iConnected ) + { + TRACE_INFO( _L("Not connected to HS") ) + TRACE_FUNC_EXIT + return KErrNotReady; + } + + iSendDataBuffer.Copy( aData ); + if ( iSendDataBuffer.Length() > 0 ) + { + TInt err = iSocket->Write( iSendDataBuffer ); + if ( err == KErrNone ) + { + iSendDataBuffer.Zero(); + } + + TRACE_FUNC_EXIT + return err; + } + + TRACE_FUNC_EXIT + + return KErrNone; + } + +void CHsRemoteController::Receive() + { + TRACE_FUNC_ENTRY + // Return value may be ignored, + // error will be notified to HandleReceiveCompleteL + iSocket->RecvOneOrMore( iReceiveDataBuffer, 0, iDataLength ); + TRACE_FUNC_EXIT + } + +TInt CHsRemoteController::ConnectRemoteControlServer( const TBTDevAddr& aAddr, + const TInt aPort ) + { + TRACE_FUNC_ENTRY + TInt error = KErrNone; + if ( !iConnected ) + { + + TProtocolDesc protocolDesc; + error = iSocketServ.FindProtocol( _L("RFCOMM"), protocolDesc ); + if ( error != KErrNone ) + { + TRACE_INFO( ( _L("iSocketServ.FindProtocol error = %d"), error) ) + TRACE_FUNC_EXIT + return error; + } + + TRAP(error, iSocket = CBluetoothSocket::NewL(*this, iSocketServ, + protocolDesc.iSockType, protocolDesc.iProtocol)); + if ( error != KErrNone ) + { + TRACE_INFO( ( _L("iSocket = CBluetoothSocket::NewL error = %d"), error)) + TRACE_FUNC_EXIT + return error; + } + + TBTSockAddr addr; + addr.SetBTAddr( aAddr ); + addr.SetPort( aPort ); + error = iSocket->Connect( addr ); + + if ( error != KErrNone ) + { + TRACE_INFO( ( _L("iSocket->Connect error = %d"), error)) + TRACE_FUNC_EXIT + return error; + } + } + else + { + TRACE_INFO( _L("CHsRemoteController::Connect() - client is already connected") ) + TRACE_FUNC_EXIT + return KErrInUse; + } + + TRACE_FUNC_EXIT + return KErrNone; + } + +TInt CHsRemoteController::CreateBTManager() + { + TInt err = KErrNone; + + if ( !iBTManager ) + { + TRAP(err, iBTManager = CHsRCBTManager::NewL(iSocketServ, this)); + if ( err != KErrNone ) + { + iBTManager = NULL; + } + return err; + } + else + { + return KErrAlreadyExists; + } + + } + +void CHsRemoteController::HandleConnectCompleteL( TInt aErr ) + { + TRACE_FUNC_ENTRY + TRACE_INFO( ( _L("aErr = %d"), aErr) ) + + if ( aErr == KErrNone ) + { + TRACE_INFO(_L("Connect completed")) + iConnected = ETrue; + Receive(); + } + if ( iObserver ) + { + iObserver->HandleConnectedToHs( aErr ); + } + TRACE_FUNC_EXIT + } + +void CHsRemoteController::HandleAcceptCompleteL( TInt /*aErr*/) + { + } + +void CHsRemoteController::HandleShutdownCompleteL( TInt /*aErr*/) + { + } + +void CHsRemoteController::HandleSendCompleteL( TInt aErr ) + { + TRACE_FUNC_ENTRY + TRACE_INFO( ( _L("aErr = %d"), aErr) ) + + if ( aErr == KErrNone ) + { + if ( ( iSendDataBuffer.Length() > 0 ) && ( ( iSocket->Write( + iSendDataBuffer ) ) == KErrNone ) ) + { + iSendDataBuffer.Zero(); + } + } + Receive(); + TRACE_FUNC_EXIT + } + +void CHsRemoteController::HandleReceiveCompleteL( TInt aErr ) + { + TRACE_FUNC_ENTRY + TRACE_INFO( ( _L("aErr = %d"), aErr) ) + + if ( aErr == KErrNone ) + { + if ( ( iSendDataBuffer.Length() > 0 ) && ( ( iSocket->Write( + iSendDataBuffer ) ) == KErrNone ) ) + { + iSendDataBuffer.Zero(); + } + Receive(); + } + else + { + TRACE_INFO(_L("ControlServer cancelled listening")); + DisconnectFromHs(); + } + } + +void CHsRemoteController::HandleIoctlCompleteL( TInt /*aErr*/) + { + } + +void CHsRemoteController::HandleActivateBasebandEventNotifierCompleteL( + TInt /*aErr*/, TBTBasebandEventNotification& /*aEventNotification*/) + { + } + +void CHsRemoteController::HandleDesiredDevFound( const TDesC& aDevName, + const TBTDevAddr& aDevAddr, const TInt aPort ) + { + TRACE_FUNC_ENTRY + //value ignored + TInt err = ConnectRemoteControlServer( aDevAddr, aPort ); + + TRACE_INFO((_L("err = %d"), err)) + + if ( iObserver && err != KErrNone ) + { + iObserver->HandleConnectedToHs( err ); + } + TRACE_FUNC_EXIT + } + +void CHsRemoteController::HandleDesiredDevNotFound( TInt aErr ) + { + TRACE_FUNC_ENTRY + + if ( iObserver ) + { + iObserver->HandleConnectedToHs( aErr ); + } + + TRACE_FUNC_EXIT + } +