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