--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmserv/radioutility/radioserver/Server/Src/RadioServer.cpp Tue Feb 02 01:08:46 2010 +0200
@@ -0,0 +1,3293 @@
+/*
+* Copyright (c) 2002-2004 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: This is the main implementation of radio server.
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <mmf/common/mmfstandardcustomcommands.h>
+#include <centralrepository.h>
+#include <coreapplicationuissdkcrkeys.h>
+#include <audiopreference.h>
+
+#include "RadioServer.h"
+#include "RadioServerSession.h"
+#include "RadioServerShutdown.h"
+#include "RadioServerSettings.h"
+#include "RadioServerFmTuner.h"
+#include "RadioDebug.h"
+
+// CONSTANTS
+const TInt KFMDefaultFreq = 87500000; // 87.5 MHz
+const TInt KJapaneseFMDefaultFreq = 76000000; // 76.0 MHz
+
+#ifndef RD_FM_RADIO_ENHANCEMENTS
+const TInt KEuroAmericaMin = 87500000;
+const TInt KEuroAmericaMax = 108000000;
+const TInt KJapanMin = 76000000;
+const TInt KJapanMax = 90000000;
+#endif //#ifdef RD_FM_RADIO_ENHANCEMENTS
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CRadioServer::CRadioServer
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CRadioServer::CRadioServer()
+ : CServer2(CActive::EPriorityStandard),
+ iState(EStateStarted),
+ iSessionCount(0),
+ iSessionCountPrimary(0),
+ iShutdownTimer(NULL),
+ iSettings(NULL),
+ iTunerControlObserver(NULL),
+ iTunerControl(NULL),
+ iRdsControl(NULL),
+ iDevSound(NULL),
+ iRepository(NULL),
+ iCenRepNotifyHandler(NULL),
+ iAsyncRequestQue(_FOFF( TRadioMessageRequestData, iLink )),
+ iAsyncRequest(NULL),
+ iSyncRequestQue(_FOFF( TRadioMessageRequestData, iLink )),
+ iSyncRequest(NULL),
+ iMaxSigStrength(0),
+ iEnableTunerInOffline(EFalse),
+ iSquelch(EFalse),
+ iPreEmpted(EFalse)
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ConstructL()
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ConstructL() - Start"));
+
+ StartL(KRadioServerName);
+
+ iDevSound = CMMFDevSound::NewL();
+ TMMFPrioritySettings prioritySettings;
+ prioritySettings.iPriority = (TInt)KAudioPriorityFMRadio;
+ prioritySettings.iPref = (TMdaPriorityPreference)KAudioPrefRadioAudioEvent;
+ iDevSound->SetPrioritySettings(prioritySettings);
+
+ // Sign up for offline mode status notification and get the latest status
+ iRepository = CRepository::NewL(KCRUidCoreApplicationUIs);
+ iCenRepNotifyHandler = CCenRepNotifyHandler::NewL(*this, *iRepository,
+ CCenRepNotifyHandler::EIntKey, KCoreAppUIsNetworkConnectionAllowed);
+ iCenRepNotifyHandler->StartListeningL();
+ TInt value;
+ TBool offlineMode = EFalse;
+ iRepository->Get(KCoreAppUIsNetworkConnectionAllowed, value);
+ if ( (TCoreAppUIsNetworkConnectionAllowed)value == ECoreAppUIsNetworkConnectionNotAllowed )
+ {
+ offlineMode = ETrue;
+ }
+
+ // Assume Antenna is connected. Otherwise, initialization will handle it anyways.
+ // After that, RadioServer gets the antenna status notification from the tuner.
+ TBool antennaStatus = ETrue;
+
+ // Max volume won't change, so just make the server remember it locally.
+ iMaxVolume = iDevSound->MaxVolume();
+ TInt volume = iDevSound->Volume();
+ TInt left, right;
+ iDevSound->GetPlayBalanceL(left, right);
+
+ iSettings = CRadioServerSettings::NewL();
+ iSettings->SetAntennaStatus(antennaStatus, EFalse);
+ iSettings->SetOfflineModeStatus(offlineMode, EFalse);
+ iSettings->SetVolume(volume, EFalse);
+ iSettings->SetBalance(left, right, EFalse);
+
+ // Initiate shut down unless we get client connections
+ iShutdownTimer = CRadioServerShutdown::NewL();
+ iShutdownTimer->Start();
+#ifdef RD_TSP_CLIENT_MAPPER
+ iMapper = CTspClientMapper::NewL();
+ iTspState = CTspClientMapper::ERegisteredClients;
+#endif // RD_TSP_CLIENT_MAPPER
+
+ RADIO_RDEBUG(_L("[RADIO-SVR] ConstructL() - End"));
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CRadioServer* CRadioServer::NewL()
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] NewL"));
+ CRadioServer* self = new( ELeave ) CRadioServer;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// Destructor
+CRadioServer::~CRadioServer()
+ {
+ if ( iShutdownTimer )
+ {
+ iShutdownTimer->Cancel();
+ delete iShutdownTimer;
+ }
+ if ( iCenRepNotifyHandler )
+ {
+ iCenRepNotifyHandler->StopListening();
+ delete iCenRepNotifyHandler;
+ }
+ delete iRepository;
+
+ delete iDevSound;
+ delete iSettings;
+ delete iTunerControl;
+ delete iTunerControlObserver;
+ delete iAsyncRequest;
+
+ ClearQueue();
+ iRdsNotifyClientIdArray.Close();
+
+#ifdef RD_TSP_CLIENT_MAPPER
+ delete iMapper;
+ iClientPids.Close();
+#endif // RD_TSP_CLIENT_MAPPER
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::AddSession
+// This method increases the client session count, and cancels the shutdown timer.
+// The timer is reset once the last client has disconnected
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::AddSession()
+ {
+ if ( ++iSessionCount == 1 )
+ {
+ iShutdownTimer->Cancel();
+ iState = EStateStarted;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::DropSession
+// This method decrements the client session count, and if no clients are connected,
+// it initiates the shutdown timer.
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::DropSession()
+ {
+ if ( --iSessionCount == 0 )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] DropSession() - Radio OFF. State[%d]"), iState);
+ switch ( iState )
+ {
+ case EStateStarted:
+ case EStateTunerOff:
+ // Shutting down normally.
+ iState = EStateStarted;
+ iMaxSigStrength = 0;
+ iEnableTunerInOffline = EFalse;
+ delete iTunerControl;
+ iTunerControl = NULL;
+ ClearQueue();
+ iShutdownTimer->Start();
+ break;
+ case EStateTunerOn:
+ iState = EStateShutdown;
+ iTunerControl->TunerOff();
+ break;
+ case EStatePlaying:
+ iState = EStateShutdown;
+ iDevSound->Stop();
+ iTunerControl->TunerOff();
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ServiceRequestL
+// Main entry for Radio Server. If the cancel-request message is already outstanding,
+// just let it complete. Only allow for cancel if the message hasn't been initiated yet.
+// For all other requests, process the message if no other outstanding message exists.
+// Otherwise, queue the message. Execution order is guaranteed for all asynchronous
+// requests.
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ServiceRequestL(
+ const RMessage2& aMessage )
+ {
+ TRadioServerRequest req;
+ TRadioMessageRequestData* data = NULL;
+#ifdef RD_TSP_CLIENT_MAPPER
+ iMessageTsp = aMessage;
+#endif // RD_TSP_CLIENT_MAPPER
+ switch( aMessage.Function() )
+ {
+ case ERadioServAddPrimaryClient:
+ iSessionCountPrimary++;
+ RegisterClientPidL(aMessage);
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ServiceRequestL() prim=[%d]"), iSessionCountPrimary);
+ aMessage.Complete(KErrNone);
+ break;
+ case ERadioServRemovePrimaryClient:
+ aMessage.Complete(ProcessRemovePrimaryClientL(aMessage));
+ break;
+ case ERadioServGetTunerCapabilities:
+ aMessage.Complete(ProcessGetTunerCapabilities(aMessage));
+ break;
+ case ERadioServEnableTunerInOfflineMode:
+ aMessage.Complete(ProcessEnableTunerInOfflineMode(aMessage.Int1()));
+ break;
+ case ERadioServGetFrequencyRange:
+ aMessage.Complete(ProcessGetFrequencyRange(aMessage));
+ break;
+ case ERadioServGetFrequency:
+ aMessage.Complete(ProcessGetFrequency(aMessage));
+ break;
+ case ERadioServGetForceMonoReception:
+ aMessage.Complete(ProcessGetForceMonoReception(aMessage));
+ break;
+ case ERadioServSetSquelch:
+ aMessage.Complete(ProcessSetSquelch(aMessage.Int1()));
+ break;
+ case ERadioServGetSquelch:
+ aMessage.Complete(ProcessGetSquelch(aMessage));
+ break;
+ case ERadioServGetSignalStrength:
+ case ERadioServGetMaxSignalStrength:
+ case ERadioServGetStereoMode:
+ case ERadioServForceMonoReception:
+ // These requests are synchronous request from the client, however, the corresponding
+ // request to the tuner control is asynchronous. Therefore, these messages need to be
+ // serialized using a queue.
+ data = new (ELeave) TRadioMessageRequestData;
+ data->iType = (TRadioServerRequest) aMessage.Function();
+ data->iMessage = aMessage;
+ if ( iSyncRequest )
+ {
+ // Outstanding request exits; add it to the queue
+ iSyncRequestQue.AddLast(*data);
+ }
+ else
+ {
+ // No outstanding request; process the request
+ ProcessSyncRequest(data);
+ }
+ break;
+ case ERadioServGetPlayerState:
+ aMessage.Complete(ProcessGetPlayerState(aMessage));
+ break;
+ case ERadioServGetMaxVolume:
+ aMessage.Complete(ProcessGetMaxVolume(aMessage));
+ break;
+ case ERadioServSetVolume:
+ aMessage.Complete(ProcessSetVolume(aMessage.Int1()));
+ break;
+ case ERadioServGetVolume:
+ aMessage.Complete(ProcessGetVolume(aMessage));
+ break;
+ case ERadioServSetVolumeRamp:
+ aMessage.Complete(ProcessSetVolumeRamp(aMessage));
+ break;
+ case ERadioServSetMute:
+ aMessage.Complete(ProcessSetMute(aMessage.Int1()));
+ break;
+ case ERadioServGetMuteStatus:
+ aMessage.Complete(ProcessGetMuteStatus(aMessage));
+ break;
+ case ERadioServSetBalance:
+ aMessage.Complete(ProcessSetBalance(aMessage.Int1(), aMessage.Int2()));
+ break;
+ case ERadioServGetBalance:
+ aMessage.Complete(ProcessGetBalance(aMessage));
+ break;
+ case ERadioServRequestTunerControl:
+ case ERadioServSetFrequencyRange:
+ case ERadioServSetFrequency:
+ case ERadioServStationSeek:
+ case ERadioServPlay:
+ case ERadioServStop:
+ case ERadioServStationSeekByPTY:
+ case ERadioServStationSeekByTA:
+ case ERadioServStationSeekByTP:
+ // These requests are asynchronous request from the client. In order to guarantee the
+ // execution order these messages are serialized using a queue.
+ data = new (ELeave) TRadioMessageRequestData;
+ data->iType = (TRadioServerRequest) aMessage.Function();
+ data->iMessage = aMessage;
+ if ( iAsyncRequest )
+ {
+ // Outstanding request exits; add it to the queue
+ iAsyncRequestQue.AddLast(*data);
+ }
+ else
+ {
+ // No outstanding request; process the request
+ ProcessAsyncRequest(data);
+ }
+ break;
+ case ERadioServGetRdsCapabilities:
+ aMessage.Complete(ProcessGetRdsCapabilities(aMessage));
+ break;
+ case ERadioServGetRdsSignalStatus:
+ aMessage.Complete(ProcessGetRdsSignalStatus(aMessage));
+ break;
+ case ERadioServNotifyRdsDataChange:
+ aMessage.Complete(ProcessNotifyRdsDataChange(aMessage));
+ break;
+ case ERadioServCancelNotifyRdsDataChange:
+ aMessage.Complete(ProcessCancelNotifyRdsDataChange(aMessage));
+ break;
+ case ERadioServSetAutomaticSwitching:
+ aMessage.Complete(ProcessSetAutomaticSwitching(aMessage.Int1()));
+ break;
+ case ERadioServGetAutomaticSwitching:
+ aMessage.Complete(ProcessGetAutomaticSwitching(aMessage));
+ break;
+ case ERadioServCancelAFSearch:
+ aMessage.Complete(ProcessCancelAFSearch());
+ break;
+ case ERadioServGetProgrammeIdentification:
+ aMessage.Complete(ProcessGetProgrammeIdentification(aMessage));
+ break;
+ case ERadioServGetProgrammeType:
+ aMessage.Complete(ProcessGetProgrammeType(aMessage));
+ break;
+ case ERadioServGetProgrammeService:
+ aMessage.Complete(ProcessGetProgrammeService(aMessage));
+ break;
+ case ERadioServGetRadioText:
+ aMessage.Complete(ProcessGetRadioText(aMessage));
+ break;
+ case ERadioServGetClockTime:
+ aMessage.Complete(ProcessGetClockTime(aMessage));
+ break;
+ case ERadioServGetTrafficAnnouncementStatus:
+ aMessage.Complete(ProcessGetTrafficAnnouncementStatus(aMessage));
+ break;
+ case ERadioServGetTrafficProgrammeStatus:
+ aMessage.Complete(ProcessGetTrafficProgrammeStatus(aMessage));
+ break;
+ case ERadioServCancel:
+ req = (TRadioServerRequest) aMessage.Int1();
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ServiceRequestL(): Cancel[%d]"), req);
+ switch ( req )
+ {
+ case ERadioServRequestTunerControl:
+ case ERadioServSetFrequencyRange:
+ case ERadioServSetFrequency:
+ // If the message has already executed or is outstanding, just let it complete.
+ // If not, remove from queue.
+ RemoveFromQueue(iAsyncRequestQue, req);
+ aMessage.Complete(KErrNone);
+ break;
+ case ERadioServStationSeek:
+ case ERadioServStationSeekByPTY:
+ case ERadioServStationSeekByTA:
+ case ERadioServStationSeekByTP:
+ // If the request is outstanding, attempt to cancel since it can take a while
+ // to complete. Otherwise, just remove from the queue.
+ if ( iAsyncRequest && ( (iAsyncRequest->iType == ERadioServStationSeek) ||
+ (iAsyncRequest->iType == ERadioServStationSeekByPTY) ||
+ (iAsyncRequest->iType == ERadioServStationSeekByTA) ||
+ (iAsyncRequest->iType == ERadioServStationSeekByTP) ) )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ServiceRequestL() - Seek Outstanding"));
+ if ( iAsyncRequest->iType == ERadioServStationSeek )
+ {
+ iTunerControl->CancelStationSeek();
+ }
+ else
+ {
+ iRdsControl->CancelRdsStationSeek();
+ }
+ // Disable squelching, if on
+ if ( iSquelch )
+ {
+ // Restore the last volume
+ iDevSound->SetVolume(iSettings->Volume());
+ iSquelch = EFalse;
+ }
+ }
+ else
+ {
+ RemoveFromQueue(iAsyncRequestQue, req);
+ }
+ aMessage.Complete(KErrNone);
+ break;
+ default:
+ RADIO_RDEBUG(_L("[RADIO-SVR] ServiceRequestL(): default !!!"));
+ // Could be some custom command that we don't support.
+ aMessage.Complete(KErrNotSupported);
+ }
+ break;
+ default:
+ RADIO_RDEBUG(_L("[RADIO-SVR] ServiceRequestL(): default!!!"));
+ // Could be some custom command that we don't support.
+ aMessage.Complete(KErrNotSupported);
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::NewSessionL
+// This method decrements the client session count, and if no clients are connected,
+// it initiates the shutdown timer.
+// -----------------------------------------------------------------------------
+//
+CSession2* CRadioServer::NewSessionL(
+ const TVersion& aVersion,
+ const RMessage2& /*aMessage*/ ) const
+ {
+ // Test if the version specifies a repository session
+ const TVersion version(KRadioServerVersionMajor,
+ KRadioServerVersionMinor,
+ KRadioServerVersionBuild);
+ if ( !User::QueryVersionSupported(aVersion, version) )
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+ CRadioServerSession* session = CRadioServerSession::NewL(*((CRadioServer*)this));
+ return session;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::TunerOnComplete (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::TunerOnComplete(
+ TRadioServerError aError )
+ {
+ RADIO_RDEBUG_INT3(_L("[RADIO-SVR] TunerOnComplete(%d) State[%d] Trigger[%d]"), aError, iState, iTunerOnTrigger);
+ TFourCC radioFourCC;
+ switch ( iTunerOnTrigger )
+ {
+ case ETriggerTunerControl:
+ if ( aError == KErrNone )
+ {
+ TRsFrequencyRange range;
+ TInt minFreq, maxFreq;
+ if ( GetFrequencyRange(range, minFreq, maxFreq) == KErrNone )
+ {
+ RADIO_RDEBUG_INT3(_L("[RADIO-SVR] TunerOnComplete() - [%d, %d, %d]"), range, minFreq, maxFreq);
+ iSettings->SetFrequencyRange( range, minFreq, maxFreq, EFalse );
+ }
+ radioFourCC.Set(iTunerCaps.iEncoding);
+ TRAPD(err, iDevSound->InitializeL(*this, radioFourCC, EMMFStatePlaying));
+ if ( err != KErrNone )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] TunerOnComplete() DevSound err=[%d]"), err);
+ CompleteAsyncRequest(err);
+ }
+ }
+ else
+ {
+ CompleteAsyncRequest(aError);
+ }
+ break;
+ case ETriggerSetFrequency:
+ if ( aError == KErrNone )
+ {
+ iState = EStateTunerOn;
+ }
+ CompleteAsyncRequest(aError);
+ break;
+ case ETriggerSetFrequencyRange:
+ if ( aError == KErrNone )
+ {
+ iState = EStateTunerOn;
+ TRsFrequencyRange range;
+ TInt minFreq, maxFreq;
+ if ( GetFrequencyRange(range, minFreq, maxFreq) == KErrNone )
+ {
+ RADIO_RDEBUG_INT3(_L("[RADIO-SVR] TunerOnComplete() - [%d, %d, %d]"), range, minFreq, maxFreq);
+ iSettings->SetFrequencyRange( range, minFreq, maxFreq );
+ }
+ }
+ CompleteAsyncRequest(aError);
+ break;
+ case ETriggerPlay:
+ if ( aError == KErrNone )
+ {
+ TRAPD(err, DoPlayL());
+ if ( err == KErrNone )
+ {
+ iState = EStatePlaying;
+ iPreEmpted = EFalse;
+ iSettings->SetRadioOn();
+ SetTspTargetClient( ERsPlayerPlaying );
+ }
+ CompleteAsyncRequest(err);
+ }
+ else
+ {
+ CompleteAsyncRequest(aError);
+ }
+ break;
+ case ETriggerAntenna:
+ if ( aError == KErrNone )
+ {
+ iState = EStateTunerOn;
+ // AK - begin: to cause publishing (CPHU-73YTQW)
+ iSettings->SetAntennaStatus(EFalse, EFalse);
+ // - end
+ iSettings->SetAntennaStatus(ETrue);
+ }
+ // else
+ // Unable to turn the tuner back on. It's possible that after TunerOn request
+ // has been sent that antenna has been disconnected or the offline mode has
+ // been enabled again. Just remain here...
+ break;
+ case ETriggerOffline:
+ if ( aError == KErrNone )
+ {
+ iState = EStateTunerOn;
+ iSettings->SetOfflineModeStatus(EFalse);
+ }
+ // else
+ // Unable to turn the tuner back on. It's possible that after TunerOn request
+ // has been sent that antenna has been disconnected or the offline mode has
+ // been enabled again. Just remain here...
+ break;
+ case ETriggerTransmitter:
+ if ( aError == KErrNone )
+ {
+ iState = EStateTunerOn;
+ iSettings->SetTransmitterStatus(EFalse);
+ }
+ // else
+ // Unable to turn the tuner back on. It's possible that after TunerOn request
+ // has been sent that antenna has been disconnected or the offline mode has
+ // been enabled again. Just remain here...
+ break;
+ default:
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::TunerOffComplete (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::TunerOffComplete(
+ TRadioServerError aError )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] TunerOffComplete(%d) State[%d]"), aError, iState);
+ switch ( iState )
+ {
+ case EStateShutdown:
+ // We are shutting down normally. Called by destructor.
+ iState = EStateStarted;
+ iSettings->Reset();
+ iMaxSigStrength = 0;
+ iEnableTunerInOffline = EFalse;
+ delete iTunerControl;
+ iTunerControl = NULL;
+ ClearQueue();
+
+ if ( iSessionCount == 0 )
+ {
+ // Make sure a new session hasn't been started while TunerOff was being processed
+ iShutdownTimer->Start();
+ }
+ break;
+ case EStateTunerOff:
+ if ( iAsyncRequest && iAsyncRequest->iType == ERadioServSetFrequencyRange )
+ {
+ if ( aError == KErrNone )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] TunerOffComplete() - Tuner ON"));
+ RecreateFmTunerControl();
+ iTunerOnTrigger = ETriggerSetFrequencyRange;
+ TFMRadioFrequencyRange freqRange = TunerControlFreqRange( iFreqRange );
+ TInt freq = KFMDefaultFreq;
+ if ( iFreqRange == ERsRangeFmJapan )
+ {
+ freq = KJapaneseFMDefaultFreq;
+ }
+ iTunerControl->TunerOn(freqRange, freq);
+ }
+ else
+ {
+ CompleteAsyncRequest(aError);
+ }
+ }
+ break;
+ default:
+ // should never happen
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::SetFrequencyRangeComplete (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::SetFrequencyRangeComplete(
+ TRadioServerError aError )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] SetFrequencyRangeComplete(%d) State[%d]"), aError, iState);
+ if ( aError == KErrNone )
+ {
+ TRsFrequencyRange range;
+ TInt minFreq, maxFreq;
+ if ( GetFrequencyRange(range, minFreq, maxFreq) == KErrNone )
+ {
+ iSettings->SetFrequencyRange(range, minFreq, maxFreq);
+ }
+ else
+ {
+ iSettings->SetFrequencyRange(range, 0, 0);
+ }
+ }
+ CompleteAsyncRequest(aError);
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::SetFrequencyComplete (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::SetFrequencyComplete(
+ TRadioServerError aError )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] SetFrequencyComplete(%d) State[%d]"), aError, iState);
+ if ( iAsyncRequest && iAsyncRequest->iType == ERadioServSetFrequency )
+ {
+ if ( aError == KErrNone )
+ {
+ iSettings->SetFrequency(iAsyncRequest->iMessage.Int1());
+ }
+ CompleteAsyncRequest(aError);
+ }
+ else
+ {
+ // Synchronization initiated from StationSeekComplete(). Ignore.
+ RADIO_RDEBUG(_L("[RADIO-SVR] SetFrequencyComplete()-SYNC done!"));
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::StationSeekComplete (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::StationSeekComplete(
+ TRadioServerError aError,
+ TInt aFrequency )
+ {
+ RADIO_RDEBUG_INT3(_L("[RADIO-SVR] StationSeekComplete(%d, %d) State[%d]"), aError, aFrequency, iState);
+ if ( iAsyncRequest && ( (iAsyncRequest->iType == ERadioServStationSeek) ||
+ (iAsyncRequest->iType == ERadioServStationSeekByPTY) ||
+ (iAsyncRequest->iType == ERadioServStationSeekByTA) ||
+ (iAsyncRequest->iType == ERadioServStationSeekByTP) ) )
+ {
+ // Disable squelching, if on
+ if ( iSquelch )
+ {
+ // Restore the last volume
+ iDevSound->SetVolume(iSettings->Volume());
+ iSquelch = EFalse;
+ }
+
+ if ( aError == KErrNone )
+ {
+ iSettings->SetFrequency(aFrequency);
+ TPckgBuf<TInt> p(aFrequency);
+ iAsyncRequest->iMessage.Write(2, p);
+ }
+ CompleteAsyncRequest(aError);
+ }
+ else
+ {
+ // Request was cancelled. Make sure the frequency is synchronized.
+ if ( iSettings->Frequency() != aFrequency )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] StationSeekComplete()-SYNC to: Freq[%d]"), iSettings->Frequency());
+ iTunerControl->SetFrequency(iSettings->Frequency());
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::AudioModeComplete (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::AudioModeComplete(
+ TRadioServerError aError,
+ TBool aStereo )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] AudioModeComplete(%d, %d)"), aError, aStereo);
+ if ( iSyncRequest && iSyncRequest->iType == ERadioServGetStereoMode )
+ {
+ if ( aError == KErrNone )
+ {
+ TPckgBuf<TBool> p(aStereo);
+ iSyncRequest->iMessage.Write(1, p);
+ }
+ CompleteSyncRequest(aError);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::SetAudioModeComplete (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::SetAudioModeComplete(
+ TRadioServerError aError )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] AudioModeComplete(%d)"), aError);
+ TInt err = aError;
+ if ( iSyncRequest && iSyncRequest->iType == ERadioServForceMonoReception )
+ {
+ if ( err == KErrNone )
+ {
+ iSettings->SetForcedMonoStatus(iSyncRequest->iMessage.Int1());
+ if ( iState == EStatePlaying )
+ {
+ iDevSound->Stop();
+ TRAP(err, DoPlayL());
+ if ( err != KErrNone )
+ {
+ iSettings->SetRadioOff(err);
+ SetTspTargetClient( ERsPlayerIdle );
+ iState = EStateTunerOff;
+ iTunerControl->TunerOff();
+ RADIO_RDEBUG(_L("[RADIO-SVR] SetAudioModeComplete() - Tuner OFF"));
+ }
+ }
+ }
+ CompleteSyncRequest(err);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::SignalStrengthComplete (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::SignalStrengthComplete(
+ TRadioServerError aError,
+ TInt aStrength )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] SignalStrengthComplete(%d, %d)"), aError, aStrength);
+ if ( iSyncRequest && iSyncRequest->iType == ERadioServGetSignalStrength )
+ {
+ if ( aError == KErrNone )
+ {
+ TPckgBuf<TInt> p(aStrength);
+ iSyncRequest->iMessage.Write(1, p);
+ }
+ CompleteSyncRequest(aError);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::MaxSignalStrengthComplete (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::MaxSignalStrengthComplete(
+ TRadioServerError aError,
+ TInt aMaxStrength )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] MaxSignalStrengthComplete(%d, %d)"), aError, aMaxStrength);
+ if ( iSyncRequest && iSyncRequest->iType == ERadioServGetMaxSignalStrength )
+ {
+ if ( aError == KErrNone )
+ {
+ iMaxSigStrength = aMaxStrength;
+ TPckgBuf<TInt> p(aMaxStrength);
+ iSyncRequest->iMessage.Write(1, p);
+ }
+ CompleteSyncRequest(aError);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::SquelchComplete (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::SquelchComplete(
+ TRadioServerError /*aError*/,
+ TBool /*aEnabled*/ )
+ {
+ // Not used.
+ // Squelch is handled internally in RadioServer
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::SetSquelchComplete (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::SetSquelchComplete(
+ TRadioServerError /*aError*/ )
+ {
+ // Not used.
+ // Squelch is handled internally in RadioServer
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::BufferFilled (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::BufferFilled(
+ TDes8& /*aBuffer*/ )
+ {
+ iDevSound->PlayData();
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::RadioEventAntennaStatusChange (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::RadioEventAntennaStatusChange(
+ TBool aAttached )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] RadioEventAntennaStatusChange(%d) State[%d]"), aAttached, iState);
+ if ( iSettings->IsAntennaAttached() == aAttached )
+ {
+ // Do nothing since the state of the antenna hasn't changed.
+ RADIO_RDEBUG(_L("[RADIO-SVR] RadioEventAntennaStatusChange() - no change"));
+ return;
+ }
+
+ switch ( iState )
+ {
+ case EStateStarted:
+ // Just update the antenna status.
+ iSettings->SetAntennaStatus(aAttached);
+ RADIO_RDEBUG(_L("[RADIO-SVR] RadioEventAntennaStatusChange() - just antenna update"));
+ break;
+ case EStateTunerOn:
+ case EStatePlaying:
+ if ( iState == EStatePlaying )
+ {
+ iDevSound->Stop();
+ iSettings->SetRadioOff(KRadioServErrAntennaNotConnected);
+ SetTspTargetClient( ERsPlayerIdle );
+ }
+ // If we are receiving this at this state, it must be antenna detached
+ iSettings->SetAntennaStatus(EFalse);
+
+ // If station seek request is currently pending, complete the message since the
+ // adaptation will never complete this for us.
+ if ( iAsyncRequest && ( (iAsyncRequest->iType == ERadioServStationSeek) ||
+ (iAsyncRequest->iType == ERadioServStationSeekByPTY) ||
+ (iAsyncRequest->iType == ERadioServStationSeekByTA) ||
+ (iAsyncRequest->iType == ERadioServStationSeekByTP) ) )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] RadioEventAntennaStatusChange() - Seek Outstanding"));
+ if ( iAsyncRequest->iType == ERadioServStationSeek )
+ {
+ iTunerControl->CancelStationSeek();
+ }
+ else
+ {
+ iRdsControl->CancelRdsStationSeek();
+ }
+ // Disable squelching, if on
+ if ( iSquelch )
+ {
+ // Restore the last volume
+ iDevSound->SetVolume(iSettings->Volume());
+ iSquelch = EFalse;
+ }
+ CompleteAsyncRequest(KRadioServErrAntennaNotConnected);
+ }
+
+ iState = EStateTunerOff;
+ iTunerControl->TunerOff();
+ RADIO_RDEBUG(_L("[RADIO-SVR] RadioEventAntennaStatusChange() - Tuner OFF"));
+ break;
+ case EStateTunerOff:
+ if ( aAttached )
+ {
+ if ( !iSettings->IsOfflineModeEnabled() && !iSettings->IsTransmitterActive() && !iPreEmpted )
+ {
+ // Don't notify the client about the antenna status change yet.
+ // Notify once the Tuner is turned ON.
+ RADIO_RDEBUG(_L("[RADIO-SVR] RadioEventAntennaStatusChange() - Tuner ON"));
+ // AK - begin: need to set this status because recreating tuner will trigger another
+ // RadioEventAntennaStatusChange. (CPHU-73YTQW)
+ iSettings->SetAntennaStatus(ETrue, EFalse);
+ RecreateFmTunerControl();
+ // - end
+ iTunerOnTrigger = ETriggerAntenna;
+ TFMRadioFrequencyRange freqRange = TunerControlFreqRange( iSettings->FrequencyRange() );
+ iTunerControl->TunerOn(freqRange, iSettings->Frequency());
+ }
+ else
+ {
+ // Can't turn the tuner ON yet. Just update the antenna status.
+ RADIO_RDEBUG(_L("[RADIO-SVR] RadioEventAntennaStatusChange() - Wait"));
+ iSettings->SetAntennaStatus(ETrue);
+ }
+ }
+ else
+ {
+ // Just update the antenna status.
+ iSettings->SetAntennaStatus(EFalse);
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::RadioEventTunerControlChange (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::RadioEventTunerControlChange(
+ TRadioServerError aError )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] RadioEventTunerControlChange(%d) State[%d]"), aError, iState);
+ switch ( iState )
+ {
+ case EStateStarted:
+ // Just update the transmitter status.
+ if ( aError == KErrNone )
+ {
+ iSettings->SetTransmitterStatus(EFalse);
+ }
+ else if ( aError == KRadioServErrFmTransmitterActive )
+ {
+ iSettings->SetTransmitterStatus(ETrue);
+ }
+ break;
+ case EStateTunerOn:
+ case EStatePlaying:
+ if ( iState == EStatePlaying )
+ {
+ iDevSound->Stop();
+ iSettings->SetRadioOff(aError);
+ SetTspTargetClient( ERsPlayerIdle );
+ }
+ // Tuner was forced off due to hardware conflict
+ if ( aError == KRadioServErrFmTransmitterActive )
+ {
+ iSettings->SetTransmitterStatus(ETrue);
+ }
+ iState = EStateTunerOff;
+ iTunerControl->TunerOff();
+ RADIO_RDEBUG(_L("[RADIO-SVR] RadioEventTunerControlChange() - Tuner OFF"));
+ break;
+ case EStateTunerOff:
+ if ( aError == KErrNone )
+ {
+ if ( iSettings->IsAntennaAttached() && !iSettings->IsOfflineModeEnabled() && !iPreEmpted )
+ {
+ // Don't notify the client about the transmitter status change yet.
+ // Notify once the Tuner is turned ON.
+ RADIO_RDEBUG(_L("[RADIO-SVR] RadioEventTunerControlChange() - Tuner ON"));
+ RecreateFmTunerControl();
+ iTunerOnTrigger = ETriggerTransmitter;
+ TFMRadioFrequencyRange freqRange = TunerControlFreqRange( iSettings->FrequencyRange() );
+ iTunerControl->TunerOn(freqRange, iSettings->Frequency());
+ }
+ else
+ {
+ // Can't turn the tuner ON yet. Just update the transmitter status.
+ iSettings->SetTransmitterStatus(EFalse);
+ }
+ }
+ else if ( aError == KRadioServErrFmTransmitterActive )
+ {
+ // Just update the transmitter status.
+ iSettings->SetTransmitterStatus(ETrue);
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::StationSeekByPTYComplete (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::StationSeekByPTYComplete(
+ TRadioServerError aError,
+ TInt aFrequency )
+ {
+ StationSeekComplete(aError,aFrequency);
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::StationSeekByTAComplete (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::StationSeekByTAComplete(
+ TRadioServerError aError,
+ TInt aFrequency )
+ {
+ StationSeekComplete(aError,aFrequency);
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::StationSeekByTPComplete (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::StationSeekByTPComplete(
+ TRadioServerError aError,
+ TInt aFrequency )
+ {
+ StationSeekComplete(aError,aFrequency);
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::RdsDataPI (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::RdsDataPI(
+ TInt aPi )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] RdsDataPI(%d)"), aPi);
+ iSettings->SetProgrammeIdentification(aPi);
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::RdsDataPTY (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::RdsDataPTY(
+ TRdsProgrammeType aPty )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] RdsDataPTY(%d)"), aPty);
+ iSettings->SetProgrammeType(aPty);
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::RdsDataPS (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::RdsDataPS(
+ TRdsPSName& aPs )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] RdsDataPTY(%S)"), &aPs);
+ iSettings->SetProgrammeService(aPs);
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::RdsDataRT (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::RdsDataRT(
+ TRdsRadioText& aRt,
+ RArray<TRdsRTplusTag>& aRTplusTags )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] RdsDataRT(%S)"), &aRt);
+ TRdsRTplusTag tag1;
+ TRdsRTplusTag tag2;
+ TRdsRadioText rtPlusObject1;
+ TRdsRadioText rtPlusObject2;
+ TRdsRadioText aRtCopy;
+
+ aRtCopy.Copy( aRt );
+ iSettings->SetRadioText( aRt );
+
+ if( aRTplusTags.Count() > 0 )
+ {
+ // tags present, extract objects pointed by the tags
+ RADIO_RDEBUG(_L("[RADIO-SVR] RT+ tags found, extract objects and pass them through"));
+ tag1 = aRTplusTags[ 0 ];
+ tag2 = aRTplusTags[ 1 ];
+
+ if( tag1.iContentType == ERTplusItemDummy )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] Tag1 dummy, skipped!"));
+ }
+ else
+ {
+ // extract object from RadioText payload pointed by received tag information
+ TInt length = tag1.iLength + 1;
+ TInt start = tag1.iStart;
+ TInt rtLength = aRtCopy.Length();
+
+ if( start > rtLength )
+ {
+ start = rtLength;
+ RADIO_RDEBUG(_L("[RADIO-SVR] Tag1 start marker adjusted"));
+ }
+
+ if( length + start > rtLength )
+ {
+ //Make sure we don't try to copy too much, in case of erroneous length indicators
+ length = rtLength - start;
+ RADIO_RDEBUG(_L("[RADIO-SVR] Tag1 length marker adjusted"));
+ }
+ rtPlusObject1 = aRtCopy.Mid( start, length );
+ }
+
+ if( tag2.iContentType == ERTplusItemDummy )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] Tag2 dummy, skipped!"));
+ }
+ else
+ {
+ // extract object from RadioText payload pointed by received tag information
+ TInt length = tag2.iLength + 1;
+ TInt start = tag2.iStart;
+ TInt rtLength = aRtCopy.Length();
+
+ if( start > rtLength )
+ {
+ start = rtLength;
+ RADIO_RDEBUG(_L("[RADIO-SVR] Tag2 start marker adjusted"));
+ }
+
+ if( length + start > rtLength )
+ {
+ //Make sure we don't try to copy too much, in case of erroneous length indicators
+ length = rtLength - start;
+ RADIO_RDEBUG(_L("[RADIO-SVR] Tag2 length marker adjusted"));
+ }
+ rtPlusObject2 = aRtCopy.Mid( start, length );
+ }
+ RADIO_RDEBUG(_L("[RADIO-SVR] Passing RT+ objects"));
+ iSettings->SetRadioTextPlusObjects( rtPlusObject1, tag1.iContentType,
+ rtPlusObject2, tag2.iContentType );
+ }
+ aRTplusTags.Reset();
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::RdsDataCT (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::RdsDataCT(
+ TDateTime& aCt )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] RdsDataCT()"));
+ iSettings->SetClockTime(aCt);
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::RdsDataTA (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::RdsDataTA(
+ TBool aTaOn )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] RdsDataTA(%d)"), aTaOn);
+ iSettings->SetTrafficAnnouncementStatus(aTaOn);
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::RdsSearchBeginAF (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::RdsSearchBeginAF()
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] RdsSearchBeginAF()"));
+ iSettings->SetRdsBeginAF();
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::RdsSearchEndAF (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::RdsSearchEndAF(
+ TRadioServerError aError,
+ TInt aFrequency )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] RdsSearchEndAF(%d, %d)"), aError, aFrequency);
+ iSettings->SetRdsEndAF(aError, aFrequency);
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::RdsEventSignalChange (From MRadioServerFMTunerObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::RdsEventSignalChange(
+ TBool aSignal )
+ {
+ iSettings->SetRdsSignalChange(aSignal);
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::InitializeComplete (From MDevSoundObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::InitializeComplete(
+ TInt aError )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] InitializeComplete(%d) State[%d]"), aError, iState);
+ if ( aError == KErrNone )
+ {
+ TMMFCapabilities devSoundCaps = iDevSound->Capabilities();
+ RADIO_RDEBUG_INT3(_L("[RADIO-SVR] InitializeComplete - DevSound(%d, %d, %d)"), devSoundCaps.iRate, devSoundCaps.iEncoding, devSoundCaps.iChannels);
+
+ TUint tunerRate = iTunerCaps.iSampleRate;
+ TUint devSoundRate = devSoundCaps.iRate;
+ // Pick the highest sample rate possible
+ if ( (tunerRate & EFMRadioSampleRate96000Hz) && (devSoundRate & EMMFSampleRate96000Hz) )
+ {
+ iDevSoundConfig.iRate = EMMFSampleRate96000Hz;
+ }
+ else if ( (tunerRate == EFMRadioSampleRate88200Hz) && (devSoundRate & EMMFSampleRate88200Hz) )
+ {
+ iDevSoundConfig.iRate = EMMFSampleRate88200Hz;
+ }
+ else if ( (tunerRate == EFMRadioSampleRate64000Hz) && (devSoundRate & EMMFSampleRate64000Hz) )
+ {
+ iDevSoundConfig.iRate = EMMFSampleRate64000Hz;
+ }
+ else if ( (tunerRate == EFMRadioSampleRate48000Hz) && (devSoundRate & EMMFSampleRate48000Hz) )
+ {
+ iDevSoundConfig.iRate = EMMFSampleRate48000Hz;
+ }
+ else if ( (tunerRate == EFMRadioSampleRate44100Hz) && (devSoundRate & EMMFSampleRate44100Hz) )
+ {
+ iDevSoundConfig.iRate = EMMFSampleRate44100Hz;
+ }
+ else if ( (tunerRate == EFMRadioSampleRate32000Hz) && (devSoundRate & EMMFSampleRate32000Hz) )
+ {
+ iDevSoundConfig.iRate = EMMFSampleRate32000Hz;
+ }
+ else if ( (tunerRate == EFMRadioSampleRate24000Hz) && (devSoundRate & EMMFSampleRate24000Hz) )
+ {
+ iDevSoundConfig.iRate = EMMFSampleRate24000Hz;
+ }
+ else if ( (tunerRate == EFMRadioSampleRate22050Hz) && (devSoundRate & EMMFSampleRate22050Hz) )
+ {
+ iDevSoundConfig.iRate = EMMFSampleRate22050Hz;
+ }
+ else if ( (tunerRate == EFMRadioSampleRate16000Hz) && (devSoundRate & EMMFSampleRate16000Hz) )
+ {
+ iDevSoundConfig.iRate = EMMFSampleRate16000Hz;
+ }
+ else if ( (tunerRate == EFMRadioSampleRate12000Hz) && (devSoundRate & EMMFSampleRate12000Hz) )
+ {
+ iDevSoundConfig.iRate = EMMFSampleRate12000Hz;
+ }
+ else if ( (tunerRate == EFMRadioSampleRate11025Hz) && (devSoundRate & EMMFSampleRate11025Hz) )
+ {
+ iDevSoundConfig.iRate = EMMFSampleRate11025Hz;
+ }
+ else if ( (tunerRate == EFMRadioSampleRate8000Hz) && (devSoundRate & EMMFSampleRate8000Hz) )
+ {
+ iDevSoundConfig.iRate = EMMFSampleRate8000Hz;
+ }
+ else
+ {
+ // Nothing matched
+ RADIO_RDEBUG(_L("[RADIO-SVR] InitializeComplete() - incompatible sample rate"));
+ CompleteAsyncRequest(KRadioServErrHardwareFaulty);
+ return;
+ }
+
+ TUint tunerChan = iTunerCaps.iChannels;
+ TUint devSoundChan = devSoundCaps.iChannels;
+ if ( ((tunerChan & EFMRadioAudioMono) && (devSoundChan & EMMFMono)) &&
+ ((tunerChan & EFMRadioAudioStereo) && (devSoundChan & EMMFStereo)))
+ {
+ iChannels = EChannelBoth;
+ }
+ else if ( (tunerChan & EFMRadioAudioMono) && (devSoundChan & EMMFMono) )
+ {
+ iChannels = EChannelMono;
+ iSettings->SetForcedMonoStatus(ETrue, EFalse);
+ }
+ else if ( (tunerChan & EFMRadioAudioStereo) && (devSoundChan & EMMFStereo) )
+ {
+ iChannels = EChannelStereo;
+ }
+ else
+ {
+ // Nothing matched
+ RADIO_RDEBUG(_L("[RADIO-SVR] InitializeComplete() - incompatible channels"));
+ CompleteAsyncRequest(KRadioServErrHardwareFaulty);
+ return;
+ }
+ iState = EStateTunerOn;
+ CompleteAsyncRequest(KErrNone);
+ }
+ else
+ {
+ CompleteAsyncRequest(aError);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ToneFinished (From MDevSoundObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ToneFinished(
+ TInt /*aError*/ )
+ {
+ // Not used
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::BufferToBeFilled (From MDevSoundObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::BufferToBeFilled(
+ CMMFBuffer* aBuffer )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] BufferToBeFilled()"));
+ iTunerControl->BufferToBeFilled(STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data());
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::PlayError (From MDevSoundObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::PlayError(
+ TInt aError )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] PlayError(%d) State[%d]"), aError, iState);
+ if ( iState == EStatePlaying )
+ {
+ // If station seek request is currently pending, complete the message since the
+ // adaptation will never complete this for us.
+ if ( iAsyncRequest && ( (iAsyncRequest->iType == ERadioServStationSeek) ||
+ (iAsyncRequest->iType == ERadioServStationSeekByPTY) ||
+ (iAsyncRequest->iType == ERadioServStationSeekByTA) ||
+ (iAsyncRequest->iType == ERadioServStationSeekByTP) ) )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] PlayError() - Seek Outstanding"));
+ if ( iAsyncRequest->iType == ERadioServStationSeek )
+ {
+ iTunerControl->CancelStationSeek();
+ }
+ else
+ {
+ iRdsControl->CancelRdsStationSeek();
+ }
+ // Disable squelching, if on
+ if ( iSquelch )
+ {
+ // Restore the last volume
+ iDevSound->SetVolume(iSettings->Volume());
+ iSquelch = EFalse;
+ }
+ CompleteAsyncRequest(KRadioServErrTuning);
+ }
+
+ // We are being pre-empted by another application with higher priority.
+ // Turn the tuner off also to prevent interference + power saving.
+ iState = EStateTunerOff;
+ iPreEmpted = ETrue;
+ iSettings->SetRadioOff(aError);
+ iTunerControl->TunerOff();
+ SetTspTargetClient( ERsPlayerIdle );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::BufferToBeEmptied (From MDevSoundObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::BufferToBeEmptied(
+ CMMFBuffer* /*aBuffer*/ )
+ {
+ // Not used
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::RecordError (From MDevSoundObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::RecordError(
+ TInt /*aError*/ )
+ {
+ // Not used
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ConvertError (From MDevSoundObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ConvertError(
+ TInt /*aError*/ )
+ {
+ // Not used
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::DeviceMessage (From MDevSoundObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::DeviceMessage(
+ TUid /*aMessageType*/,
+ const TDesC8& /*aMsg*/ )
+ {
+ // Not used
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::SendEventToClient (From MDevSoundObserver)
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::SendEventToClient(
+ const TMMFEvent& /*aEvent*/ )
+ {
+ // Attempt to acquire sound device is rejected by audio policy server.
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] BufferToBeFilled() State[%d]"), iState);
+ iState = EStateTunerOn;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::HandleNotifyInt (From MCenRepNotifyHandlerCallback)
+// Notification from Central Repository indicating change in device's offline mode.
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::HandleNotifyInt(
+ TUint32 aId,
+ TInt /*aNewValue*/ )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] HandleNotifyInt()"));
+ // Start listening immediately before analyzing the notification to ensure that we
+ // don't miss further updates.
+ TRAPD(err, iCenRepNotifyHandler->StartListeningL());
+ if ( err != KErrNone )
+ {
+ User::Panic(_L("RadioServer-CR"), err );
+ }
+ if ( aId != KCoreAppUIsNetworkConnectionAllowed )
+ {
+ return;
+ }
+ TInt value;
+ iRepository->Get(KCoreAppUIsNetworkConnectionAllowed, value);
+
+ TBool offlineEnabled = EFalse;
+ if ( (TCoreAppUIsNetworkConnectionAllowed)value == ECoreAppUIsNetworkConnectionNotAllowed )
+ {
+ offlineEnabled = ETrue;
+ }
+
+ if ( iSettings->IsOfflineModeEnabled() == offlineEnabled )
+ {
+ // Do nothing since the offline status hasn't changed.
+ return;
+ }
+
+ switch ( iState )
+ {
+ case EStateStarted:
+ // Just update the offline mode status.
+ iSettings->SetOfflineModeStatus(offlineEnabled);
+ break;
+ case EStateTunerOn:
+ case EStatePlaying:
+ iSettings->SetOfflineModeStatus(offlineEnabled);
+ if ( !AllowRadioInOfflineMode() )
+ {
+ if ( iState == EStatePlaying )
+ {
+ iDevSound->Stop();
+ iSettings->SetRadioOff(KRadioServErrOfflineMode);
+ SetTspTargetClient( ERsPlayerIdle );
+ }
+
+ // If station seek request is currently pending, complete the message since the
+ // adaptation will never complete this for us.
+ if ( iAsyncRequest && ( (iAsyncRequest->iType == ERadioServStationSeek) ||
+ (iAsyncRequest->iType == ERadioServStationSeekByPTY) ||
+ (iAsyncRequest->iType == ERadioServStationSeekByTA) ||
+ (iAsyncRequest->iType == ERadioServStationSeekByTP) ) )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] HandleNotifyInt() - Seek Outstanding"));
+ if ( iAsyncRequest->iType == ERadioServStationSeek )
+ {
+ iTunerControl->CancelStationSeek();
+ }
+ else
+ {
+ iRdsControl->CancelRdsStationSeek();
+ }
+ // Disable squelching, if on
+ if ( iSquelch )
+ {
+ // Restore the last volume
+ iDevSound->SetVolume(iSettings->Volume());
+ iSquelch = EFalse;
+ }
+ CompleteAsyncRequest(KRadioServErrOfflineMode);
+ }
+
+ iState = EStateTunerOff;
+ iTunerControl->TunerOff();
+ RADIO_RDEBUG(_L("[RADIO-SVR] HandleNotifyInt() - Tuner OFF"));
+ }
+ break;
+ case EStateTunerOff:
+ if ( offlineEnabled )
+ {
+ // Just update the offline mode status.
+ iSettings->SetOfflineModeStatus(ETrue);
+ }
+ else
+ {
+ if ( iSettings->IsAntennaAttached() && !iSettings->IsTransmitterActive() && !iPreEmpted )
+ {
+ // Don't notify the client about the offline mode status change yet.
+ // Notify once the Tuner is turned ON.
+ RADIO_RDEBUG(_L("[RADIO-SVR] HandleNotifyInt() - Tuner ON"));
+ RecreateFmTunerControl();
+ iTunerOnTrigger = ETriggerOffline;
+ TFMRadioFrequencyRange freqRange = TunerControlFreqRange( iSettings->FrequencyRange() );
+ iTunerControl->TunerOn(freqRange, iSettings->Frequency());
+ }
+ else
+ {
+ // Can't turn the tuner ON yet. Just update the offline mode status.
+ iSettings->SetOfflineModeStatus(EFalse);
+ }
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+/***********************************************************
+ * Internal Functions Begin *
+ ***********************************************************/
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessAsyncRequest
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ProcessAsyncRequest(
+ TRadioMessageRequestData* aRequest )
+ {
+ // Set the current outstanding request
+ iAsyncRequest = aRequest;
+ switch( aRequest->iType )
+ {
+ case ERadioServRequestTunerControl:
+ ProcessRequestTunerControl((TRsTuner)aRequest->iMessage.Int1());
+ break;
+ case ERadioServSetFrequencyRange:
+ ProcessSetFrequencyRange((TRsFrequencyRange)aRequest->iMessage.Int1());
+ break;
+ case ERadioServSetFrequency:
+ ProcessSetFrequency(aRequest->iMessage.Int1());
+ break;
+ case ERadioServStationSeek:
+ ProcessStationSeek(aRequest->iMessage.Int1());
+ break;
+ case ERadioServPlay:
+ ProcessPlay();
+ break;
+ case ERadioServStop:
+ ProcessStop(aRequest->iMessage.Int1());
+ break;
+ case ERadioServStationSeekByPTY:
+ ProcessStationSeekByPTY(aRequest->iMessage.Int1(), aRequest->iMessage.Int2());
+ break;
+ case ERadioServStationSeekByTA:
+ ProcessStationSeekByTA(aRequest->iMessage.Int1());
+ break;
+ case ERadioServStationSeekByTP:
+ ProcessStationSeekByTP(aRequest->iMessage.Int1());
+ break;
+ default:
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessRequestTunerControl
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ProcessRequestTunerControl(
+ TRsTuner aTuner )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] ProcessRequestTunerControl(%d) State[%d]"), aTuner, iState);
+ if ( aTuner != ERsTunerFm )
+ {
+ // Only FM is supported at this point
+ CompleteAsyncRequest(KErrNotSupported);
+ return;
+ }
+
+ if ( iState != EStateStarted )
+ {
+ CompleteAsyncRequest(KErrAlreadyExists);
+ return;
+ }
+
+ TInt err = KErrNone;
+ if ( !iTunerControl )
+ {
+ if ( !iTunerControlObserver )
+ {
+ TRAP(err, iTunerControlObserver = CRadioServerFMTuner::NewL(*this));
+ }
+ if ( err == KErrNone )
+ {
+ TRAP(err, iTunerControl = CFMRadioTunerControl::NewL(*iTunerControlObserver));
+ if ( err == KErrNone )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessRequestTunerControl() - objects created"));
+ iTunerCaps = iTunerControl->Capabilities();
+ // RadioServer does not support dual tuner. Update the tuner capability to
+ // disable dual tuner support even if the adaptation supports it.
+ iTunerCaps.iTunerFunctions = (iTunerCaps.iTunerFunctions & 0x03);
+
+#ifdef RD_FM_RADIO_ENHANCEMENTS
+ iRdsControl = iTunerControl->RdsControl(*iTunerControlObserver);
+ if ( iRdsControl )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessRequestTunerControl() - RDS control obtained"));
+ iRdsControl->GetCapabilities(iRdsCaps);
+ // RadioServer does not support RadioText+. Update the tuner capability to
+ // disable RadioText+ support even if the adaptation supports it.
+ iRdsCaps.iRdsFunctions = (iRdsCaps.iRdsFunctions & 0x1EF);
+ }
+#endif
+ }
+ }
+ }
+ // AK - begin: (CPHU-73YTQW)
+ else
+ {
+ RecreateFmTunerControl();
+ }
+ // - end
+
+ if ( err == KErrNone )
+ {
+ if ( !AllowRadioInOfflineMode() )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessRequestTunerControl(): Offline"));
+ err = KRadioServErrOfflineMode;
+ }
+ else if ( iSettings->IsTransmitterActive() )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessRequestTunerControl(): Transmitter active"));
+ err = KRadioServErrFmTransmitterActive;
+ }
+ else if ( !iSettings->IsAntennaAttached() )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessRequestTunerControl(): Antenna not attached"));
+ err = KRadioServErrAntennaNotConnected;
+ }
+ }
+
+ if ( err == KErrNone )
+ {
+ iTunerOnTrigger = ETriggerTunerControl;
+ TFMRadioFrequencyRange freqRange = TunerControlFreqRange( iSettings->FrequencyRange() );
+ iTunerControl->TunerOn(freqRange, iSettings->Frequency());
+ }
+ else
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessRequestTunerControl() - unabled to create tuner. err=[%d]"), err);
+ CompleteAsyncRequest(err);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessSetFrequencyRange
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ProcessSetFrequencyRange(
+ TRsFrequencyRange aRange )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] ProcessSetFrequencyRange(%d) State[%d]"), aRange, iState);
+ if ( aRange == ERsRangeFmEuroAmerica || aRange == ERsRangeFmJapan )
+ {
+ if ( (iSettings->FrequencyRange()) == aRange )
+ {
+ // Same range; no further action needed
+ CompleteAsyncRequest(KErrNone);
+ return;
+ }
+
+ if ( iState == EStatePlaying )
+ {
+ iState = EStateTunerOff;
+ iFreqRange = aRange;
+ iDevSound->Stop();
+ iSettings->SetRadioOff(KErrNone);
+ iTunerControl->TunerOff();
+ // This request is completed upon TunerOffComplete()
+ SetTspTargetClient( ERsPlayerIdle );
+ }
+ else if ( iState == EStateTunerOn )
+ {
+ iState = EStateTunerOff;
+ iFreqRange = aRange;
+ iTunerControl->TunerOff();
+ // This request is completed upon TunerOffComplete()
+ }
+ else
+ {
+ CompleteAsyncRequest(KErrNotReady);
+ }
+ }
+ else
+ {
+ CompleteAsyncRequest(KErrNotSupported);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessSetFrequency
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ProcessSetFrequency(
+ TInt aFrequency )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] ProcessSetFrequency(%d) State[%d]"), aFrequency, iState);
+ switch ( iState )
+ {
+ case EStateTunerOn:
+ case EStatePlaying:
+ if( iSettings->Frequency() == aFrequency )
+ {
+ // Same frequency
+ CompleteAsyncRequest(KErrNone);
+ }
+ else
+ {
+ iTunerControl->SetFrequency(aFrequency);
+ }
+ break;
+ case EStateTunerOff:
+ if ( iSettings->IsAntennaAttached() && AllowRadioInOfflineMode()
+ && !iSettings->IsTransmitterActive() )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessSetFrequency() - Sent TunerOn request"));
+ RecreateFmTunerControl();
+ iTunerOnTrigger = ETriggerSetFrequency;
+ TFMRadioFrequencyRange freqRange = TunerControlFreqRange( iSettings->FrequencyRange() );
+ iTunerControl->TunerOn(freqRange, aFrequency);
+ }
+ else
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessSetFrequency - KErrNotReady"));
+ CompleteAsyncRequest(KErrNotReady);
+ }
+ break;
+ case EStateStarted:
+ CompleteAsyncRequest(KErrNotReady);
+ break;
+ default :
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessStationSeek
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ProcessStationSeek(
+ TBool aUpwards )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] ProcessStationSeek(%d) State[%d]"), aUpwards, iState);
+ switch ( iState )
+ {
+ case EStateTunerOn:
+ case EStatePlaying:
+ if ( iState == EStatePlaying )
+ {
+ if ( iSettings->IsSquelchEnabled() && !iSettings->IsMute() )
+ {
+ // Simulate squelching
+ iDevSound->SetVolume(0);
+ iSquelch = ETrue;
+ }
+ }
+ if ( aUpwards )
+ {
+ iTunerControl->StationSeek(EFMRadioSeekUp);
+ }
+ else
+ {
+ iTunerControl->StationSeek(EFMRadioSeekDown);
+ }
+ break;
+ case EStateStarted:
+ case EStateTunerOff:
+ CompleteAsyncRequest(KErrNotReady);
+ break;
+ default :
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessPlay
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ProcessPlay()
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessPlay() State[%d]"), iState);
+ switch ( iState )
+ {
+ case EStateTunerOn:
+ TRAPD(err, DoPlayL());
+ if ( err == KErrNone )
+ {
+ iState = EStatePlaying;
+ iPreEmpted = EFalse;
+ iSettings->SetRadioOn();
+ // Notify secondary clients that radio is now playing. This should trigger
+ // secondary clients to create a session to observe for events.
+ iSettings->SetRadioMonitorStatus(ETrue);
+ SetTspTargetClient( ERsPlayerPlaying );
+ }
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessPlay() DevSound err=[%d]"), err);
+ CompleteAsyncRequest(err);
+ break;
+ case EStatePlaying:
+ // Already playing
+ CompleteAsyncRequest(KErrNone);
+ break;
+ case EStateTunerOff:
+ if ( iSettings->IsAntennaAttached() && AllowRadioInOfflineMode()
+ && !iSettings->IsTransmitterActive() )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessPlay() - Sent TunerOn request"));
+ RecreateFmTunerControl();
+ iTunerOnTrigger = ETriggerPlay;
+ TFMRadioFrequencyRange freqRange = TunerControlFreqRange( iSettings->FrequencyRange() );
+ iTunerControl->TunerOn(freqRange, iSettings->Frequency());
+ }
+ else
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessPlay - KErrNotReady"));
+ CompleteAsyncRequest(KErrNotReady);
+ }
+ break;
+ default:
+ CompleteAsyncRequest(KErrNotReady);
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessStop
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ProcessStop(
+ TBool aIfOnlyPrimaryClient )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] ProcessStop(%d) State[%d]"), aIfOnlyPrimaryClient, iState);
+ if ( iState == EStatePlaying )
+ {
+ if ( aIfOnlyPrimaryClient && (iSessionCountPrimary > 1) )
+ {
+ // Client has requested stop only if the requesting client is the only primary client.
+ // There are other clients, so don't stop the audio in this case.
+ return;
+ }
+ iState = EStateTunerOn;
+ // Stop ongoing playback. This is synchronous function.
+ iDevSound->Stop();
+ iSettings->SetRadioOff(KErrNone);
+ SetTspTargetClient( ERsPlayerIdle );
+ }
+ CompleteAsyncRequest(KErrNone);
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessStationSeekByPTY
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ProcessStationSeekByPTY(
+ TRsRdsProgrammeType aPty,
+ TBool aSeekUp )
+ {
+ RADIO_RDEBUG_INT3(_L("[RADIO-SVR] ProcessStationSeekByPTY(%d, %d) State[%d]"), aPty, aSeekUp, iState);
+ switch ( iState )
+ {
+ case EStateTunerOn:
+ case EStatePlaying:
+ if ( !iRdsControl )
+ {
+ CompleteAsyncRequest(KErrNotSupported);
+ return;
+ }
+
+ if ( iSettings->IsSquelchEnabled() && !iSettings->IsMute() )
+ {
+ // Simulate squelching
+ iDevSound->SetVolume(0);
+ iSquelch = ETrue;
+ }
+ iRdsControl->StationSeekByPTY(aPty, aSeekUp);
+ break;
+ case EStateStarted:
+ case EStateTunerOff:
+ CompleteAsyncRequest(KErrNotReady);
+ break;
+ default :
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessStationSeekByTA
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ProcessStationSeekByTA(
+ TBool aSeekUp )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] ProcessStationSeekByTA(%d) State[%d]"), aSeekUp, iState);
+ switch ( iState )
+ {
+ case EStateTunerOn:
+ case EStatePlaying:
+ if ( !iRdsControl )
+ {
+ CompleteAsyncRequest(KErrNotSupported);
+ return;
+ }
+
+ if ( iSettings->IsSquelchEnabled() && !iSettings->IsMute() )
+ {
+ // Simulate squelching
+ iDevSound->SetVolume(0);
+ iSquelch = ETrue;
+ }
+ iRdsControl->StationSeekByTA(aSeekUp);
+ break;
+ case EStateStarted:
+ case EStateTunerOff:
+ CompleteAsyncRequest(KErrNotReady);
+ break;
+ default :
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessStationSeekByTP
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ProcessStationSeekByTP(
+ TBool aSeekUp )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] ProcessStationSeekByTP(%d) State[%d]"), aSeekUp, iState);
+ switch ( iState )
+ {
+ case EStateTunerOn:
+ case EStatePlaying:
+ if ( !iRdsControl )
+ {
+ CompleteAsyncRequest(KErrNotSupported);
+ return;
+ }
+
+ if ( iSettings->IsSquelchEnabled() && !iSettings->IsMute() )
+ {
+ // Simulate squelching
+ iDevSound->SetVolume(0);
+ iSquelch = ETrue;
+ }
+ iRdsControl->StationSeekByTP(aSeekUp);
+ break;
+ case EStateStarted:
+ case EStateTunerOff:
+ CompleteAsyncRequest(KErrNotReady);
+ break;
+ default :
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessRemovePrimaryClient
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessRemovePrimaryClientL(
+ const RMessage2& aMessage )
+ {
+#ifdef RD_TSP_CLIENT_MAPPER
+
+ RThread client;
+ aMessage.ClientL( client, EOwnerProcess );
+ RProcess process;
+ client.Process( process );
+ TInt index = iClientPids.Find( process.Id() );
+ if ( index != KErrNotFound )
+ {
+ iClientPids.Remove( index );
+ if ( iProcessId == process.Id() )
+ {
+ iMapper->RemoveTspTargetClient( iTspState, iProcessId );
+ if ( iClientPids.Count() && iState == EStatePlaying ) // still primary clients remaining
+ {
+ iProcessId = iClientPids[0];
+ RADIO_RDEBUG_INT( _L("RADIO-SVR] ProcessRemovePrimaryClient() pid[%d]"), (TInt)iProcessId );
+ iMapper->SetTspTargetClient( CTspClientMapper::EPlayingClients, iProcessId );
+ iTspState = CTspClientMapper::EPlayingClients;
+ }
+ }
+ }
+
+#endif // RD_TSP_CLIENT_MAPPER
+
+ if ( --iSessionCountPrimary == 0 )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessRemovePrimaryClient() - last primary"));
+ iSettings->SetRadioMonitorStatus(EFalse);
+ }
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetTunerCapabilities
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetTunerCapabilities(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetTunerCapabilities() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TRsTunerCapabilities caps;
+ caps.iFrequencyRange = iTunerCaps.iTunerBands;
+ caps.iCapabilities = iTunerCaps.iTunerFunctions;
+
+ TPckgBuf<TRsTunerCapabilities> p(caps);
+ aMessage.Write(1, p);
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessEnableTunerInOfflineMode
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessEnableTunerInOfflineMode(
+ TBool aEnable )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessEnableTunerInOfflineMode(%d)"), aEnable);
+ TInt err = KErrNone;
+ if ( iState == EStateStarted )
+ {
+ iEnableTunerInOffline = aEnable;
+ }
+ else
+ {
+ if ( iTunerCaps.iTunerFunctions & 0x01 ) // ETunerAvailableInOfflineMode
+ {
+ // Tuner supports playing radio in offline mode
+ iEnableTunerInOffline = aEnable;
+ }
+ else
+ {
+ err = KErrNotSupported;
+ }
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetFrequencyRange
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetFrequencyRange(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetFrequencyRange() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TRsFrequencyRange range;
+ TInt minFreq;
+ TInt maxFreq;
+ TInt err = iSettings->GetFrequencyRange(range, minFreq, maxFreq);
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetFrequencyRange() - [%d]"), err);
+ RADIO_RDEBUG_INT3(_L("[RADIO-SVR] ProcessGetFrequencyRange() - [%d, %d, %d]"), range, minFreq, maxFreq);
+ if ( err == KErrNone )
+ {
+ TPckgBuf<TRsFrequencyRange> pkg1(range);
+ aMessage.Write(1, pkg1);
+ TPckgBuf<TInt> pkg2(minFreq);
+ aMessage.Write(2, pkg2);
+ TPckgBuf<TInt> pkg3(maxFreq);
+ aMessage.Write(3, pkg3);
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetFrequency
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetFrequency(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetFrequency() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TPckgBuf<TInt> p(iSettings->Frequency());
+ aMessage.Write(1, p);
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetForceMonoReception
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetForceMonoReception(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetForceMonoReception() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TPckgBuf<TBool> p(iSettings->IsForceMonoEnabled());
+ aMessage.Write(1,p);
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessSetSquelch
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessSetSquelch(
+ TBool aEnabled )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] ProcessSetSquelch(%d) State[%d]"), aEnabled, iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ // Squelch is handled internally in RadioServer instead of requesting it to the tuner control
+ iSettings->SetSquelch(aEnabled);
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetSquelch
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetSquelch(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetSquelch() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TPckgBuf<TBool> p(iSettings->IsSquelchEnabled());
+ aMessage.Write(1,p);
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessSyncRequest
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ProcessSyncRequest(
+ TRadioMessageRequestData* aRequest )
+ {
+ // Set the current outstanding request
+ iSyncRequest = aRequest;
+ switch( aRequest->iType )
+ {
+ case ERadioServGetSignalStrength:
+ ProcessGetSignalStrength();
+ break;
+ case ERadioServGetMaxSignalStrength:
+ ProcessGetMaxSignalStrength();
+ break;
+ case ERadioServGetStereoMode:
+ ProcessGetStereoMode();
+ break;
+ case ERadioServForceMonoReception:
+ ProcessForceMonoReception(aRequest->iMessage.Int1());
+ break;
+ default:
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetSignalStrength
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ProcessGetSignalStrength()
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetSignalStrength() State[%d]"), iState);
+ if ( iState == EStateTunerOn || iState == EStatePlaying )
+ {
+ // The request is completed once SignalStrengthComplete() is received from tuner control
+ iTunerControl->SignalStrength();
+ }
+ else
+ {
+ CompleteSyncRequest(KErrNotReady);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetMaxSignalStrength
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ProcessGetMaxSignalStrength()
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetMaxSignalStrength() State[%d]"), iState);
+ switch ( iState )
+ {
+ case EStateStarted:
+ CompleteSyncRequest(KErrNotReady);
+ break;
+ case EStateTunerOn:
+ case EStatePlaying:
+ if ( iMaxSigStrength > 0 )
+ {
+ // This value is constant once we get it from the tuner. If the value is
+ // already available, there is no need to get it again from the tuner.
+ TPckgBuf<TInt> p(iMaxSigStrength);
+ iSyncRequest->iMessage.Write(1, p);
+ CompleteSyncRequest(KErrNone);
+ }
+ else
+ {
+ // The request is completed once MaxSignalStrengthComplete() is received from tuner control
+ iTunerControl->MaxSignalStrength();
+ }
+ break;
+ case EStateTunerOff:
+ if ( iMaxSigStrength > 0 )
+ {
+ // This value is constant once we get it from the tuner. If the value is
+ // already available, there is no need to get it again from the tuner.
+ TPckgBuf<TInt> p(iMaxSigStrength);
+ iSyncRequest->iMessage.Write(1, p);
+ CompleteSyncRequest(KErrNone);
+ }
+ else
+ {
+ CompleteSyncRequest(KErrNotReady);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetStereoMode
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ProcessGetStereoMode()
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetStereoMode() State[%d]"), iState);
+ if ( iState == EStateTunerOn || iState == EStatePlaying )
+ {
+ // The request is completed once AudioModeComplete() is received from tuner control
+ iTunerControl->AudioMode();
+ }
+ else
+ {
+ CompleteSyncRequest(KErrNotReady);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessForceMonoReception
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::ProcessForceMonoReception(
+ TBool aForcedMono )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] ProcessForceMonoReception(%d) State[%d]"), aForcedMono, iState);
+ if ( aForcedMono == iSettings->IsForceMonoEnabled() )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessForceMonoReception() - no change"));
+ CompleteSyncRequest(KErrNone);
+ return;
+ }
+
+ if ( iState == EStateTunerOn || iState == EStatePlaying )
+ {
+ TFMRadioAudioMode mode;
+ if ( aForcedMono )
+ {
+ if ( (iChannels == EChannelBoth) || (iChannels == EChannelMono) )
+ {
+ mode = EFMRadioAudioMono;
+ }
+ else
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessForceMonoReception() - unable to set to Mono"));
+ CompleteSyncRequest(KErrNotSupported);
+ return;
+ }
+ }
+ else
+ {
+ if ( (iChannels == EChannelBoth) || (iChannels == EChannelStereo) )
+ {
+ mode = EFMRadioAudioStereo;
+ }
+ else
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] DoPlayL() - unable to set to stereo"));
+ CompleteSyncRequest(KErrNotSupported);
+ return;
+ }
+ }
+ // The request is completed once SetAudioModeComplete() is received from tuner control.
+ iTunerControl->SetAudioMode(mode);
+ }
+ else
+ {
+ CompleteSyncRequest(KErrNotReady);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetPlayerState
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetPlayerState(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetPlayerState() State[%d]"), iState);
+ TRsPlayerState state = ERsPlayerIdle;
+ if ( iState == EStatePlaying )
+ {
+ state = ERsPlayerPlaying;
+ }
+ TPckgBuf<TRsPlayerState> p(state);
+ aMessage.Write(1,p);
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetMaxVolume
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetMaxVolume(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessGetMaxVolume()"));
+ TPckgBuf<TInt> p(iMaxVolume);
+ aMessage.Write(1, p);
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessSetVolume
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessSetVolume(
+ TInt aVolume )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessSetVolume(%d)"), aVolume);
+ if ( aVolume < 0 || aVolume > iMaxVolume )
+ {
+ return KErrArgument;
+ }
+
+ if ( aVolume != iSettings->Volume() )
+ {
+ if ( !iSettings->IsMute() )
+ {
+ iDevSound->SetVolume(aVolume);
+ }
+ iSettings->SetVolume(aVolume);
+ }
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetVolume
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetVolume(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessGetMaxVolume()"));
+ TPckgBuf<TInt> p(iSettings->Volume());
+ aMessage.Write(1, p);
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessSetVolumeRamp
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessSetVolumeRamp(
+ const RMessage2& aMessage )
+ {
+ TTimeIntervalMicroSeconds rampDuration(0);
+ TPckg<TTimeIntervalMicroSeconds> rampDurationPckg(rampDuration);
+ TInt err = aMessage.Read(1, rampDurationPckg);
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] ProcessSetVolumeRamp(%d) err[%d]"), I64INT(rampDuration.Int64()), err);
+ if ( err == KErrNone )
+ {
+ iDevSound->SetVolumeRamp(rampDuration);
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessSetMute
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessSetMute(
+ TBool aMute )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessSetMute(%d)"), aMute);
+ if ( aMute && !iSettings->IsMute() )
+ {
+ iDevSound->SetVolume(0);
+ }
+ else if ( !aMute && iSettings->IsMute() )
+ {
+ // Restore the last volume
+ iDevSound->SetVolume(iSettings->Volume());
+ }
+ iSettings->SetMuteStatus(aMute);
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetMuteStatus
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetMuteStatus(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessGetMuteStatus()"));
+ TPckgBuf<TBool> p(iSettings->IsMute());
+ aMessage.Write(1,p);
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessSetBalance
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessSetBalance(
+ TInt aLeft,
+ TInt aRight )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] ProcessSetBalance(%d, %d)"), aLeft, aRight);
+ if ( (aLeft < KRadioServerBalanceMin) || (aLeft > KRadioServerBalanceMax)
+ || (aRight < KRadioServerBalanceMin) || (aRight > KRadioServerBalanceMax) )
+ {
+ return KErrArgument;
+ }
+
+ TInt err = KErrNone;
+ TInt left, right;
+ iSettings->GetBalance(left, right);
+ if ( (left != aLeft) || (right != aRight) )
+ {
+ TRAP(err, iDevSound->SetPlayBalanceL(aLeft, aRight));
+ if( err == KErrNone )
+ {
+ iSettings->SetBalance(aLeft, aRight);
+ }
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetBalance
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetBalance(
+ const RMessage2& aMessage )
+ {
+ TInt left, right;
+ iSettings->GetBalance(left, right);
+ TPckgBuf<TInt> p1(left);
+ TPckgBuf<TInt> p2(right);
+ aMessage.Write(1,p1);
+ aMessage.Write(2,p2);
+ return KErrNone;
+ }
+
+/***********************************************************
+ * MRdsControl & MRdsControlObserver Begins
+ ***********************************************************/
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetRdsCapabilities
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetRdsCapabilities(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetRdsCapabilities() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TInt err = KErrNone;
+ if ( iRdsControl )
+ {
+ TRsRdsCapabilities caps;
+ caps.iRdsFunctions = iRdsCaps.iRdsFunctions;
+ TPckgBuf<TRsRdsCapabilities> p(caps);
+ aMessage.Write(1, p);
+ }
+ else
+ {
+ err = KErrNotSupported;
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetRdsSignalStatus
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetRdsSignalStatus(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetRdsSignalStatus() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TInt err = KErrNone;
+ if ( iRdsControl )
+ {
+ TBool signalStatus;
+ err = iRdsControl->GetRdsSignalStatus(signalStatus);
+ if ( err == KErrNone )
+ {
+ TPckgBuf<TBool> pkg(signalStatus);
+ aMessage.Write(1, pkg);
+ }
+ }
+ else
+ {
+ err = KErrNotSupported;
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessNotifyRdsDataChange
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessNotifyRdsDataChange(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessNotifyRdsDataChange() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TInt err = KErrNone;
+ if ( iRdsControl )
+ {
+ if ( iRdsNotifyClientIdArray.Count() == 0 )
+ {
+ TRdsData data;
+ data.iRdsFunctions = TRdsData::KAllRdsData;
+ data.iAdditionalFunctions1 = 0; // To suppress compiler warning
+ data.iAdditionalFunctions2 = 0; // To suppress compiler warning
+ err = iRdsControl->NotifyRdsDataChange(data);
+ }
+ if ( err == KErrNone )
+ {
+ RThread clientThread;
+ TInt error = aMessage.Client(clientThread);
+ if ( error == KErrNone )
+ {
+ TUint clientId = clientThread.Id().operator TUint();
+ AddRdsNotifyClientId(clientId);
+ }
+ }
+ }
+ else
+ {
+ err = KErrNotSupported;
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessCancelNotifyRdsDataChange
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessCancelNotifyRdsDataChange(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] ProcessCancelNotifyRdsDataChange()"));
+ if ( iRdsNotifyClientIdArray.Count() > 0 )
+ {
+ RThread clientThread;
+ TInt error = aMessage.Client(clientThread);
+ if ( error == KErrNone )
+ {
+ TUint clientId = clientThread.Id().operator TUint();
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessCancelNotifyRdsDataChange() clientID[%d]"), clientId);
+ RemoveRdsNotifyClientId(clientId);
+ }
+ if ( iRdsNotifyClientIdArray.Count() == 0 )
+ {
+ if ( iRdsControl )
+ {
+ iRdsControl->CancelNotifyRdsDataChange();
+ }
+ }
+ }
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessSetAutomaticSwitching
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessSetAutomaticSwitching(
+ TBool aAuto )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] ProcessSetAutomaticSwitching(%d) State[%d]"), aAuto, iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TInt err = KErrNone;
+ if ( iRdsControl )
+ {
+ err = iRdsControl->SetAutomaticSwitching(aAuto);
+ if ( err == KErrNone )
+ {
+ iSettings->SetAutoSwitchStatus(aAuto);
+ }
+ }
+ else
+ {
+ err = KErrNotSupported;
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetAutomaticSwitching
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetAutomaticSwitching(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetAutomaticSwitching() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TInt err = KErrNone;
+ if ( iRdsControl )
+ {
+ TPckgBuf<TBool> p(iSettings->AutoSwitch());
+ aMessage.Write(1, p);
+ }
+ else
+ {
+ err = KErrNotSupported;
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessCancelAFSearch
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessCancelAFSearch()
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessCancelAFSearch() State[%d]"), iState);
+ if ( iRdsControl )
+ {
+ iRdsControl->CancelAFSearch();
+ }
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetProgrammeIdentification
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetProgrammeIdentification(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetProgrammeIdentification() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TInt err = KErrNone;
+ if ( iRdsControl )
+ {
+ TInt pi;
+ err = iRdsControl->GetProgrammeIdentification(pi);
+ if ( err == KErrNone )
+ {
+ TPckgBuf<TInt> p(pi);
+ aMessage.Write(1, p);
+ }
+ }
+ else
+ {
+ err = KErrNotSupported;
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetProgrammeType
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetProgrammeType(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetProgrammeType() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TInt err = KErrNone;
+ if ( iRdsControl )
+ {
+ TRdsProgrammeType rdsPty;
+ err = iRdsControl->GetProgrammeType(rdsPty);
+ if ( err == KErrNone )
+ {
+ TRsRdsProgrammeType pty = rdsPty;
+ TPckgBuf<TRsRdsProgrammeType> p(pty);
+ aMessage.Write(1, p);
+ }
+ }
+ else
+ {
+ err = KErrNotSupported;
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetProgrammeService
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetProgrammeService(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetProgrammeService() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TInt err = KErrNone;
+ if ( iRdsControl )
+ {
+ TRdsPSName rdsPs;
+ err = iRdsControl->GetProgrammeService(rdsPs);
+ if ( err == KErrNone )
+ {
+ TRsRdsPSName ps;
+ ps.Copy(rdsPs);
+ TPckgBuf<TRsRdsPSName> p(ps);
+ aMessage.Write(1, p);
+ }
+ }
+ else
+ {
+ err = KErrNotSupported;
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetRadioText
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetRadioText(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetRadioText() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TInt err = KErrNone;
+ if ( iRdsControl )
+ {
+ TRdsRadioText rdsRt;
+ RArray<TRdsRTplusTag> rtTags;
+ err = iRdsControl->GetRadioText(rdsRt, rtTags);
+ rtTags.Close();
+ if ( err == KErrNone )
+ {
+ TRsRdsRadioText rt;
+ rt.Copy(rdsRt);
+ TPckgBuf<TRsRdsRadioText> p(rt);
+ aMessage.Write(1, p);
+ }
+ }
+ else
+ {
+ err = KErrNotSupported;
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetClockTime
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetClockTime(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetClockTime() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TInt err = KErrNone;
+ if ( iRdsControl )
+ {
+ TDateTime ct;
+ err = iRdsControl->GetClockTime(ct);
+ if ( err == KErrNone )
+ {
+ TPckgBuf<TDateTime> p(ct);
+ aMessage.Write(1, p);
+ }
+ }
+ else
+ {
+ err = KErrNotSupported;
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetTrafficAnnouncementStatus
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetTrafficAnnouncementStatus(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetTrafficAnnouncementStatus() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TInt err = KErrNone;
+ if ( iRdsControl )
+ {
+ TBool ta;
+ err = iRdsControl->GetTrafficAnnouncementStatus(ta);
+ if ( err == KErrNone )
+ {
+ TPckgBuf<TBool> p(ta);
+ aMessage.Write(1, p);
+ }
+ }
+ else
+ {
+ err = KErrNotSupported;
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::ProcessGetTrafficProgrammeStatus
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::ProcessGetTrafficProgrammeStatus(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] ProcessGetTrafficProgrammeStatus() State[%d]"), iState);
+ if ( iState == EStateStarted )
+ {
+ return KErrNotReady;
+ }
+
+ TInt err = KErrNone;
+ if ( iRdsControl )
+ {
+ TBool tp;
+ err = iRdsControl->GetTrafficProgrammeStatus(tp);
+ if ( err == KErrNone )
+ {
+ TPckgBuf<TBool> p(tp);
+ aMessage.Write(1, p);
+ }
+ }
+ else
+ {
+ err = KErrNotSupported;
+ }
+ return err;
+ }
+
+// ----------------------------------------------------
+// CRadioServer::CompleteAsyncRequest
+// Complete current outstanding request
+// ----------------------------------------------------
+//
+void CRadioServer::CompleteAsyncRequest(
+ TInt aErrorCode )
+ {
+ if ( iAsyncRequest && !(iAsyncRequest->iMessage.IsNull()) )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] CompleteAsyncRequest(%d, %d) - Client alive"), iAsyncRequest->iType, aErrorCode);
+ iAsyncRequest->iMessage.Complete(aErrorCode);
+ }
+ else
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] CompleteAsyncRequest(%d, %d) - Client gone"), iAsyncRequest->iType, aErrorCode);
+ }
+
+ delete iAsyncRequest;
+ iAsyncRequest = NULL;
+ ProcessNextItemInQueue(iAsyncRequestQue);
+ }
+
+// ----------------------------------------------------
+// CRadioServer::CompleteSyncRequest
+// Complete current outstanding request
+// ----------------------------------------------------
+//
+void CRadioServer::CompleteSyncRequest(
+ TInt aErrorCode )
+ {
+ if ( iSyncRequest && !(iSyncRequest->iMessage.IsNull()) )
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] CompleteSyncRequest(%d, %d) - Client alive"), iSyncRequest->iType, aErrorCode);
+ iSyncRequest->iMessage.Complete(aErrorCode);
+ }
+ else
+ {
+ RADIO_RDEBUG_INT2(_L("[RADIO-SVR] CompleteAsyncRequest(%d, %d) - Client gone"), iSyncRequest->iType, aErrorCode);
+ }
+
+ delete iSyncRequest;
+ iSyncRequest = NULL;
+ ProcessNextItemInQueue(iSyncRequestQue);
+ }
+
+// ----------------------------------------------------
+// CRadioServer::RemoveFromQueue
+// ----------------------------------------------------
+//
+void CRadioServer::RemoveFromQueue(
+ TSglQue<TRadioMessageRequestData>& aQue,
+ TRadioServerRequest aMessageType )
+ {
+ TRadioMessageRequestData* request;
+ TSglQueIter<TRadioMessageRequestData> iter(aQue);
+ iter.SetToFirst();
+ request = iter++;
+ while ( request )
+ {
+ if( request->iType == aMessageType )
+ {
+ aQue.Remove(*request);
+ if( !(request->iMessage.IsNull()) )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] RemoveFromQueue()"));
+ request->iMessage.Complete(KErrCancel);
+ }
+ delete request;
+ break;
+ }
+ request = iter++;
+ }
+ }
+
+// ----------------------------------------------------
+// CRadioServer::ProcessNextItemInQueue
+// ----------------------------------------------------
+//
+void CRadioServer::ProcessNextItemInQueue(
+ TSglQue<TRadioMessageRequestData>& aQue )
+ {
+ if ( !aQue.IsEmpty() )
+ {
+ // there is at least one element in the linked list
+ TRadioMessageRequestData* data;
+
+ data = aQue.First();
+ aQue.Remove(*data);
+ ProcessAsyncRequest(data);
+ }
+ }
+
+// ----------------------------------------------------
+// CRadioServer::ClearQueue
+// ----------------------------------------------------
+//
+void CRadioServer::ClearQueue()
+ {
+ while ( !iAsyncRequestQue.IsEmpty() )
+ {
+ iAsyncRequest = iAsyncRequestQue.First();
+ iAsyncRequestQue.Remove(*iAsyncRequest);
+ delete iAsyncRequest;
+ iAsyncRequest = NULL;
+ }
+
+ while ( !iSyncRequestQue.IsEmpty() )
+ {
+ iSyncRequest = iSyncRequestQue.First();
+ iSyncRequestQue.Remove(*iSyncRequest);
+ delete iSyncRequest;
+ iSyncRequest = NULL;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::AllowRadioInOfflineMode
+// -----------------------------------------------------------------------------
+//
+TBool CRadioServer::AllowRadioInOfflineMode()
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] AllowRadioInOfflineMode()"));
+ TBool res = EFalse;
+ if ( iSettings->IsOfflineModeEnabled() )
+ {
+ if ( iEnableTunerInOffline && (iTunerCaps.iTunerFunctions & 0x01) ) // ETunerAvailableInOfflineMode
+ {
+ // Only allowed when client requested tuner in offline AND adaptation supports it
+ res = ETrue;
+ }
+ }
+ else
+ {
+ // Phone is not in Offline mode anyways; OK
+ res = ETrue;
+ }
+ return res;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::GetFrequencyRange
+// -----------------------------------------------------------------------------
+//
+TInt CRadioServer::GetFrequencyRange(
+ TRsFrequencyRange& aRange,
+ TInt& aMinFreq,
+ TInt& aMaxFreq ) const
+ {
+ TInt err = KErrNone;
+#ifdef RD_FM_RADIO_ENHANCEMENTS
+ TFMRadioFrequencyRange range;
+ err = iTunerControl->GetFrequencyRange(range, aMinFreq, aMaxFreq);
+
+ if ( err == KErrNone )
+ {
+ if ( range == EFMRadioFrequencyEuroAmerica )
+ {
+ aRange = ERsRangeFmEuroAmerica;
+ }
+ else
+ {
+ aRange = ERsRangeFmJapan;
+ }
+ }
+#else
+ aRange = iSettings->FrequencyRange();
+ if ( aRange == ERsRangeFmEuroAmerica )
+ {
+ aMinFreq = KEuroAmericaMin;
+ aMaxFreq = KEuroAmericaMax;
+ }
+ else
+ {
+ aMinFreq = KJapanMin;
+ aMaxFreq = KJapanMax;
+ }
+#endif //#ifdef RD_FM_RADIO_ENHANCEMENTS
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] GetFrequencyRange() err[%d]"), err);
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::TunerControlFreqRange
+// -----------------------------------------------------------------------------
+//
+TFMRadioFrequencyRange CRadioServer::TunerControlFreqRange(
+ TRsFrequencyRange aRange )
+ {
+ if ( aRange == ERsRangeFmEuroAmerica )
+ {
+ return EFMRadioFrequencyEuroAmerica;
+ }
+ else
+ {
+ // Safe to assume; check was already done at ProcessSetFrequencyRange
+ return EFMRadioFrequencyJapan;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::DoPlayL
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::DoPlayL()
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] DoPlayL()"));
+ if ( iSettings->IsForceMonoEnabled() )
+ {
+ iDevSoundConfig.iChannels = EMMFMono;
+ }
+ else
+ {
+ iDevSoundConfig.iChannels = EMMFStereo;
+ }
+
+ iDevSound->SetConfigL(iDevSoundConfig);
+ RADIO_RDEBUG(_L("[RADIO-SVR] DoPlayL() - DevSound configured"));
+ iDevSound->PlayInitL();
+ RADIO_RDEBUG(_L("[RADIO-SVR] DoPlayL() - DevSound playInit OK"));
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::RecreateFmTunerControl
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::RecreateFmTunerControl()
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] RecreateFmTunerControl()"));
+ // AK - temporary until adaptation fix is available (CPHU-73YTQW)
+ delete iTunerControl;
+ iTunerControl = NULL;
+ iRdsControl = NULL;
+ TRAPD(err, iTunerControl = CFMRadioTunerControl::NewL(*iTunerControlObserver));
+ if ( err != KErrNone )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] RecreateFmTunerControl() - failed to recreate!"));
+ }
+#ifdef RD_FM_RADIO_ENHANCEMENTS
+ if ( iTunerControl )
+ {
+ iRdsControl = iTunerControl->RdsControl(*iTunerControlObserver);
+ if ( !iRdsControl )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] RecreateFmTunerControl() - failed to get RDS Control!"));
+ }
+ }
+#endif
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::AddRdsNotifyClientId
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::AddRdsNotifyClientId( TUint aClientId )
+ {
+ TInt index = iRdsNotifyClientIdArray.Find(aClientId);
+ if ( index == KErrNotFound )
+ {
+ // Client is not in the array, so add client.
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] AddRdsNotifyClientId() Add client[%d]"), aClientId);
+ iRdsNotifyClientIdArray.Append(aClientId);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::RemoveRdsNotifyClientId
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::RemoveRdsNotifyClientId( TUint aClientId )
+ {
+ TInt index = iRdsNotifyClientIdArray.Find(aClientId);
+ if ( index != KErrNotFound )
+ {
+ // Client is in the array, so remove client.
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] RemoveRdsNotifyClientId() Remove client[%d]"), aClientId);
+ iRdsNotifyClientIdArray.Remove(index);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::SetTspTargetClient
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::SetTspTargetClient(
+ TRsPlayerState aPlayerTargetState )
+ {
+ RADIO_RDEBUG_INT(_L("[RADIO-SVR] SetTspTargetClient(%d)"), aPlayerTargetState);
+#ifdef RD_TSP_CLIENT_MAPPER
+ if ( aPlayerTargetState == ERsPlayerPlaying )
+ {
+ iMapper->SetTspTargetClient( CTspClientMapper::EPlayingClients, iProcessId );
+ iTspState = CTspClientMapper::EPlayingClients;
+ }
+ else if ( aPlayerTargetState == ERsPlayerIdle )
+ {
+ iMapper->SetTspTargetClientToOtherType( CTspClientMapper::EStoppedClients, iProcessId );
+ iTspState = CTspClientMapper::EStoppedClients;
+ }
+#endif // RD_TSP_CLIENT_MAPPER
+ }
+
+// -----------------------------------------------------------------------------
+// CRadioServer::RegisterClientPidL
+// -----------------------------------------------------------------------------
+//
+void CRadioServer::RegisterClientPidL(
+ const RMessage2& aMessage )
+ {
+ RADIO_RDEBUG(_L("[RADIO-SVR] RegisterClientPid()"));
+#ifdef RD_TSP_CLIENT_MAPPER
+
+ RThread client;
+ aMessage.ClientL( client, EOwnerProcess );
+ RProcess process;
+ client.Process( process );
+ iClientPids.Append(process.Id());
+ if ( iClientPids.Count() == 1 )
+ {
+ iProcessId = process.Id();
+ }
+#endif // RD_TSP_CLIENT_MAPPER
+ }
+// End of File