--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/btsac/src/btsaController.cpp Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,684 @@
+/*
+* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Implementation for CBTSAController class. This class is advertised
+* to E-com framework (@see proxy.cpp) so that it loads this class when
+* this plugin gets loaded. That is why this class implements the interface
+* of the module (currently BT Accessory Server) which loads this plugin.Being
+* main class, this class constructs other classes and also recieves callbacks,
+* hence implementing their interfaces.
+*
+*/
+
+
+// INCLUDE FILES
+#include "btsaController.h"
+#include "btsacactive.h"
+#include "btsacStateIdle.h"
+#include "btsacStateListening.h"
+#include "btsacStreamerController.h"
+#include "btsacSEPManager.h"
+#include "btsacGavdp.h"
+#include "debug.h"
+#include <e32property.h>
+#include "btaudioremconpskeys.h"
+
+_LIT_SECURITY_POLICY_C1( KPSKeyReadPolicy,
+ ECapabilityLocalServices);
+_LIT_SECURITY_POLICY_C1( KPSKeyWritePolicy,
+ ECapabilityLocalServices);
+
+// CONSTANTS
+
+// MODULE DATA STRUCTURES
+
+// ================= MEMBER FUNCTIONS =======================
+
+// -----------------------------------------------------------------------------
+// CBTSAController::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CBTSAController* CBTSAController::NewL(TPluginParams& aParams)
+ {
+ CBTSAController* self = new (ELeave) CBTSAController(aParams);
+ CleanupStack::PushL(self);
+ self->ConstructL( );
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CBTSAController::~CBTSAController()
+ {
+ TRACE_FUNC
+ if(iStreamingSockets.Count())
+ {
+ TRACE_INFO((_L("[SOCKET] closed.")))
+ iStreamingSockets[0].Close();
+ }
+ iStreamingSockets.Close();
+ delete iStreamer;
+ delete iGavdp;
+ delete iState;
+ delete iGavdpErrorActive;
+ delete iLocalSEPs;
+ delete iRemoteSEPs;
+ iAccDb.ResetAndDestroy();
+ iAccDb.Close();
+ RProperty::Delete( KBTAudioRemCon, KBTAudioPlayerControl );
+ TRACE_INFO((_L("CBTSAController::~CBTSAController() completed")))
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::CBTSAController
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+CBTSAController::CBTSAController(TPluginParams& aParams)
+ : CBTAccPlugin(aParams)
+ {
+ TRACE_FUNC
+ }
+
+
+// -----------------------------------------------------------------------------
+// CBTSAController::ConstructL
+// Symbian 2nd phase constructor.
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::ConstructL()
+ {
+ TRACE_FUNC_ENTRY
+ CBtsacState* state = CBtsacIdle::NewL(*this);
+ CleanupStack::PushL(state);
+ iStreamer = CBTSACStreamerController::NewL(*this);
+ // Initially idle state is registered as observer of GAVDP
+ iGavdp = CBTSACGavdp::NewL(state);
+ iLocalSEPs = CBTSACSEPManager::NewL(TBTDevAddr());
+ iGavdpErrorActive = CBtsacActive::NewL(*this, CActive::EPriorityStandard, KRequestIdGavdpError);
+ ChangeStateL(state);
+ CleanupStack::Pop(state);
+
+ ResetRemoteCache();
+
+ TInt err = RProperty::Define( KBTAudioRemCon,
+ KBTAudioPlayerControl, RProperty::EInt,
+ KPSKeyReadPolicy,
+ KPSKeyWritePolicy );
+ TRACE_INFO((_L("PS define err %d"), err))
+ TRACE_FUNC_EXIT
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::ChangeStateL
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::ChangeStateL(CBtsacState* aState)
+ {
+ TRACE_FUNC_ENTRY
+ TRACE_ASSERT(!!aState, EBTPanicNullPointer);
+ if(iState)
+ {
+ if(aState->GetStateIndex() == iState->GetStateIndex())
+ {
+ // We already are in desired state, delete the state which came in and return
+ TRACE_INFO((_L("CBTSAController::ChangeStateL(), already in desired state.")))
+ delete aState;
+ return;
+ }
+ }
+ CBtsacState *CurrentState = iState;
+ iState = aState;
+ TInt err = KErrNone;
+ TRAP(err, iState->EnterL());
+ if (err)
+ {
+ ChangeStateL(iState->ErrorOnEntryL(err));
+ }
+ delete CurrentState;
+ TRACE_FUNC_EXIT
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::ResetRemoteCache
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::ResetRemoteCache()
+ {
+ TRACE_FUNC
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::InitializeSEPManager
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::InitializeSEPManager()
+ {
+ TRACE_FUNC
+ iSBCSEPIndex = 0; // SBC SEP Index in iRemoteSEPs array
+ if( iRemoteSEPs )
+ {
+ delete iRemoteSEPs;
+ iRemoteSEPs = NULL;
+ }
+ TRAPD(ret, iRemoteSEPs = CBTSACSEPManager::NewL(iRemoteAddr));
+ if (ret)
+ {
+ TRACE_INFO((_L("CBTSAController::InitializeSEPManager(), ERROR")))
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::CleanSockets
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::CleanSockets()
+ {
+ TRACE_FUNC
+ if(iStreamingSockets.Count())
+ {
+ // Close possible streaming socket(s)
+ TRACE_INFO((_L("[SOCKET] closed.")))
+ iStreamingSockets[0].Close();
+ iStreamingSockets.Remove(0);
+ iStreamingSockets.Reset();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::PluginType
+// -----------------------------------------------------------------------------
+//
+TProfiles CBTSAController::PluginType()
+ {
+ TRACE_FUNC
+ return EStereo;
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::ConnectToAccessory
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::ConnectToAccessory(const TBTDevAddr& aAddr, TRequestStatus& aStatus)
+ {
+ TRACE_FUNC_ENTRY
+ TRACE_INFO_SEG(
+ {TBuf<KBTDevAddrReadable> buf; aAddr.GetReadable(buf);
+ Trace(_L("[REQUEST] Connect request, BT Addr %S"), &buf);})
+ iConnectStatus = &aStatus;
+ aStatus = KRequestPending;
+ TRAPD(err, iState->ConnectL(aAddr));
+ if (err)
+ {
+ CompletePendingRequests(KConnectReq, err);
+ }
+ TRACE_FUNC_EXIT
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::CancelConnectToAccessory
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::CancelConnectToAccessory(const TBTDevAddr& aAddr)
+ {
+ TRACE_FUNC_ENTRY
+ TRACE_INFO_SEG(
+ {TBuf<KBTDevAddrReadable> buf; aAddr.GetReadable(buf); Trace(_L("BT Addr %S"), &buf);})
+ if (aAddr != iRemoteAddr)
+ {
+ TRACE_INFO((_L("CBTSAController::CancelConnectToAccessory() Invalid address, error.")))
+ CompletePendingRequests(KConnectReq, KErrArgument);
+ return;
+ }
+ TRAP_IGNORE(iState->CancelConnectL());
+ TRACE_FUNC_EXIT
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::DisconnectAccessory
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::DisconnectAccessory(const TBTDevAddr& aAddr, TRequestStatus& aStatus)
+ {
+ TRACE_FUNC_ENTRY
+ TRACE_INFO_SEG(
+ {TBuf<KBTDevAddrReadable> buf; aAddr.GetReadable(buf);
+ Trace(_L("[REQUEST] Disconnect request, BT Addr %S"), &buf);})
+
+ // if we have an open/close audio request pending, complete it
+ CompletePendingRequests((KOpenAudioReq | KCloseAudioReq), KErrDisconnected);
+ iDisconnectStatus = &aStatus;
+ aStatus = KRequestPending;
+ if (aAddr != iRemoteAddr )
+ {
+ TRACE_INFO((_L("CBTSAController::DisconnectAccessory() Invalid address, error.")))
+ CompletePendingRequests(KDisconnectReq, KErrArgument);
+ return;
+ }
+ TRAPD(err, iState->DisconnectL());
+ if (err)
+ {
+ CompletePendingRequests(KDisconnectReq, err);
+ return;
+ }
+ SetResetAudioInput(ETrue);
+ TRACE_FUNC_EXIT
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::OpenAudioLink
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::OpenAudioLink(const TBTDevAddr& aAddr, TRequestStatus& aStatus)
+ {
+ TRACE_FUNC_ENTRY
+ TRACE_INFO_SEG(
+ {TBuf<KBTDevAddrReadable> buf; aAddr.GetReadable(buf);
+ Trace(_L("[REQUEST] Open audio request, BT Addr %S"), &buf);})
+ iOpenAudioStatus = &aStatus;
+ aStatus = KRequestPending;
+ TRAPD(err, iState->OpenAudioLinkL(aAddr));
+ if (err)
+ {
+ CompletePendingRequests(KOpenAudioReq, err);
+ }
+ TRACE_FUNC_EXIT
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::CancelOpenAudioLink
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::CancelOpenAudioLink(const TBTDevAddr& aAddr)
+ {
+ TRACE_FUNC_ENTRY
+ TRACE_INFO_SEG(
+ {TBuf<KBTDevAddrReadable> buf; aAddr.GetReadable(buf); Trace(_L("BT Addr %S"), &buf);})
+ if(aAddr != iRemoteAddr)
+ {
+ TRACE_INFO((_L("CBTSAController::CancelOpenAudioLink() Invalid address, error.")))
+ CompletePendingRequests(KOpenAudioReq, KErrArgument);
+ return;
+ }
+ if(IsOpenAudioReqFromAccFWPending())
+ {
+ TRAP_IGNORE(iState->CancelOpenAudioLinkL());
+ }
+ TRACE_FUNC_EXIT
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::CloseAudioLink
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::CloseAudioLink(const TBTDevAddr& aAddr, TRequestStatus& aStatus)
+ {
+ TRACE_FUNC_ENTRY
+ TRACE_INFO_SEG(
+ {TBuf<KBTDevAddrReadable> buf; aAddr.GetReadable(buf);
+ Trace(_L("[REQUEST] Close audio request, BT Addr %S"), &buf);})
+ iCloseAudioStatus = &aStatus;
+ aStatus = KRequestPending;
+ TRAPD(err, iState->CloseAudioLinkL(aAddr));
+ if (err)
+ {
+ CompletePendingRequests(KCloseAudioReq, err);
+ }
+ TRACE_FUNC_EXIT
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::CancelCloseAudioLink
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::CancelCloseAudioLink(const TBTDevAddr& aAddr)
+ {
+ TRACE_FUNC_ENTRY
+ TRACE_INFO_SEG(
+ {TBuf<KBTDevAddrReadable> buf; aAddr.GetReadable(buf); Trace(_L("BT Addr %S"), &buf);})
+ if(aAddr != iRemoteAddr)
+ {
+ TRACE_INFO((_L("CBTSAController::CancelCloseAudioLink() Invalid address, error.")))
+ CompletePendingRequests(KCloseAudioReq, KErrArgument);
+ return;
+ }
+ if(iCloseAudioStatus)
+ {
+ iState->CancelCloseAudioLink(aAddr);
+ }
+ TRACE_FUNC_EXIT
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::AccInUse
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::AccInUse()
+ {
+ TRACE_FUNC
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::StartRecording
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::StartRecording()
+ {
+ TRACE_FUNC
+ iState->StartRecording();
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::StoreAccInfo
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::StoreAccInfo()
+ {
+ TRACE_FUNC
+ iAccDb.Append(iRemoteSEPs);
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::DeleteAccInfo
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::DeleteAccInfo()
+ {
+ TRACE_FUNC
+ for(TInt i = 0 ; i < iAccDb.Count() ; i++)
+ {
+ iAccDb.Remove(i);
+ }
+ iAccDb.Reset();
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::IsAccInfoAvailable
+// -----------------------------------------------------------------------------
+//
+TBool CBTSAController::IsAccInfoAvailable()
+ {
+ TRACE_INFO((_L("CBTSAController::IsAccInfoAvailable() Count: %d"), iAccDb.Count()))
+ for (TInt i=0; i<iAccDb.Count(); i++)
+ {
+ CBTSACSEPManager* SM = iAccDb[i];
+ if ( SM->GetDeviceAddr() == iRemoteAddr )
+ {
+ iRemoteSEPs = iAccDb[i]; // retrieve SEP Manager
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::AbortStream
+// -----------------------------------------------------------------------------
+//
+TInt CBTSAController::AbortStream()
+ {
+ TRACE_FUNC
+ TAvdtpSEPInfo SEPInfo;
+ if (iRemoteSEPs->GetInfo(iSBCSEPIndex, SEPInfo))
+ {
+ TRACE_INFO((_L("CBTSAController::AbortStream() Couldn't retrieve SEP Info !")))
+ return KErrGeneral;
+ }
+ TSEID remoteSEPid = SEPInfo.SEID();
+ iGavdp->AbortStreaming(remoteSEPid);
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::NewAccessory
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::NewAccessory(const TBTDevAddr& aAddr)
+ {
+ TRACE_FUNC
+ TInt connectedProfiles = Observer().ConnectionStatus( aAddr );
+ if( !(connectedProfiles & EStereo) )
+ {
+ Observer().NewAccessory( aAddr, EStereo );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::DisconnectedFromRemote
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::DisconnectedFromRemote(const TBTDevAddr& aAddr, TInt /*aError*/)
+ {
+ TRACE_FUNC
+ Observer().AccessoryDisconnected(aAddr, EStereo );
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::AccessoryOpenedAudio
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::AccessoryOpenedAudio(const TBTDevAddr& aBDAddr)
+ {
+ TRACE_FUNC
+ Observer().RemoteAudioOpened(aBDAddr, EStereo );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CBTSAController::AccessoryClosedAudio
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::AccessoryClosedAudio(const TBTDevAddr& aBDAddr)
+ {
+ TRACE_FUNC
+ Observer().RemoteAudioClosed(aBDAddr, EStereo );
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::AccessorySuspendedAudio
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::AccessorySuspendedAudio(const TBTDevAddr& aBDAddr)
+ {
+ TRACE_FUNC
+ RProperty::Set(KBTAudioRemCon, KBTAudioPlayerControl, EBTAudioPausePlayer);
+ Observer().RemoteAudioClosed(aBDAddr, EStereo );
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::CompletePendingRequests
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::CompletePendingRequests(TUint aCompleteReq, TInt aError)
+ {
+ TRACE_INFO((_L("CBTSAController::CompletePendingRequests() Request %d"), aCompleteReq))
+
+ if((aCompleteReq & KConnectReq) && iConnectStatus)
+ {
+ TRACE_INFO((_L("[REQUEST] Connect request completed with %d"), aError))
+ User::RequestComplete(iConnectStatus, aError);
+ }
+ if((aCompleteReq & KDisconnectReq) && iDisconnectStatus)
+ {
+ TRACE_INFO((_L("[REQUEST] Disconnect request completed with %d"), aError))
+ User::RequestComplete(iDisconnectStatus, aError);
+ }
+ if((aCompleteReq & KOpenAudioReq) && iOpenAudioStatus)
+ {
+ TRACE_INFO((_L("[REQUEST] Open audio request completed with %d"), aError))
+ User::RequestComplete(iOpenAudioStatus, aError);
+ }
+ if((aCompleteReq & KCloseAudioReq) && iCloseAudioStatus)
+ {
+ TRACE_INFO((_L("[REQUEST] Close audio request completed with %d"), aError))
+ User::RequestComplete(iCloseAudioStatus, KErrNone); // audio sw cant handle error codes.
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::SetRemoteAddr
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::SetRemoteAddr(const TBTDevAddr& aRemoteAddr)
+ {
+ iRemoteAddr = aRemoteAddr;
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::GetRemoteAddr
+// -----------------------------------------------------------------------------
+//
+TBTDevAddr CBTSAController::GetRemoteAddr() const
+ {
+ return iRemoteAddr;
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::IsOpenAudioReqFromAccFWPending
+// -----------------------------------------------------------------------------
+//
+TBool CBTSAController::IsOpenAudioReqFromAccFWPending() const
+ {
+ if(iOpenAudioStatus)
+ return ETrue;
+ else
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::SetSEPIndex
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::SetSEPIndex(TInt aIndex)
+ {
+ iSBCSEPIndex = aIndex;
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::GetSEPIndex
+// -----------------------------------------------------------------------------
+//
+TInt CBTSAController::GetSEPIndex() const
+ {
+ return iSBCSEPIndex;
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::SetResetAudioInput
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::SetResetAudioInput(TBool aReset)
+ {
+ iResetAudioInput = aReset;
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::GetResetAudioInput
+// -----------------------------------------------------------------------------
+//
+TBool CBTSAController::GetResetAudioInput() const
+ {
+ return iResetAudioInput;
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::GetGavdpErrorActive
+// -----------------------------------------------------------------------------
+//
+CBtsacActive* CBTSAController::GetGavdpErrorActive() const
+ {
+ return iGavdpErrorActive;
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::NotifyError
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::NotifyError(TInt /*aError*/)
+ {
+ TRACE_FUNC
+ if(iState->GetStateIndex() == EStateStreaming)
+ {
+ TRAP_IGNORE(iState->CloseAudioLinkL(GetRemoteAddr()));
+ }
+ else
+ {
+ TRAPD(err, ChangeStateL(CBtsacListening::NewL(*this, EGavdpResetReasonGeneral, EFalse)));
+ if (err)
+ {
+ TRACE_INFO((_L("CBTSAController::NotifyError() Couldn't change state.")))
+ }
+ }
+ CompletePendingRequests(KCompleteAllReqs, KErrCancel);
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::GAVDP_Error
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::GAVDP_Error(TInt aError)
+ {
+ TRACE_INFO((_L("CBTSAController::GAVDP_Error(%d)"), aError))
+ if(iGavdpErrorActive)
+ {
+ if (!iGavdpErrorActive->IsActive())
+ {
+ TRequestStatus* sta = &(iGavdpErrorActive->iStatus);
+ iGavdpErrorActive->iStatus = KRequestPending;
+ User::RequestComplete(sta, aError);
+ iGavdpErrorActive->GoActive();
+ }
+ }
+ else
+ {
+ TRACE_INFO((_L("CBTSAController::CBTSAController() AO doesn't exist.")))
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::RequestCompletedL
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::RequestCompletedL(CBtsacActive& aActive)
+ {
+ TRACE_FUNC
+ switch(aActive.RequestId())
+ {
+ case KRequestIdGavdpError:
+ {
+ iState->HandleGavdpErrorL(aActive.iStatus.Int());
+ break;
+ }
+ default:
+ {
+ TRACE_INFO((_L("CBTSAController::RequestCompletedL() Unknown request")))
+ break;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBTSAController::CancelRequest
+// -----------------------------------------------------------------------------
+//
+void CBTSAController::CancelRequest(CBtsacActive& /*aActive*/)
+ {
+ TRACE_FUNC
+ }
+
+// End of File