bluetoothengine/headsetsimulator/remotecontroller/src/hsremotecontroller.cpp
branchheadsetsimulator
changeset 60 90dbfc0435e3
--- /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
+    }
+