mmserv/tms/tmsserver/src/tmsserversession.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:08:46 +0200
changeset 0 71ca22bcf22a
child 3 4f62049db6ac
child 12 5a06f39ad45b
permissions -rw-r--r--
Revision: 201003 Kit: 201005

/*
 * 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 <AudioPreference.h>
#include "tmsutility.h"
#include "tmsclientserver.h"
#include "tmsshared.h"
#include "tmsserversession.h"

using namespace TMS;

const TUint KArrayExpandSize = 8;

// -----------------------------------------------------------------------------
// TMSServerSession::NewL
// Symbian constructor.
// -----------------------------------------------------------------------------
//
TMSServerSession* TMSServerSession::NewL(TMSServer &aServer)
    {
    TMSServerSession* self = new (ELeave) TMSServerSession(aServer);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
    }

// -----------------------------------------------------------------------------
// TMSServerSession::~TMSServerSession
// The destructor
// -----------------------------------------------------------------------------
//
TMSServerSession::~TMSServerSession()
    {
    TRACE_PRN_FN_ENT;

    iServer.DropSession(); // will start shutdown if no more sessions left
    delete iDevSound;

    if (iMsgQueue.Handle() > 0)
        {
        iMsgQueue.Close();
        }

    if (iTMSCallSessionHandle.Handle() > 0)
        {
        iTMSCallSessionHandle.Close();
        }

    // Release memory and close handles to unused plug-ins held by the DevSound
    REComSession::FinalClose();

    TRACE_PRN_FN_EXT;
    }

// -----------------------------------------------------------------------------
// TMSServerSession::ConstructL
// 2-nd phase constructor.
// -----------------------------------------------------------------------------
//
void TMSServerSession::ConstructL()
    {
    TRACE_PRN_FN_ENT;
    TRACE_PRN_FN_EXT;
    }

// -----------------------------------------------------------------------------
// TMSServerSession::TMSServerSession
// -----------------------------------------------------------------------------
//
TMSServerSession::TMSServerSession(TMSServer &aServer) :
    iServer(aServer)
    {
    TRACE_PRN_FN_ENT;
    iServer.AddSession();
    TRACE_PRN_FN_EXT;
    }

// -----------------------------------------------------------------------------
// TMSServerSession::ServiceL
// Service request handler.
// -----------------------------------------------------------------------------
//
void TMSServerSession::ServiceL(const RMessage2& aMessage)
    {
    TRAPD(err, DispatchMessageL(aMessage));

    if (err != KErrNone)
        {
        aMessage.Complete(err);
        }
    }

// -----------------------------------------------------------------------------
// TMSServerSession::DispatchMessageL
// Service request handler.
// -----------------------------------------------------------------------------
//
void TMSServerSession::DispatchMessageL(const RMessage2& aMessage)
    {
    switch (aMessage.Function())
        {
        case ETMSCallSessionHandle:
            GetTMSCallSessionHandleL(aMessage);
            break;
        case ETMSGetSupportedEncodersCount:
            GetCodecsCountL(aMessage, TMS_STREAM_UPLINK);
            break;
        case ETMSGetSupportedDecodersCount:
            GetCodecsCountL(aMessage, TMS_STREAM_DOWNLINK);
            break;
        case ETMSGetSupportedEncoders:
            GetSupportedCodecsL(aMessage, TMS_STREAM_UPLINK);
            break;
        case ETMSGetSupportedDecoders:
            GetSupportedCodecsL(aMessage, TMS_STREAM_DOWNLINK);
            break;
        case ETMSSetOutput:
            SetOutput(aMessage);
            break;
        case ETMSGetOutput:
            iServer.GetOutput(aMessage);
            break;
        case ETMSGetPreviousOutput:
            iServer.GetPreviousOutput(aMessage);
            break;
        case ETMSGetAvailableOutputs:
            iServer.GetAvailableOutputs(aMessage);
            break;
        case ETMSStartRoutingNotifier:
            iServer.StartRoutingNotifierL();
            aMessage.Complete(KErrNone);
            break;
        case ETMSCancelRoutingNotifier:
            iServer.CancelRoutingNotifier();
            aMessage.Complete(KErrNone);
            break;
        case ETMSStartGlobalEffectNotifier:
            iServer.StartCenRepHandlerL();
            aMessage.Complete(KErrNone);
            break;
        case ETMSCancelGlobalEffectNotifier:
            iServer.CancelCenRepHandler();
            aMessage.Complete(KErrNone);
            break;
        case ETMSSetMsgQueueHandle:
            SetMessageQueueHandleL(aMessage);
            break;
        case ETMSSetGlobalVol:
            SetVolLevel(aMessage);
            break;
        case ETMSGetGlobalVol:
            iServer.GetLevel(aMessage);
            break;
        case ETMSGetMaxGlobalVol:
            iServer.GetMaxLevel(aMessage);
            break;
        case ETMSSetGlobalGain:
            SetMicGain(aMessage);
            break;
        case ETMSGetGlobalGain:
            iServer.GetGain(aMessage);
            break;
        case ETMSGetMaxGlobalGain:
            iServer.GetMaxGain(aMessage);
            break;
        default:
            User::Leave(KErrNotSupported);
            break;
        }
    }

// -----------------------------------------------------------------------------
// TMSServerSession::SetMessageQueueHandleL
//
// Open message queue for handling server notifications back to the client.
// -----------------------------------------------------------------------------
//
void TMSServerSession::SetMessageQueueHandleL(const RMessage2& aMessage)
    {
    gint status = KErrNone;
    if (iMsgQueue.Handle() <= 0)
        {
        status = iMsgQueue.Open(aMessage, 0);
        }
    if (status != KErrNone)
        {
        User::Leave(KErrArgument);
        }
    aMessage.Complete(KErrNone);
    }

// -----------------------------------------------------------------------------
// TMSServerSession::SetVolLevel
// -----------------------------------------------------------------------------
//
void TMSServerSession::SetVolLevel(const RMessage2& aMessage)
    {
    TInt level = aMessage.Int0();
    iServer.SetLevel(this, TRUE, level);
    aMessage.Complete(KErrNone);
    }

// -----------------------------------------------------------------------------
// TMSServerSession::SetMicGain
// -----------------------------------------------------------------------------
//
void TMSServerSession::SetMicGain(const RMessage2& aMessage)
    {
    TInt gain = aMessage.Int0();
    iServer.SetGain(this, gain);
    aMessage.Complete(KErrNone);
    }

// -----------------------------------------------------------------------------
// TMSServerSession::HandleGlobalEffectChange
// -----------------------------------------------------------------------------
//
void TMSServerSession::HandleGlobalEffectChange(TInt globalevent)
    {
    TRACE_PRN_FN_ENT;
    iMsgBuffer.iRequest = ECmdGlobalEffectChange;
    iMsgBuffer.iStatus = KErrNone;
    iMsgBuffer.iInt = globalevent;
    NotifyClient();
    TRACE_PRN_FN_EXT;
    }

// -----------------------------------------------------------------------------
// TMSServerSession::HandleRoutingChange
// -----------------------------------------------------------------------------
//
void TMSServerSession::HandleRoutingChange(TRoutingMsgBufPckg routinginfo)
    {
    TRACE_PRN_FN_ENT;
    iMsgBuffer.iRequest = ECmdGlobalRoutingChange;
    iMsgBuffer.iStatus = KErrNone;
    iMsgBuffer.iInt = routinginfo().iEvent;
    iMsgBuffer.iUint = routinginfo().iOutput;
    NotifyClient();
    TRACE_PRN_FN_EXT;
    }

// -----------------------------------------------------------------------------
// TMSServerSession::GetTMSCallSessionHandleL
// -----------------------------------------------------------------------------
//
void TMSServerSession::GetTMSCallSessionHandleL(const RMessage2& aMessage)
    {
    TRACE_PRN_FN_ENT;
    if (iTMSCallSessionHandle.Handle() == 0)
        {
        iServer.GetNewTMSCallSessionHandleL(iTMSCallSessionHandle);
        }
    aMessage.Complete(iTMSCallSessionHandle);
    TRACE_PRN_FN_EXT;
    }

// -----------------------------------------------------------------------------
// TMSServerSession::GetCodecsCountL
//
// Note: Currently, no data persists as a new session is created each time
//       before calling this method.
// -----------------------------------------------------------------------------
//
void TMSServerSession::GetCodecsCountL(const RMessage2& aMessage,
        TMSStreamType strmType)
    {
    TInt err = KErrNone;
    TInt codecsCount = 0;

    RArray<TFourCC>* codecs;
    iServer.GetSupportedCodecs(strmType, codecs);

    if (codecs)
        {
        codecsCount = codecs->Count();
        }

    if (codecsCount <= 0)
        {
        delete iDevSound;
        iDevSound = NULL;
        iDevSound = CMMFDevSound::NewL();

        if (iDevSound)
            {
            codecs->Reset();
            TMMFPrioritySettings priority;

            if (strmType == TMS_STREAM_UPLINK)
                {
                iDevSound->GetSupportedInputDataTypesL(*codecs, priority);
                }
            else if (strmType == TMS_STREAM_DOWNLINK)
                {
                iDevSound->GetSupportedOutputDataTypesL(*codecs, priority);
                }
            else
                {
                err = KErrNotSupported;
                }

#ifdef __WINSCW__
            // Support for adaptation stubs
            codecs->Append(KMccFourCCIdG711);
            codecs->Append(KMccFourCCIdG729);
            codecs->Append(KMccFourCCIdILBC);
            codecs->Append(KMccFourCCIdAMRNB);
#endif
            codecsCount = codecs->Count();
            }

        delete iDevSound;
        iDevSound = NULL;
        }

    TmsMsgBufPckg p;
    p().iInt = codecsCount;
#ifndef __WINSCW__
    p().iUint = 0; // G711 frame size undetermined
    //TODO: query G.711 codec to find its correct frame size (10 or 20 ms)
#else
    p().iUint = KTMSG711FrameLen20ms;
#endif //__WINSCW__
    p().iStatus = err;
    aMessage.WriteL(0, p);
    aMessage.Complete(KErrNone);
    }

// -----------------------------------------------------------------------------
// TMSServerSession::GetSupportedEncodersL
//
// -----------------------------------------------------------------------------
//
void TMSServerSession::GetSupportedCodecsL(const RMessage2& aMessage,
        TMSStreamType strmType)
    {
    TRACE_PRN_FN_ENT;

    CBufFlat* dataCopyBuffer = CBufFlat::NewL(KArrayExpandSize);
    CleanupStack::PushL(dataCopyBuffer);
    RBufWriteStream stream;
    stream.Open(*dataCopyBuffer);
    CleanupClosePushL(stream);

    RArray<TFourCC>* codecs;
    iServer.GetSupportedCodecs(strmType, codecs);
    TInt codecsCount = 0;
    codecsCount = codecs->Count();

    for (TInt i = 0; i < codecsCount; i++)
        {
        TFourCC fcc = (codecs->Array())[i];
        stream.WriteUint32L(fcc.FourCC());
        TRACE_PRN_N2(_L("TMS->Codec[%d]==[0x%x]"), i+1, fcc.FourCC());
        }

    aMessage.WriteL(0, dataCopyBuffer->Ptr(0));
    CleanupStack::PopAndDestroy(&stream);
    CleanupStack::PopAndDestroy(dataCopyBuffer);
    aMessage.Complete(KErrNone);

    TRACE_PRN_FN_EXT;
    }

// -----------------------------------------------------------------------------
// TMSServerSession::SetOutput
// -----------------------------------------------------------------------------
//
void TMSServerSession::SetOutput(const RMessage2& aMessage)
    {
    TInt output = aMessage.Int0();
    iServer.SetOutput(this, output);
    aMessage.Complete(KErrNone);
    }

// -----------------------------------------------------------------------------
// TMSServerSession::NotifyClient
// -----------------------------------------------------------------------------
//
void TMSServerSession::NotifyClient()
    {
    if (iMsgQueue.Handle() > 0)
        {
        iMsgQueue.Send(iMsgBuffer);
        }
    }

// End of file