diff -r 02103bf20ee5 -r 90dbfc0435e3 bluetoothengine/headsetsimulator/core/src/hscore.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetoothengine/headsetsimulator/core/src/hscore.cpp Wed Sep 15 15:59:44 2010 +0200 @@ -0,0 +1,909 @@ +/* + * 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 "hscore.h" +#include "hsprofilemanager.h" +#include "hsobserver.h" +#include "hsserver.h" +#include "hsaudioserver.h" +#include "hsclientmanager.h" +#include "hsclient.h" +#include "hstools.h" +#include "hsremotecontrolserver.h" +#include "debug.h" + +EXPORT_C CHsCore* CHsCore::NewL( const TUUID& aService ) + { + CHsCore* self = CHsCore::NewLC( aService ); + CleanupStack::Pop( self ); + return self; + } + +EXPORT_C CHsCore* CHsCore::NewLC( const TUUID& aService ) + { + CHsCore* self = new ( ELeave ) CHsCore( aService ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +EXPORT_C CHsCore::~CHsCore() + { + TRACE_FUNC_ENTRY + + DestroyComponents(); + iSocketServ.Close(); + + TRACE_FUNC_EXIT + } + +CHsCore::CHsCore( const TUUID& aService ) : + iService( aService ) + { + + } + +void CHsCore::ConstructL() + { + TRACE_FUNC_ENTRY + + User::LeaveIfError( iSocketServ.Connect() ); + CreateComponentsL(); + RegisterProperty(); + InitializeSimulationL(); + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsCore::StartSimulationL( const TUid& aCoDUid, + const TUid& aSdpUid, const TUid& aProfileUid, const TDesC& aBTName ) + { + TRACE_FUNC_ENTRY + + InitializeSimulationL( aBTName ); + + LoadSdpL( aSdpUid ); + LoadCodL( aCoDUid ); + LoadProfileL( aProfileUid ); + + User::LeaveIfError( StartHSServer() ); + User::LeaveIfError( StartAudioServer( ETrue ) ); + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsCore::StartSimulationL( const TDesC8& aCoDName, + const TDesC8& aSdpName, const TDesC8& aProfileName, + const TDesC& aBTName ) + { + TRACE_FUNC_ENTRY + + InitializeSimulationL( aBTName ); + + LoadSdpL( aSdpName ); + LoadCodL( aCoDName ); + LoadProfileL( aProfileName ); + + User::LeaveIfError( StartHSServer() ); + User::LeaveIfError( StartAudioServer( ETrue ) ); + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsCore::StopSimulation() + { + TRACE_FUNC_ENTRY + DestroyPluginManager(); + DestroyClientManager(); + DestroyHSServer(); + DestroyAudioServer(); + + CreateHSServer(); + CreateAudioServer( ETrue ); + CreateClientManager(); + CreatePluginManager(); + + TRAP_IGNORE(InitializeSimulationL()); + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsCore::ConnectWithName( const TDesC &aName ) + { + TRACE_FUNC_ENTRY + if ( iObserver ) + { + iObserver->HandleConnectingToClient(); + } + if ( iHsBTManager ) + { + TRAPD(err, iHsBTManager->FindNameL(aName)); + if ( err != KErrNone && iObserver ) + { + iObserver->HandleUnableToConnectClient(); + } + TRACE_INFO((_L("Connect with name: %S, error = %d"), &aName, err)) + } + else if ( iObserver ) + { + iObserver->HandleUnableToConnectClient(); + } + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsCore::ConnectWithDevAddress( const TDesC& aDevAddress ) + { + TRACE_FUNC_ENTRY + if ( iObserver ) + { + iObserver->HandleConnectingToClient(); + } + if ( iHsBTManager ) + { + TRAPD(err, iHsBTManager->FindDevL(aDevAddress)); + if ( err != KErrNone && iObserver ) + { + iObserver->HandleUnableToConnectClient(); + } + } + else if ( iObserver ) + { + iObserver->HandleUnableToConnectClient(); + } + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsCore::ConnectWithLastConnectedL() + { + TRACE_FUNC_ENTRY + + TBTDevAddr addr; + User::LeaveIfError( GetLastConnected( addr ) ); + + RBuf lastDevAddrBuf; + + lastDevAddrBuf.CreateL( KMaxBluetoothNameLen ); + addr.GetReadable( lastDevAddrBuf ); + + ConnectWithDevAddress( lastDevAddrBuf ); + + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsCore::CancelConnecting() + { + TRACE_FUNC_ENTRY + if ( iHsBTManager ) + { + iHsBTManager->CancelConnecting(); + } + TRACE_FUNC_EXIT + } + +EXPORT_C void CHsCore::DisconnectClients() + { + TRACE_FUNC_ENTRY + if ( iHSClientManager ) + { + iHSClientManager->DisconnectClients(); + } + TRACE_FUNC_EXIT + } + +EXPORT_C TInt CHsCore::Send( const TDesC8 &aData, TInt aNumber ) + { + TRACE_FUNC_ENTRY + TInt ret = KErrNone; + if ( iHSClientManager && iHSProfileManager ) + { + TBuf8 tmp; + + TRAP(ret, iHSProfileManager->HandleCommandL(aData, tmp, EFalse)); + if ( KErrNone == ret ) + { + ret = iHSClientManager->Send( tmp, aNumber ); + } + } + else + { + ret = KErrNotReady; + } + TRACE_FUNC_EXIT + return ret; + } + +EXPORT_C void CHsCore::SetObserver( MHsObserver& aObserver ) + { + TRACE_FUNC_ENTRY + iObserver = &aObserver; + TRACE_FUNC_EXIT + } + +EXPORT_C TInt CHsCore::AcceptIncomingCall() + { + TRACE_FUNC_ENTRY + + TBuf8 tmp; + TRAPD(ret,iHSProfileManager->AcceptIncomingCallL(tmp)); + + if ( KErrNone == ret ) + { + ret = iHSClientManager->Send( tmp ); + } + + TRACE_FUNC_EXIT + return ret; + } + +EXPORT_C TInt CHsCore::ReleaseOngoingCall() + { + TBuf8 tmp; + TRAPD(ret,iHSProfileManager->ReleaseOngoingCallL(tmp)); + + if ( KErrNone == ret ) + { + ret = iHSClientManager->Send( tmp ); + } + + TRACE_FUNC_EXIT + return ret; + } + +void CHsCore::InitializeSimulationL( const TDesC& aBTName ) + { + TRACE_FUNC_ENTRY + + User::LeaveIfNull( iHsBTManager ); + if ( aBTName != KNullDesC ) + { + SetBTName( aBTName ); + iHsBTManager->TurnBtOnL( aBTName ); + } + else + { + iHsBTManager->TurnBtOnL(); + } + + TRACE_FUNC_EXIT + } + +void CHsCore::RegisterProperty() + { + TRACE_FUNC_ENTRY + // Return value may be ignored, no influence on main Headset functionality + RProperty::Define( KHSProperty, ELastDevice, RProperty::EByteArray, + KLastDevAddrLength ); + + TRACE_FUNC_EXIT + } + +void CHsCore::CreateComponentsL() + { + TRACE_FUNC_ENTRY + User::LeaveIfError( CreateControlServer() ); + User::LeaveIfError( CreateHSServer() ); + User::LeaveIfError( CreateAudioServer( ETrue ) ); + User::LeaveIfError( CreateClientManager() ); + User::LeaveIfError( CreatePluginManager() ); + User::LeaveIfError( CreateBTManager() ); + + TRACE_FUNC_EXIT + } + +void CHsCore::DestroyComponents() + { + TRACE_FUNC_ENTRY + + DestroyControlServer(); + DestroyPluginManager(); + DestroyClientManager(); + DestroyHSServer(); + DestroyAudioServer(); + DestroyBTManager(); + + TRACE_FUNC_EXIT + } + +TInt CHsCore::CreateHSServer() + { + TRACE_FUNC_ENTRY + TInt ret = KErrNone; + + if ( !iHSServer ) + { + TRAP(ret, iHSServer = CHsServer::NewL(iSocketServ)); + + if ( ret == KErrNone ) + { + iHSServer->SetNewClientObserver( *this ); + } + } + else + { + ret = KErrAlreadyExists; + } + + TRACE_FUNC_EXIT + return ret; + } + +TInt CHsCore::StartHSServer() + { + TRACE_FUNC_ENTRY + + TInt ret = KErrNone; + if ( !iHSServer ) + { + ret = KErrNotReady; + } + else + { + if ( !iHSServer->IsReady() ) + { + ret = iHSServer->Listen(); + } + else + { + ret = KErrInUse; + } + } + + if ( ret == KErrNone && iHSProfileManager ) + { + iHSProfileManager->SetSdpServicePort( iHSServer->GetPort() ); + iHSProfileManager->RefreshSdp(); + } + + TRACE_FUNC_EXIT + return ret; + } + +void CHsCore::StopHSServer() + { + TRACE_FUNC_ENTRY + if ( ( iHSServer ) && ( iHSServer->IsReady() ) ) + { + iHSServer->Shutdown(); + } + + TRACE_FUNC_EXIT + } + +void CHsCore::DestroyHSServer() + { + TRACE_FUNC_ENTRY + + if ( iHSServer ) + { + delete iHSServer; + iHSServer = NULL; + } + TRACE_FUNC_EXIT + } + +TInt CHsCore::CreateAudioServer( TBool aPullAudio ) + { + TRACE_FUNC_ENTRY + + TInt ret = KErrNone; + + if ( iAudioServer ) + { + ret = KErrAlreadyExists; + } + else + { + TRAP(ret, iAudioServer = CHsAudioServer::NewL(iSocketServ, aPullAudio)); + } + + TRACE_FUNC_EXIT + + return ret; + } + +TInt CHsCore::StartAudioServer( TBool aPullAudio ) + { + TRACE_FUNC_ENTRY + TInt ret = KErrNone; + + if ( iAudioServer && !iAudioServer->IsListen() + && !iAudioServer->IsConnected() ) + { + iAudioServer->SetPullAudio( aPullAudio ); + TRAP(ret, iAudioServer->ListenL()); + } + else + { + ret = KErrNotReady; + } + + TRACE_FUNC_EXIT + + return ret; + + } + +void CHsCore::StopAudioServer() + { + TRACE_FUNC_ENTRY + if ( iAudioServer ) + { + if ( iAudioServer->IsConnected() ) + { + iAudioServer->Disconnect(); + } + if ( iAudioServer->IsListen() ) + { + iAudioServer->Shutdown(); + } + } + TRACE_FUNC_EXIT + } + +void CHsCore::DestroyAudioServer() + { + TRACE_FUNC_ENTRY + + if ( iAudioServer ) + { + delete iAudioServer; + iAudioServer = NULL; + } + TRACE_FUNC_EXIT + } + +TInt CHsCore::CreateClientManager() + { + TRACE_FUNC_ENTRY + TInt err = KErrNone; + + if ( iHSClientManager ) + { + err = KErrAlreadyExists; + } + else + { + TRAP(err, iHSClientManager = CHsClientManager::NewL()); + } + TRACE_FUNC_EXIT + return err; + } + +void CHsCore::DestroyClientManager() + { + TRACE_FUNC_ENTRY + if ( iHSClientManager ) + { + delete iHSClientManager; + iHSClientManager = NULL; + } + TRACE_FUNC_EXIT + } + +TInt CHsCore::CreatePluginManager() + { + TRACE_FUNC_ENTRY + TInt err = KErrNone; + if ( iHSProfileManager ) + { + err = KErrAlreadyExists; + } + else + { + TRAP(err, iHSProfileManager = CHsProfileManager::NewL()); + } + TRACE_FUNC_EXIT + return err; + } + +void CHsCore::DestroyPluginManager() + { + TRACE_FUNC_ENTRY + + if ( iHSProfileManager ) + { + delete iHSProfileManager; + iHSProfileManager = NULL; + } + + TRACE_FUNC_EXIT + } + +TInt CHsCore::CreateBTManager() + { + TRACE_FUNC_ENTRY + TInt err = KErrNone; + + if ( !iHsBTManager ) + { + TRAP(err, iHsBTManager = CHsBTManager::NewL(iSocketServ, this)); + if ( err == KErrNone ) + { + iHsBTManager->SetService( iService ); + } + } + else + { + err = KErrAlreadyExists; + } + + TRACE_FUNC_EXIT + return err; + } + +void CHsCore::DestroyBTManager() + { + TRACE_FUNC_ENTRY + if ( iHsBTManager ) + { + delete iHsBTManager; + iHsBTManager = NULL; + } + TRACE_FUNC_EXIT + } + +TInt CHsCore::CreateControlServer() + { + TRACE_FUNC_ENTRY + TInt err = KErrNone; + if ( !iHSControlServer ) + { + TRAP(err, iHSControlServer = CHsControlServer::NewL(iSocketServ, this); + iHSControlServer->SetConnectionObserver( *this ); + iHSControlServer->StartRemoteControlServerL()); + } + else + { + err = KErrAlreadyExists; + } + TRACE_FUNC_EXIT + return err; + } + +void CHsCore::DestroyControlServer() + { + TRACE_FUNC_ENTRY + if ( iHSControlServer ) + { + delete iHSControlServer; + iHSControlServer = NULL; + } + TRACE_FUNC_EXIT + + } + +void CHsCore::SetBTName( const TBTFriendlyName &aBTName ) + { + iBTFriendlyName = aBTName; + } + +TInt CHsCore::GetLastConnected( TBTDevAddr &aBTDevAddr ) + { + TRACE_FUNC_ENTRY + RBuf bufAddr; + TInt error = bufAddr.Create( KLastDevAddrLength ); + if ( KErrNone != error ) + { + + return error; + } + + error = RProperty::Get( KHSProperty, ELastDevice, bufAddr ); + TRACE_INFO( (_L("Last-connected dev addr: %S"), &bufAddr) ) + if ( error == KErrNone ) + { + error = aBTDevAddr.SetReadable( bufAddr ); + + } + bufAddr.Close(); + TRACE_FUNC_EXIT + return error; + } + +TInt CHsCore::SaveClient( CBluetoothSocket* aSocket ) + { + TRACE_FUNC_ENTRY + TInt error = KErrNone; + TBTSockAddr sockAddr; + aSocket->RemoteName( sockAddr ); + + TBTDevAddr devAddr = sockAddr.BTAddr(); + + RBuf bufAddr; + + error = bufAddr.Create( KLastDevAddrLength ); + if ( KErrNone == error ) + { + devAddr.GetReadable( bufAddr ); + TRACE_INFO( (_L("Read address:: %S"), &bufAddr) ); + error = RProperty::Set( KHSProperty, ELastDevice, bufAddr ); + bufAddr.Close(); + } + + TRACE_FUNC_EXIT + return error; + } + +void CHsCore::SetSdpRecordServicePortFromServer() + { + TRACE_FUNC_ENTRY + if ( iHSServer && iHSProfileManager ) + { + iHSProfileManager->SetSdpServicePort( iHSServer->GetPort() ); + } + TRACE_FUNC_EXIT + } + +void CHsCore::LoadProfileL( const TDesC8& aProfileName ) + { + TRACE_FUNC_ENTRY + + User::LeaveIfNull( iHSProfileManager ); + iHSProfileManager->LookupAndManageProfileL( aProfileName ); + + TRACE_FUNC_EXIT + } + +void CHsCore::LoadProfileL( const TUid& aProfileUid ) + { + TRACE_FUNC_ENTRY + + User::LeaveIfNull( iHSProfileManager ); + iHSProfileManager->LookupAndManageProfileL( aProfileUid ); + + TRACE_FUNC_EXIT + } + +void CHsCore::LoadSdpL( const TDesC8& aSdpName ) + { + TRACE_FUNC_ENTRY + + User::LeaveIfNull( iHSProfileManager ); + + SetSdpRecordServicePortFromServer(); + iHSProfileManager->LookupAndManageSdpL( aSdpName ); + TRACE_INFO(_L("iHSProfileManager lookup and manage SDP success") ); + + iHSProfileManager->LoadSdpL(); + + TRACE_FUNC_EXIT + } + +void CHsCore::LoadSdpL( const TUid& aSdpUid ) + { + TRACE_FUNC_ENTRY + User::LeaveIfNull( iHSProfileManager ); + + SetSdpRecordServicePortFromServer(); + iHSProfileManager->LookupAndManageSdpL( aSdpUid ); + TRACE_INFO(_L("iHSProfileManager lookup and manage SDP success") ); + + iHSProfileManager->LoadSdpL(); + + TRACE_FUNC_EXIT + } + +void CHsCore::LoadCodL( const TDesC8& aCoDName ) + { + TRACE_FUNC_ENTRY + + User::LeaveIfNull( iHSProfileManager ); + + iHSProfileManager->LookupAndManageCodL( aCoDName ); + iHSProfileManager->LoadCodL(); + + TRACE_FUNC_EXIT + } + +void CHsCore::LoadCodL( const TUid& aCoDUid ) + { + TRACE_FUNC_ENTRY + + User::LeaveIfNull( iHSProfileManager ); + + iHSProfileManager->LookupAndManageCodL( aCoDUid ); + iHSProfileManager->LoadCodL(); + + TRACE_FUNC_EXIT + } + +void CHsCore::HandleNewClientL( CBluetoothSocket* aClientSocket, TInt aErr ) + { + TRACE_FUNC_ENTRY + + if ( ( KErrNone == aErr ) && ( iHSClientManager ) ) + { + CHsClient *clientTmp = NULL; + if ( aClientSocket ) + { + clientTmp = CHsClient::NewL( aClientSocket, this, iHSClientManager ); + + //Return value may be ignored + SaveClient( aClientSocket ); + iHSClientManager->HandleNewClientL( clientTmp, aErr ); + + TBuf8 tmp; + + iHSProfileManager->HandleClientConnected( tmp ); + if ( tmp.Compare( KNullDesC8 ) != 0 ) + { + iHSClientManager->Send( tmp, KHsDefaultClientNumber ); + } + + if ( iObserver ) + { + iObserver->HandleConnectedToClient(); + } + } + } + else + { + if ( iHsBTManager ) + { + iHsBTManager->CancelConnecting(); + } + if ( iObserver ) + { + iObserver->HandleUnableToConnectClient(); + } + } + + TRACE_FUNC_EXIT + } + +void CHsCore::HandleClientConnectL( TInt aErr ) + { + TRACE_FUNC_ENTRY + TRACE_INFO( (_L("aErr = %d"), aErr)) + + TRACE_FUNC_EXIT + } + +void CHsCore::HandleClientDisconnectL( TInt aErr ) + { + TRACE_FUNC_ENTRY + TRACE_INFO( (_L("aErr = %d"), aErr)) + + if ( iObserver ) + { + iObserver->HandleDisconnectedFromClient(); + } + if ( iAudioServer ) + { + iAudioServer->ListenL(); + } + if ( iHSProfileManager ) + { + iHSProfileManager->HandleClientDisconnected( aErr ); + } + + TRACE_FUNC_EXIT + } + +void CHsCore::HandleClientReceiveCompleteL( const TDesC8 &aData, TInt aErr ) + { + TRACE_FUNC_ENTRY + TRACE_INFO( (_L("aErr = %d"), aErr)) + + if ( iHSProfileManager ) + { + iBufferFromProfileToClient.Zero(); + + TRACE_INFO( (_L8(" Received data from AG client [%S]") , &aData) ) + iHSProfileManager->HandleCommandL( aData, iBufferFromProfileToClient, + ETrue ); + + if ( iHSClientManager ) + { + iHSClientManager->Send( iBufferFromProfileToClient ); + } + } + TRACE_FUNC_EXIT + } +void CHsCore::HandleClientSendCompleteL( TInt aErr ) + { + TRACE_FUNC_ENTRY + TRACE_INFO( (_L("aErr = %d"), aErr)) + + TRACE_FUNC_EXIT + } + +void CHsCore::HandleClientOtherProblemL( TInt aErr ) + { + TRACE_FUNC_ENTRY + TRACE_INFO( (_L("aErr = %d"), aErr)) + + TRACE_FUNC_EXIT + } + +void CHsCore::HandleDesiredDeviceFound( const TDesC& /*aDevName*/, + const TBTDevAddr& aDevAddr, const TInt aPort ) + { + TRACE_FUNC_ENTRY + TBTSockAddr sockaddr; + sockaddr.SetBTAddr( aDevAddr ); + sockaddr.SetPort( aPort ); + TRAPD(err, iHSServer->GetSocketAndTryToConnectL(sockaddr)); + if ( err != KErrNone ) + { + TRACE_INFO( (_L("CHsServer::GetSocketAndTryToConnectL() error = %d"), err) ) + TRAP_IGNORE( HandleNewClientL(NULL, err)); + + } + + TRACE_FUNC_EXIT + } + +void CHsCore::HandleSdpQueryError( TInt aErr ) + { + TRACE_FUNC_ENTRY + TRACE_INFO( (_L("aErr = %d"), aErr)) + if ( iObserver ) + { + iObserver->HandleUnableToConnectClient(); + } + TRACE_FUNC_EXIT + } + +void CHsCore::HandleServiceNotFound( TInt aErr ) + { + TRACE_FUNC_ENTRY + TRACE_INFO( (_L("aErr = %d"), aErr)) + if ( iObserver ) + { + iObserver->HandleUnableToConnectClient(); + } + TRACE_FUNC_EXIT + } + +void CHsCore::HandlePortNotFound( TInt aErr ) + { + TRACE_FUNC_ENTRY + TRACE_INFO( (_L("aErr = %d"), aErr)) + if ( iObserver ) + { + iObserver->HandleUnableToConnectClient(); + } + TRACE_FUNC_EXIT + } + +void CHsCore::HandleDesiredDeviceNotFound( TInt aErr ) + { + TRACE_FUNC_ENTRY + TRACE_INFO( (_L("aErr = %d"), aErr)) + if ( iObserver ) + { + iObserver->HandleUnableToConnectClient(); + } + TRACE_FUNC_EXIT + } + +void CHsCore::HandleRemoteControllerConnected( TInt aErr ) + { + TRACE_FUNC_ENTRY + if ( iObserver && aErr == KErrNone ) + { + iObserver->HandleConnectedToRemoteController(); + } + TRACE_FUNC_EXIT + } + +void CHsCore::HandleRemoteControllerDisconnected( TInt /** aErr */) + { + TRACE_FUNC_ENTRY + if ( iObserver ) + { + iObserver->HandleDisconnectedFromRemoteController(); + } + TRACE_FUNC_EXIT + }