/*
* Copyright (c) 2009 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: Telephony Multimedia Service
*
*/
#include <s32mem.h>
#include <gstring.h>
#include <AudioPreference.h>
#include <tmseffectobsrvr.h>
#include <tmsglobalroutingobsrvr.h>
#include <tmsringtoneobsrvr.h>
#include <tmsdtmfobsrvr.h>
#include <tmsinbandtoneobsrvr.h>
#include "tmsutility.h"
#include "tmsclientserver.h"
#include "tmsproxy.h"
using namespace TMS;
// CONSTANTS
const TUint KTMSServerConnectRetries = 2;
const TUint KSessionMessageSlots = 10;
const TUint KUTF8Multiply = 2;
// -----------------------------------------------------------------------------
// StartServer
//
// Function that will launch TMS server executable in it its own process.
// Start the server process/thread, which lives in an EPOCEXE object.
// Returns: gint: TMS_RESULT_SUCCESS (0) if no error.
// -----------------------------------------------------------------------------
//
gint TMSProxy::StartServer()
{
const TUidType serverUid(KNullUid, KNullUid, KTMSServerUid3);
// Only one instance of the server is allowed. Attempt of launching
// second instance of the server will fail with KErrAlreadyExists.
RProcess server;
gint ret = server.Create(KTMSServerFile, KNullDesC, serverUid);
if (ret == TMS_RESULT_SUCCESS)
{
TRequestStatus stat;
server.Rendezvous(stat);
if (stat != KRequestPending)
{
server.Kill(0); // abort startup
}
else
{
server.Resume(); // logon OK - start the server
}
User::WaitForRequest(stat); // wait for start or death
// We can't use the 'exit reason' if the server panicked, as '0' is a
// valid panic 'reason', which cannot be distinguished from
// TMS_RESULT_SUCCESS.
ret = (server.ExitType() == EExitPanic) ? KErrGeneral : stat.Int();
server.Close();
}
return ret;
}
// -----------------------------------------------------------------------------
// TMSProxy::TMSProxy
// -----------------------------------------------------------------------------
//
EXPORT_C TMSProxy::TMSProxy()
{
ResetObjectLists();
iMsgQHandler = NULL;
}
// -----------------------------------------------------------------------------
// TMSProxy::~TMSProxy
// -----------------------------------------------------------------------------
//
EXPORT_C TMSProxy::~TMSProxy()
{
ResetObjectLists();
if (iMsgQHandler)
{
iMsgQHandler->Cancel();
}
delete iMsgQHandler;
if (iMsgQueue.Handle() > 0)
{
iMsgQueue.Close();
}
if (Handle() > 0)
{
Close();
}
}
// -----------------------------------------------------------------------------
// TMSProxy::Connect
// Create a client-side session. Start the server if not started already.
// -----------------------------------------------------------------------------
//
EXPORT_C gint TMSProxy::Connect()
{
TRACE_PRN_FN_ENT;
gint retry = KTMSServerConnectRetries;
gint err(TMS_RESULT_GENERAL_ERROR);
gint numMessageSlots = KSessionMessageSlots;
for (;;)
{
// Try to create a new session with the server
err = CreateSession(KTMSServerName, Version(), numMessageSlots);
if ((err != KErrNotFound) && (err != KErrServerTerminated))
{
TRACE_PRN_N1(_L("[TMS session created; err==%d]"), err);
break; // Connected to existing server - ok
}
if (--retry == 0)
{
break; // Failed.
}
// Server not running, try to start it.
err = StartServer();
TRACE_PRN_N1(_L("[TMS server started; err==%d]"), err);
if ((err != TMS_RESULT_SUCCESS) && (err != KErrAlreadyExists))
{
break; // Server not launched - propagate error
}
}
TRACE_PRN_IF_ERR(err);
if (err == KErrNone)
{
err = CreateQueue(KTMSMsgQSlots);
}
TRACE_PRN_FN_EXT;
return TMSRESULT(err);
}
// -----------------------------------------------------------------------------
// TMSProxy::Version
// -----------------------------------------------------------------------------
//
EXPORT_C TVersion TMSProxy::Version() const
{
return (TVersion(KTMSServMajorVersionNumber, KTMSServMinorVersionNumber,
KTMSServBuildVersionNumber));
}
// -----------------------------------------------------------------------------
// TMSProxy::Close
// -----------------------------------------------------------------------------
//
EXPORT_C void TMSProxy::Close()
{
TRACE_PRN_FN_ENT;
RSessionBase::Close();
TRACE_PRN_FN_EXT;
}
EXPORT_C gint TMSProxy::GetTMSCallSessionHandle()
{
gint err(TMS_RESULT_SUCCESS);
err = SendReceive(ETMSCallSessionHandle);
return TMSRESULT(err);
}
EXPORT_C gint TMSProxy::GetSupportedDecoders(RArray<TUint32>& aDecoders,
gint& aFrameSize)
{
TRACE_PRN_FN_ENT;
gint err(TMS_RESULT_SUCCESS);
TmsMsgBufPckg pckg1;
TIpcArgs args1(&pckg1);
err = SendReceive(ETMSGetSupportedDecodersCount, args1);
gint count = 0;
aFrameSize = 0;
if (err == TMS_RESULT_SUCCESS)
{
count = pckg1().iInt;
aFrameSize = pckg1().iUint; //for g711 10/20ms frame detection
err = pckg1().iStatus;
}
if (count > 0 && err == TMS_RESULT_SUCCESS)
{
TRAP(err, PopulateArrayL(ETMSGetSupportedDecoders, aDecoders, count));
}
TRACE_PRN_FN_EXT;
return TMSRESULT(err);
}
EXPORT_C gint TMSProxy::GetSupportedEncoders(RArray<TUint32>& aEncoders,
gint& aFrameSize)
{
TRACE_PRN_FN_ENT;
gint err(TMS_RESULT_SUCCESS);
TmsMsgBufPckg pckg1;
TIpcArgs args1(&pckg1);
err = SendReceive(ETMSGetSupportedEncodersCount, args1);
gint count = 0;
aFrameSize = 0;
if (err == TMS_RESULT_SUCCESS)
{
count = pckg1().iInt;
aFrameSize = pckg1().iUint; //for g711 10/20ms frame detection
err = pckg1().iStatus;
}
if (count > 0 && err == TMS_RESULT_SUCCESS)
{
TRAP(err, PopulateArrayL(ETMSGetSupportedEncoders, aEncoders, count));
}
TRACE_PRN_FN_EXT;
return TMSRESULT(err);
}
EXPORT_C gint TMSProxy::SetOutput(TMSAudioOutput output)
{
TRACE_PRN_FN_ENT;
gint status = TMS_RESULT_SUCCESS;
if (output == TMS_AUDIO_OUTPUT_NONE)
{
status = TMS_RESULT_INVALID_ARGUMENT;
}
else
{
status = RSessionBase::SendReceive(ETMSSetOutput, TIpcArgs(output));
}
TRACE_PRN_FN_EXT;
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::GetOutput(TMSAudioOutput& output)
{
TRACE_PRN_FN_ENT;
TPckgBuf<guint> pckg;
TIpcArgs args(&pckg);
gint status = RSessionBase::SendReceive(ETMSGetOutput, args);
if (status == TMS_RESULT_SUCCESS)
{
output = pckg();
}
TRACE_PRN_FN_EXT;
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::GetPreviousOutput(TMSAudioOutput& output)
{
TRACE_PRN_FN_ENT;
TPckgBuf<guint> pckg;
TIpcArgs args(&pckg);
gint status = RSessionBase::SendReceive(ETMSGetPreviousOutput, args);
if (status == TMS_RESULT_SUCCESS)
{
output = pckg();
}
TRACE_PRN_FN_EXT;
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::GetAvailableOutputs(OutputVector& outputs)
{
gint status(TMS_RESULT_DOES_NOT_EXIST);
TRAP(status, GetAvailableOutputsL(outputs));
return TMSRESULT(status);
}
void TMSProxy::GetAvailableOutputsL(OutputVector& outputs)
{
HBufC8* buf = HBufC8::NewLC(10 * sizeof(TUint32));
TPtr8 ptr = buf->Des();
TPckgBuf<gint> countpkg;
TIpcArgs args;
args.Set(0, &countpkg);
args.Set(1, &ptr);
gint status = SendReceive(ETMSGetAvailableOutputs, args);
outputs.clear();
if (status != TMS_RESULT_SUCCESS)
{
User::Leave(status);
}
else
{
RDesReadStream stream(ptr);
CleanupClosePushL(stream);
for (gint i = 0; i < countpkg(); i++)
{
TMSAudioOutput output = stream.ReadUint32L();
if (output != TMS_AUDIO_OUTPUT_NONE)
{
outputs.push_back(output);
}
//TRACE_PRN_N1(_L("TMS->TMSProxy: outputs: [%d]"), stream.ReadUint32L());
}
CleanupStack::PopAndDestroy(&stream);
}
CleanupStack::PopAndDestroy(buf);
}
EXPORT_C gint TMSProxy::GetLevel(guint& level)
{
TRACE_PRN_FN_ENT;
TPckgBuf<guint> pckg;
TIpcArgs args(&pckg);
gint status = RSessionBase::SendReceive(ETMSGetGlobalVol, args);
if (status == TMS_RESULT_SUCCESS)
{
level = pckg();
}
TRACE_PRN_FN_EXT;
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::GetMaxLevel(guint& level)
{
TRACE_PRN_FN_ENT;
TPckgBuf<guint> pckg;
TIpcArgs args(&pckg);
gint status = RSessionBase::SendReceive(ETMSGetMaxGlobalVol, args);
if (status == TMS_RESULT_SUCCESS)
{
level = pckg();
}
TRACE_PRN_FN_EXT;
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::SetLevel(guint level)
{
TRACE_PRN_FN_ENT;
gint status = RSessionBase::SendReceive(ETMSSetGlobalVol, TIpcArgs(level));
TRACE_PRN_FN_EXT;
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::GetGain(guint& level)
{
TRACE_PRN_FN_ENT;
TPckgBuf<guint> pckg;
TIpcArgs args(&pckg);
gint status = RSessionBase::SendReceive(ETMSGetGlobalGain, args);
if (status == TMS_RESULT_SUCCESS)
{
level = pckg();
}
TRACE_PRN_FN_EXT;
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::GetMaxGain(guint& level)
{
TRACE_PRN_FN_ENT;
TPckgBuf<guint> pckg;
TIpcArgs args(&pckg);
gint status = RSessionBase::SendReceive(ETMSGetMaxGlobalGain, args);
if (status == TMS_RESULT_SUCCESS)
{
level = pckg();
}
TRACE_PRN_FN_EXT;
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::SetGain(guint level)
{
TRACE_PRN_FN_ENT;
gint status = RSessionBase::SendReceive(ETMSSetGlobalGain,
TIpcArgs(level));
TRACE_PRN_FN_EXT;
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::InitRT(const TMSRingToneType type, GString* str,
GString* tts)
{
TRACE_PRN_FN_ENT;
gint status(TMS_RESULT_INVALID_ARGUMENT);
TIpcArgs args;
HBufC* ttsBuf(NULL);
if (tts)
{
// Convert buffer from UTF-8 to unicode (16-bit)
// Note: UTF-8 strings can take up to 4 bytes per character
gint unilen = tts->len / KUTF8Multiply;
TRAP(status, ttsBuf = HBufC::NewL(unilen));
if (status == KErrNone)
{
TPtr p = ttsBuf->Des();
p.Copy((TUint16*) tts->str, unilen);
args.Set(1, &p);
}
}
switch (type)
{
case TMS_RINGTONE_DEFAULT:
{
status = RSessionBase::SendReceive(ETMSRingToneInitDefault, args);
break;
}
case TMS_RINGTONE_FILE:
{
if (str)
{
HBufC* buf(NULL);
// Convert buffer from UTF-8 to unicode (16-bit)
// Note: UTF-8 strings can take up to 4 bytes per character
gint unilen = str->len / KUTF8Multiply;
TRAP(status, buf = HBufC::NewL(unilen));
if (buf && status == KErrNone)
{
TPtr p = buf->Des();
p.Copy((TUint16*) str->str, unilen);
TIpcArgs args;
args.Set(0, &p);
status = RSessionBase::SendReceive(ETMSRingToneInitFile,
args);
}
delete buf;
buf = NULL;
}
break;
}
case TMS_RINGTONE_BEEP_ONCE:
{
status = RSessionBase::SendReceive(ETMSRingToneInitBeepOnce);
break;
}
case TMS_RINGTONE_SILENT:
{
status = RSessionBase::SendReceive(ETMSRingToneInitSilent);
break;
}
case TMS_RINGTONE_UNSECURE_VOIP:
{
status = RSessionBase::SendReceive(ETMSRingToneInitUnsecureVoIP);
break;
}
case TMS_RINGTONE_SEQUENCE:
{
if (str)
{
HBufC8* buf(NULL);
gint len = str->len;
TRAP(status, buf = HBufC8::NewL(len));
if (buf && status == KErrNone)
{
TPtr8 p = buf->Des();
p.Copy((TUint8*) str->str, len);
TIpcArgs args;
args.Set(0, &p);
status = RSessionBase::SendReceive(
ETMSRingToneInitSequence, args);
}
delete buf;
buf = NULL;
}
break;
}
default:
break;
}
delete ttsBuf;
ttsBuf = NULL;
TRACE_PRN_FN_EXT;
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::DeinitRT()
{
gint status(TMS_RESULT_SUCCESS);
status = RSessionBase::SendReceive(ETMSRingToneDeinit);
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::PlayRT()
{
gint status(TMS_RESULT_SUCCESS);
status = RSessionBase::SendReceive(ETMSRingTonePlay);
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::StopRT()
{
gint status(TMS_RESULT_SUCCESS);
status = RSessionBase::SendReceive(ETMSRingToneStop);
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::PauseRT()
{
gint status(TMS_RESULT_SUCCESS);
status = RSessionBase::SendReceive(ETMSRingTonePause);
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::MuteRT()
{
gint status(TMS_RESULT_SUCCESS);
status = RSessionBase::SendReceive(ETMSRingToneMute);
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::StartDTMF(TMSStreamType streamtype, GString* tone)
{
TRACE_PRN_FN_ENT;
__ASSERT_ALWAYS(tone, PANIC(TMS_RESULT_NULL_ARGUMENT));
gint status(TMS_RESULT_SUCCESS);
HBufC* buf(NULL);
TRAP(status, buf = HBufC::NewL(tone->len));
if (status == KErrNone)
{
TPtr p1 = buf->Des();
TPtr8 p2((TUint8*) tone->str, tone->len, tone->len);
p1.Copy(p2);
TRACE_PRN_N(p1);
TIpcArgs args;
args.Set(0, streamtype);
args.Set(1, &p1);
status = RSessionBase::SendReceive(ETMSStartDTMF, args);
}
delete buf;
buf = NULL;
TRACE_PRN_FN_EXT;
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::StopDTMF(TMSStreamType streamtype)
{
TRACE_PRN_FN_ENT;
gint status(TMS_RESULT_SUCCESS);
status = RSessionBase::SendReceive(ETMSStopDTMF, TIpcArgs(streamtype));
TRACE_PRN_FN_EXT;
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::ContinueDTMFStringSending(gboolean continuesending)
{
TRACE_PRN_FN_ENT;
gint status(TMS_RESULT_SUCCESS);
status = RSessionBase::SendReceive(ETMSContinueDTMF,
TIpcArgs(continuesending));
TRACE_PRN_FN_EXT;
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::StartInbandTone(TMSInbandToneType inbandtonetype)
{
TRACE_PRN_FN_ENT;
gint status(TMS_RESULT_SUCCESS);
status = RSessionBase::SendReceive(ETMSStartInbandTone,
TIpcArgs(inbandtonetype));
TRACE_PRN_FN_EXT;
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::StopInbandTone()
{
TRACE_PRN_FN_ENT;
gint status(TMS_RESULT_SUCCESS);
status = RSessionBase::SendReceive(ETMSStopInbandTone);
TRACE_PRN_FN_EXT;
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::StartDTMFNotifier()
{
gint status(TMS_RESULT_SUCCESS);
status = RSessionBase::SendReceive(ETMSStartDTMFNotifier); //DTMFHandler
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::CancelDTMFNotifier()
{
gint status(TMS_RESULT_SUCCESS);
status = RSessionBase::SendReceive(ETMSCancelDTMFNotifier); //DTMFHandler
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::StartGlobalEffectNotifier()
{
gint status(TMS_RESULT_SUCCESS);
RSessionBase::SendReceive(ETMSStartGlobalEffectNotifier); //CenRepHandler
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::CancelGlobalEffectNotifier()
{
gint status(TMS_RESULT_SUCCESS);
status = RSessionBase::SendReceive(ETMSCancelGlobalEffectNotifier);
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::StartRoutingNotifier()
{
gint status(TMS_RESULT_SUCCESS);
status = RSessionBase::SendReceive(ETMSStartRoutingNotifier); //TAR
return TMSRESULT(status);
}
EXPORT_C gint TMSProxy::CancelRoutingNotifier()
{
gint status(TMS_RESULT_SUCCESS);
status = RSessionBase::SendReceive(ETMSCancelRoutingNotifier);
return TMSRESULT(status);
}
// ---------------------------------------------------------------------------
// TMSProxy::SetMsgQueueNotifier
// ---------------------------------------------------------------------------
//
EXPORT_C gint TMSProxy::SetMsgQueueNotifier(TMSMsgQueueNotifierType type,
gpointer obsrv, gpointer parent, gint clientid)
{
gint status(TMS_RESULT_SUCCESS);
switch (type)
{
case EMsgQueueGlobalVolumeType:
case EMsgQueueGlobalGainType:
status = AddGlobalEffectObserver(
*(static_cast<TMSEffectObserver*>(obsrv)),
*(static_cast<TMSEffect*>(parent)), clientid);
break;
case EMsgQueueGlobalRoutingType:
status = AddRoutingObserver(
*(static_cast<TMSGlobalRoutingObserver*>(obsrv)),
*(static_cast<TMSGlobalRouting*>(parent)), clientid);
break;
case EMsgQueueRingtoneType:
status = AddRingToneObserver(
*(static_cast<TMSRingToneObserver*>(obsrv)),
*(static_cast<TMSRingTone*>(parent)), clientid);
break;
case EMsgQueueDTMFType:
status = AddDTMFObserver(*(static_cast<TMSDTMFObserver*>(obsrv)),
*(static_cast<TMSDTMF*>(parent)), clientid);
break;
case EMsgQueueInbandToneType:
status = AddInbandToneObserver(
*(static_cast<TMSInbandToneObserver*>(obsrv)),
*(static_cast<TMSInbandTone*>(parent)), clientid);
break;
default:
status = TMS_RESULT_INVALID_ARGUMENT;
break;
}
return TMSRESULT(status);
}
// ---------------------------------------------------------------------------
// TMSProxy::RemoveMsgQueueNotifier
// ---------------------------------------------------------------------------
//
EXPORT_C gint TMSProxy::RemoveMsgQueueNotifier(TMSMsgQueueNotifierType type,
gpointer obsrv)
{
gint status(TMS_RESULT_SUCCESS);
switch (type)
{
case EMsgQueueGlobalVolumeType:
case EMsgQueueGlobalGainType:
status = RemoveGlobalEffectObserver(
*(static_cast<TMSEffectObserver*>(obsrv)));
break;
case EMsgQueueGlobalRoutingType:
status = RemoveRoutingObserver(
*(static_cast<TMSGlobalRoutingObserver*>(obsrv)));
break;
case EMsgQueueRingtoneType:
status = RemoveRingToneObserver(
*(static_cast<TMSRingToneObserver*>(obsrv)));
break;
case EMsgQueueDTMFType:
status = RemoveDTMFObserver(
*(static_cast<TMSDTMFObserver*>(obsrv)));
break;
case EMsgQueueInbandToneType:
status = RemoveInbandToneObserver(
*(static_cast<TMSInbandToneObserver*>(obsrv)));
break;
default:
status = TMS_RESULT_INVALID_ARGUMENT;
break;
}
return TMSRESULT(status);
}
void TMSProxy::PopulateArrayL(TMSClientServerRequest aRequest,
RArray<TUint32>& aDecoders, gint aCount)
{
HBufC8* buf = HBufC8::NewLC(aCount * sizeof(TUint32));
TPtr8 ptr = buf->Des();
TIpcArgs args;
args.Set(0, &ptr);
gint err = SendReceive(aRequest, args);
if (err == TMS_RESULT_SUCCESS)
{
RDesReadStream stream(ptr);
CleanupClosePushL(stream);
aDecoders.Reset();
for (gint i = 0; i < aCount; i++)
{
aDecoders.Append(stream.ReadUint32L());
}
CleanupStack::PopAndDestroy(&stream);
}
CleanupStack::PopAndDestroy(buf);
}
gint TMSProxy::AddGlobalEffectObserver(TMSEffectObserver& obsrv,
TMSEffect& parent, gint /*clientid*/)
{
gint status = iEffectsObsrvrList.Find(&obsrv);
if (status == KErrNotFound)
{
status = iEffectsObsrvrList.Append(&obsrv);
status = iEffectsParentList.Append(&parent);
}
else
{
status = TMS_RESULT_ALREADY_EXIST;
}
return TMSRESULT(status);
}
gint TMSProxy::RemoveGlobalEffectObserver(TMSEffectObserver& obsrv)
{
gint status(TMS_RESULT_SUCCESS);
gint index = iEffectsObsrvrList.Find(&obsrv);
if (index >= 0)
{
iEffectsObsrvrList.Remove(index);
iEffectsParentList.Remove(index);
}
else
{
status = TMS_RESULT_DOES_NOT_EXIST;
}
return TMSRESULT(status);
}
gint TMSProxy::AddRoutingObserver(TMSGlobalRoutingObserver& obsrv,
TMSGlobalRouting& parent, gint /*clientid*/)
{
gint status = iRoutingObsrvrList.Find(&obsrv);
if (status == KErrNotFound)
{
status = iRoutingObsrvrList.Append(&obsrv);
status = iRoutingParentList.Append(&parent);
}
else
{
status = TMS_RESULT_ALREADY_EXIST;
}
return TMSRESULT(status);
}
gint TMSProxy::RemoveRoutingObserver(TMSGlobalRoutingObserver& obsrv)
{
gint status(TMS_RESULT_SUCCESS);
gint index = iRoutingObsrvrList.Find(&obsrv);
if (index >= 0)
{
iRoutingObsrvrList.Remove(index);
iRoutingParentList.Remove(index);
}
else
{
status = TMS_RESULT_DOES_NOT_EXIST;
}
return TMSRESULT(status);
}
gint TMSProxy::AddRingToneObserver(TMSRingToneObserver& obsrv,
TMSRingTone& parent, gint /*clientid*/)
{
gint status = iRingToneObsrvrList.Find(&obsrv);
if (status == KErrNotFound)
{
status = iRingToneObsrvrList.Append(&obsrv);
status = iRingToneParentList.Append(&parent);
}
else
{
status = TMS_RESULT_ALREADY_EXIST;
}
return TMSRESULT(status);
}
gint TMSProxy::RemoveRingToneObserver(TMSRingToneObserver& obsrv)
{
gint status(TMS_RESULT_SUCCESS);
gint index = iRingToneObsrvrList.Find(&obsrv);
if (index >= 0)
{
iRingToneObsrvrList.Remove(index);
iRingToneParentList.Remove(index);
}
else
{
status = TMS_RESULT_DOES_NOT_EXIST;
}
return TMSRESULT(status);
}
gint TMSProxy::AddDTMFObserver(TMSDTMFObserver& obsrv, TMSDTMF& parent,
gint /*clientid*/)
{
// Add to list if observer is not already added
gint status = iDTMFObsrvrList.Find(&obsrv);
if (status == KErrNotFound)
{
status = iDTMFObsrvrList.Append(&obsrv);
status = iDTMFParentList.Append(&parent);
}
else
{
status = TMS_RESULT_ALREADY_EXIST;
}
return TMSRESULT(status);
}
gint TMSProxy::RemoveDTMFObserver(TMSDTMFObserver& obsrv)
{
gint status(TMS_RESULT_SUCCESS);
gint index = iDTMFObsrvrList.Find(&obsrv);
if (index >= 0)
{
iDTMFObsrvrList.Remove(index);
iDTMFParentList.Remove(index);
}
else
{
status = TMS_RESULT_DOES_NOT_EXIST;
}
return TMSRESULT(status);
}
gint TMSProxy::AddInbandToneObserver(TMSInbandToneObserver& obsrv,
TMSInbandTone& parent, gint /*clientid*/)
{
// Add to list if observer is not already added
gint status = iInbandToneObsrvrList.Find(&obsrv);
if (status == KErrNotFound)
{
status = iInbandToneObsrvrList.Append(&obsrv);
status = iInbandToneParentList.Append(&parent);
}
else
{
status = TMS_RESULT_ALREADY_EXIST;
}
return TMSRESULT(status);
}
gint TMSProxy::RemoveInbandToneObserver(TMSInbandToneObserver& obsrv)
{
gint status(TMS_RESULT_SUCCESS);
gint index = iInbandToneObsrvrList.Find(&obsrv);
if (index >= 0)
{
iInbandToneObsrvrList.Remove(index);
iInbandToneParentList.Remove(index);
}
else
{
status = TMS_RESULT_DOES_NOT_EXIST;
}
return TMSRESULT(status);
}
// ---------------------------------------------------------------------------
// TMSProxy::CreateQueue
// ---------------------------------------------------------------------------
//
gint TMSProxy::CreateQueue(const gint aNumSlots)
{
gint status(TMS_RESULT_INVALID_ARGUMENT);
if (iMsgQueue.Handle() <= 0)
{
status = iMsgQueue.CreateGlobal(KNullDesC, aNumSlots);
if (status == TMS_RESULT_SUCCESS)
{
TRAP(status, ReceiveMsgQHandlerEventsL());
if (status == TMS_RESULT_SUCCESS)
{
TIpcArgs args;
args.Set(0, iMsgQueue);
status = RSessionBase::SendReceive(ETMSSetMsgQueueHandle,
args);
}
}
}
return TMSRESULT(status);
}
// ---------------------------------------------------------------------------
// TMSProxy::ReceiveMsgQHandlerEventsL
// Starts message queue handler (A/O) to monitor communication and transfer
// buffer events between client and the server.
// ---------------------------------------------------------------------------
//
void TMSProxy::ReceiveMsgQHandlerEventsL()
{
if (iMsgQHandler)
{
iMsgQHandler->Cancel();
}
else
{
iMsgQHandler = TMSQueueHandler::NewL(&iMsgQueue, NULL);
iMsgQHandler->AddObserver(*this, -1);
}
iMsgQHandler->Start();
}
// ---------------------------------------------------------------------------
// TMSProxy::QueueEvent
// Call from QueueHandler as a result of TMS Server callback.
// ---------------------------------------------------------------------------
//
void TMSProxy::QueueEvent(gint aEventType, gint aError, void* event_data)
{
TMSSignalEvent event = {}; //all elements initialized to zeros
event.type = aEventType;
event.reason = TMSRESULT(aError);
event.user_data = NULL; //use only to return data passed in by the user
switch (aEventType)
{
case TMS_EVENT_EFFECT_VOL_CHANGED:
{
if (event_data)
{
event.event_data = static_cast<gpointer>(event_data);
}
for (gint i = 0; i < iEffectsObsrvrList.Count(); i++)
{
iEffectsObsrvrList[i]->EffectsEvent(*iEffectsParentList[i],
event);
}
break;
}
case TMS_EVENT_EFFECT_GAIN_CHANGED:
{
for (gint i = 0; i < iEffectsObsrvrList.Count(); i++)
{
iEffectsObsrvrList[i]->EffectsEvent(*iEffectsParentList[i],
event);
}
break;
}
case TMS_EVENT_ROUTING_AVAIL_OUTPUTS_CHANGED:
case TMS_EVENT_ROUTING_OUTPUT_CHANGED:
case TMS_EVENT_ROUTING_SET_OUTPUT_COMPLETE:
{
guint output(0);
if (event_data != NULL)
{
output = *(static_cast<guint*>(event_data));
}
for (gint i = 0; i < iRoutingObsrvrList.Count(); i++)
{
iRoutingObsrvrList[i]->GlobalRoutingEvent(
*iRoutingParentList[i], event, output);
}
break;
}
case TMS_EVENT_RINGTONE_OPEN_COMPLETE:
case TMS_EVENT_RINGTONE_PLAY_COMPLETE:
case TMS_EVENT_RINGTONE_DEINIT_COMPLETE:
{
for (gint i = 0; i < iRingToneObsrvrList.Count(); i++)
{
iRingToneObsrvrList[i]->RingtoneEvent(*iRingToneParentList[i],
event);
}
break;
}
case TMS_EVENT_DTMF_TONE_STARTED:
case TMS_EVENT_DTMF_TONE_STOPPED:
{
for (gint i = 0; i < iDTMFObsrvrList.Count(); i++)
{
iDTMFObsrvrList[i]->DTMFEvent(*iDTMFParentList[i], event);
}
break;
}
case TMS_EVENT_INBAND_TONE_STARTED:
case TMS_EVENT_INBAND_TONE_STOPPED:
{
for (gint i = 0; i < iInbandToneObsrvrList.Count(); i++)
{
iInbandToneObsrvrList[i]->InbandToneEvent(
*iInbandToneParentList[i], event);
}
break;
}
default:
break;
}
}
// ---------------------------------------------------------------------------
// TMSProxy::ResetObjectLists
// ---------------------------------------------------------------------------
//
void TMSProxy::ResetObjectLists()
{
iEffectsObsrvrList.Reset();
iRoutingObsrvrList.Reset();
iRingToneObsrvrList.Reset();
iDTMFObsrvrList.Reset();
iInbandToneObsrvrList.Reset();
iEffectsParentList.Reset();
iRoutingParentList.Reset();
iRingToneParentList.Reset();
iDTMFParentList.Reset();
iInbandToneParentList.Reset();
}
// End of file