mmserv/tms/tmscallserver/src/ipcalluplinkds.cpp
changeset 0 71ca22bcf22a
child 3 4f62049db6ac
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmserv/tms/tmscallserver/src/ipcalluplinkds.cpp	Tue Feb 02 01:08:46 2010 +0200
@@ -0,0 +1,690 @@
+/*
+ * 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 <mmcccodecinformation.h>
+#include <IlbcEncoderIntfc.h>
+#include <G711EncoderIntfc.h>
+#include <G729EncoderIntfc.h>
+#include <SpeechEncoderConfig.h>
+#include "tmsutility.h"
+#include "ipcallstream.h"
+
+using namespace TMS;
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::TMSVoIPUplink
+// Standard Constructor
+// -----------------------------------------------------------------------------
+//
+TMSVoIPUplink::TMSVoIPUplink()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::~TMSVoIPUplink
+// Standard Constructor
+// -----------------------------------------------------------------------------
+//
+TMSVoIPUplink::~TMSVoIPUplink()
+    {
+    TRACE_PRN_FN_ENT;
+
+    Stop();
+
+    delete iSpeechEncoderConfig;
+    delete iG711EncoderIntfc;
+    delete iG729EncoderIntfc;
+    delete iIlbcEncoderIntfc;
+
+    TRACE_PRN_FN_EXT;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::NewL
+// Symbian two-phase constructor
+// -----------------------------------------------------------------------------
+//
+TMSVoIPUplink* TMSVoIPUplink::NewL(const guint32 codecID,
+        const TMMFPrioritySettings priority)
+    {
+    TMSVoIPUplink* self = new (ELeave) TMSVoIPUplink();
+    CleanupStack::PushL(self);
+    self->ConstructL(codecID, priority);
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::ConstructL
+// Part two of Symbian two phase construction
+// -----------------------------------------------------------------------------
+//
+void TMSVoIPUplink::ConstructL(const guint32 codecID,
+        const TMMFPrioritySettings priority)
+    {
+    TRACE_PRN_FN_ENT;
+
+    iCodecID = codecID;
+    iPriority = priority;
+
+    // Client must set these before querying!
+    iG711EncodeMode = TMS_G711_CODEC_MODE_ALAW;
+    iILBCEncodeMode = TMS_ILBC_CODEC_MODE_20MS_FRAME;
+
+    TRAPD(err, InitDevSoundL(EMMFStateRecording, priority));
+    if (err != TMS_RESULT_SUCCESS)
+        {
+        User::Leave(err);
+        }
+
+    iMaxBufLen = ConfigureMedia(iCodecID);
+
+    TRACE_PRN_FN_EXT;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::Start
+//
+// -----------------------------------------------------------------------------
+//
+void TMSVoIPUplink::Start()
+    {
+    TRACE_PRN_FN_ENT;
+
+    gint err = TMS_RESULT_ILLEGAL_OPERATION;
+    iWriteDataXferHndlToClient = FALSE;
+
+    if (iStatus == EReady && iDevSound)
+        {
+        TRAP(err, iDevSound->RecordInitL());
+        TRACE_PRN_IF_ERR(err);
+
+        if (err != TMS_RESULT_SUCCESS)
+            {
+            //TODO: Notify main thread
+            iStatus = EReady;
+            }
+#ifdef _DEBUG
+        else
+            {
+            iSamplesRecCount = 0;
+            }
+#endif
+        }
+
+    TRACE_PRN_FN_EXT;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::Stop
+//
+// -----------------------------------------------------------------------------
+//
+void TMSVoIPUplink::Stop()
+    {
+    TRACE_PRN_FN_ENT;
+
+    if (iStatus == EStreaming && iDevSound)
+        {
+        iDevSound->Stop();
+        iStatus = EReady;
+        }
+    else
+        {
+        //TODO: Notify main thread
+        }
+    TRACE_PRN_FN_EXT;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::BufferToBeEmptied
+// From MDevSoundObserver
+// -----------------------------------------------------------------------------
+//
+void TMSVoIPUplink::BufferToBeEmptied(CMMFBuffer* aBuffer)
+    {
+    iDevSoundBufPtr = static_cast<CMMFDataBuffer*> (aBuffer);
+    TDes8& data = iDevSoundBufPtr->Data();
+
+    iBufLen = iDevSoundBufPtr->BufferSize();
+    TRACE_PRN_N1(_L("TMS->UPL: BTBE->LEN [%d]"), iBufLen);
+
+    // Adjust/create RChunk if necessary
+    gint err = DoChunk(iBufLen, iMsgBuffer);
+
+    if (err != TMS_RESULT_SUCCESS)
+        {
+        Stop();
+        iMsgBuffer.iStatus = err;
+        }
+    else
+        {
+        // Pass buffer parameters to the client
+        iMsgBuffer.iStatus = err;
+        iMsgBuffer.iInt = iBufLen;
+
+        // Copy data over to RChunk
+        TPtr8 dataPtr(iChunk.Base(), iBufLen, iBufLen);
+        dataPtr = data;
+        iStatus = EStreaming;
+
+        // If chunk is opened, we will expect a call from the client to
+        // get chunk handle. When we get a call to copy chunk handle,
+        // check these variables and see if they match. This is not
+        // completely secure, but will provide some level of security.
+        if (iMsgBuffer.iBool == TRUE)
+            {
+            iWriteDataXferHndlToClient = TRUE;
+            iKey = iMsgBuffer.iUint32;
+            }
+        }
+
+    // Notify client there is buffer ready to be emptied
+    iMsgBuffer.iRequest = ECmdEmptyBuffer;
+    err = iMsgQueue.Send(iMsgBuffer);
+    TRACE_PRN_IF_ERR(err);
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::BufferEmptied
+//
+// -----------------------------------------------------------------------------
+//
+void TMSVoIPUplink::BufferEmptied()
+    {
+    //TRACE_PRN_N(_L("TMS->UPL->BE"));
+    if (iDevSound)
+        {
+        iDevSound->RecordData();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::SetCodecCi
+//
+// -----------------------------------------------------------------------------
+//
+gint TMSVoIPUplink::SetCodecCi()
+    {
+    TRAPD(err, SetCodecCiL());
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::SetCodecCiL
+//
+// -----------------------------------------------------------------------------
+//
+void TMSVoIPUplink::SetCodecCiL()
+    {
+    TRACE_PRN_FN_ENT;
+
+    switch (iCodecID)
+        {
+        case KMccFourCCIdG711:
+            {
+            if (!iG711EncoderIntfc)
+                {
+                iG711EncoderIntfc = CG711EncoderIntfc::NewL(*iDevSound);
+                }
+            break;
+            }
+        case KMccFourCCIdG729:
+            {
+            if (!iG729EncoderIntfc)
+                {
+                iG729EncoderIntfc = CG729EncoderIntfc::NewL(*iDevSound);
+                }
+            break;
+            }
+        case KMccFourCCIdILBC:
+            {
+            if (!iIlbcEncoderIntfc)
+                {
+                iIlbcEncoderIntfc = CIlbcEncoderIntfc::NewL(*iDevSound);
+                }
+            break;
+            }
+        case KMccFourCCIdAMRNB:
+        case KMMFFourCCCodePCM16:
+            {
+            break;
+            }
+        default:
+            {
+            User::Leave(TMS_RESULT_INVALID_ARGUMENT);
+            break;
+            }
+        }
+
+    if (!iSpeechEncoderConfig && iCodecID != KMMFFourCCCodePCM16)
+        {
+        iSpeechEncoderConfig = CSpeechEncoderConfig::NewL(*iDevSound);
+        }
+
+    TRACE_PRN_FN_EXT;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::SetGain
+//
+// -----------------------------------------------------------------------------
+//
+gint TMSVoIPUplink::SetGain(const guint gain)
+    {
+    gint status(TMS_RESULT_UNINITIALIZED_OBJECT);
+    if (iDevSound)
+        {
+        iDevSound->SetGain(gain);
+        status = TMS_RESULT_SUCCESS;
+        }
+    TRACE_PRN_N1(_L("TMS->UPL: SetGain [%d]"), gain);
+    return status;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::GetGain
+//
+// -----------------------------------------------------------------------------
+//
+gint TMSVoIPUplink::GetGain(guint& gain)
+    {
+    gint status(TMS_RESULT_UNINITIALIZED_OBJECT);
+    if (iDevSound)
+        {
+        gain = iDevSound->Gain();
+        status = TMS_RESULT_SUCCESS;
+        }
+    TRACE_PRN_N1(_L("TMS->UPL: GetGain [%d]"), gain);
+    return status;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::GetMaxGain
+//
+// -----------------------------------------------------------------------------
+//
+gint TMSVoIPUplink::GetMaxGain(guint& gain)
+    {
+    gint status(TMS_RESULT_UNINITIALIZED_OBJECT);
+    if (iDevSound)
+        {
+        gain = iDevSound->MaxGain();
+        status = TMS_RESULT_SUCCESS;
+        }
+    TRACE_PRN_N1(_L("TMS->UPL: MaxGain [%d]"), gain);
+    return status;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::GetDataXferChunkHndl
+//
+// -----------------------------------------------------------------------------
+//
+gint TMSVoIPUplink::GetDataXferChunkHndl(const TUint32 key, RChunk& chunk)
+    {
+    gint status = TMS_RESULT_SUCCESS;
+
+    if (iChunk.Handle())
+        {
+        if (iWriteDataXferHndlToClient && (iKey == key))
+            {
+            chunk = iChunk;
+            iWriteDataXferHndlToClient = FALSE;
+            iKey = 0;
+            }
+        else
+            {
+            status = TMS_RESULT_ILLEGAL_OPERATION;
+            }
+        }
+
+    return status;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::SetIlbcCodecMode
+//
+// -----------------------------------------------------------------------------
+//
+gint TMSVoIPUplink::SetIlbcCodecMode(const gint mode)
+    {
+    gint err = TMS_RESULT_DOES_NOT_EXIST;
+
+    if (iStatus == EReady)
+        {
+        iILBCEncodeMode = mode;
+
+        if (iIlbcEncoderIntfc && iCodecID == KMccFourCCIdILBC)
+            {
+            if (mode == TMS_ILBC_CODEC_MODE_20MS_FRAME)
+                {
+                err = iIlbcEncoderIntfc->SetEncoderMode(
+                        CIlbcEncoderIntfc::E20msFrame);
+                TRACE_PRN_N(_L("TMS->UPL: SetIlbcCodecMode [20ms Frame]"));
+                }
+            else if (mode == TMS_ILBC_CODEC_MODE_30MS_FRAME)
+                {
+                err = iIlbcEncoderIntfc->SetEncoderMode(
+                        CIlbcEncoderIntfc::E30msFrame);
+                TRACE_PRN_N(_L("TMS->UPL: SetIlbcCodecMode [30ms Frame]"));
+                }
+            }
+        }
+
+    TRACE_PRN_IF_ERR(err);
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::GetIlbcCodecMode
+//
+// -----------------------------------------------------------------------------
+//
+gint TMSVoIPUplink::GetIlbcCodecMode(gint& mode)
+    {
+    // not available through CIs -> return cached value
+    mode = iILBCEncodeMode;
+    TRACE_PRN_N1(_L("TMS->UPL: GetIlbcCodecMode [%d]"), mode);
+    return TMS_RESULT_SUCCESS;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::SetG711CodecMode
+//
+// -----------------------------------------------------------------------------
+//
+gint TMSVoIPUplink::SetG711CodecMode(const gint mode)
+    {
+    gint err = TMS_RESULT_DOES_NOT_EXIST;
+
+    if (iStatus == EReady)
+        {
+        iG711EncodeMode = mode;
+
+        if (iG711EncoderIntfc && iCodecID == KMccFourCCIdG711)
+            {
+            if (mode == TMS_G711_CODEC_MODE_ALAW)
+                {
+                err = iG711EncoderIntfc->SetEncoderMode(
+                        CG711EncoderIntfc::EEncALaw);
+                TRACE_PRN_N(_L("TMS->UPL: SetG711CodecMode [ALaw]"));
+                }
+            else if (mode == TMS_G711_CODEC_MODE_MULAW)
+                {
+                err = iG711EncoderIntfc->SetEncoderMode(
+                        CG711EncoderIntfc::EEncULaw);
+                TRACE_PRN_N(_L("TMS->UPL: SetG711CodecMode [uLaw]"));
+                }
+            }
+        }
+
+    TRACE_PRN_IF_ERR(err);
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::GetG711CodecMode
+//
+// -----------------------------------------------------------------------------
+//
+gint TMSVoIPUplink::GetG711CodecMode(gint& mode)
+    {
+    // not available through CIs -> return cached value
+    mode = iG711EncodeMode;
+    TRACE_PRN_N1(_L("TMS->UPL: GetG711CodecMode [%d]"), mode);
+    return TMS_RESULT_SUCCESS;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::GetSupportedBitrates
+//
+// -----------------------------------------------------------------------------
+//
+gint TMSVoIPUplink::GetSupportedBitrates(RArray<guint>& bitrates)
+    {
+    gint err = TMS_RESULT_DOES_NOT_EXIST;
+    bitrates.Reset();
+
+    if (iSpeechEncoderConfig)
+        {
+        err = iSpeechEncoderConfig->GetSupportedBitrates(bitrates);
+        }
+
+    TRACE_PRN_IF_ERR(err);
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::SetBitrate
+//
+// -----------------------------------------------------------------------------
+//
+gint TMSVoIPUplink::SetBitrate(guint bitrate)
+    {
+    gint err = TMS_RESULT_DOES_NOT_EXIST;
+
+    if (iSpeechEncoderConfig)
+        {
+        err = iSpeechEncoderConfig->SetBitrate(bitrate);
+        TRACE_PRN_N1(_L("TMS->UPL: SetBitrate [%d]"), bitrate);
+        }
+
+    TRACE_PRN_IF_ERR(err);
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::GetBitrate
+//
+// -----------------------------------------------------------------------------
+//
+gint TMSVoIPUplink::GetBitrate(guint& bitrate)
+    {
+    gint err = TMS_RESULT_DOES_NOT_EXIST;
+
+    if (iSpeechEncoderConfig)
+        {
+        err = iSpeechEncoderConfig->GetBitrate(bitrate);
+        TRACE_PRN_N1(_L("TMS->UPL: GetBitrate [%d]"), bitrate);
+        }
+
+    TRACE_PRN_IF_ERR(err);
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::SetVad
+//
+// -----------------------------------------------------------------------------
+//
+gint TMSVoIPUplink::SetVad(const TMSFormatType fmttype, const gboolean vad)
+    {
+    gint err = TMS_RESULT_DOES_NOT_EXIST;
+
+    switch (fmttype)
+        {
+        case TMS_FORMAT_G711:
+            {
+            if (iG711EncoderIntfc)
+                {
+                err = iG711EncoderIntfc->SetVadMode(vad);
+                TRACE_PRN_N1(_L("TMS->UPL: SetVad [%d]"), vad);
+                }
+            break;
+            }
+        case TMS_FORMAT_G729:
+            {
+            if (iG729EncoderIntfc)
+                {
+                err = iG729EncoderIntfc->SetVadMode(vad);
+                TRACE_PRN_N1(_L("TMS->UPL: SetVad [%d]"), vad);
+                }
+            break;
+            }
+        case TMS_FORMAT_ILBC:
+            {
+            if (iIlbcEncoderIntfc)
+                {
+                err = iIlbcEncoderIntfc->SetVadMode(vad);
+                TRACE_PRN_N1(_L("TMS->UPL: SetVad [%d]"), vad);
+                }
+            break;
+            }
+        case TMS_FORMAT_AMR:
+            {
+            if (iSpeechEncoderConfig)
+                {
+                err = iSpeechEncoderConfig->SetVadMode(vad);
+                TRACE_PRN_N1(_L("TMS->UPL: SetVad [%d]"), vad);
+                }
+            break;
+            }
+        default:
+            {
+            break; //TMS_RESULT_DOES_NOT_EXIST
+            }
+        }
+
+    TRACE_PRN_IF_ERR(err);
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::GetVad
+//
+// -----------------------------------------------------------------------------
+//
+gint TMSVoIPUplink::GetVad(const TMSFormatType fmttype, gboolean& vad)
+    {
+    gint err = TMS_RESULT_DOES_NOT_EXIST;
+
+    switch (fmttype)
+        {
+        case TMS_FORMAT_G711:
+            {
+            if (iG711EncoderIntfc)
+                {
+                err = iG711EncoderIntfc->GetVadMode(vad);
+                TRACE_PRN_N1(_L("TMS->UPL: GetVad [%d]"), vad);
+                }
+            break;
+            }
+        case TMS_FORMAT_G729:
+            {
+            if (iG729EncoderIntfc)
+                {
+                err = iG729EncoderIntfc->GetVadMode(vad);
+                TRACE_PRN_N1(_L("TMS->UPL: GetVad [%d]"), vad);
+                }
+            break;
+            }
+        case TMS_FORMAT_ILBC:
+            {
+            if (iIlbcEncoderIntfc)
+                {
+                err = iIlbcEncoderIntfc->GetVadMode(vad);
+                TRACE_PRN_N1(_L("TMS->UPL: GetVad [%d]"), vad);
+                }
+            break;
+            }
+        case TMS_FORMAT_AMR:
+            {
+            if (iSpeechEncoderConfig)
+                {
+                err = iSpeechEncoderConfig->GetVadMode(vad);
+                TRACE_PRN_N1(_L("TMS->UPL: GetVad [%d]"), vad);
+                }
+            break;
+            }
+        default:
+            {
+            break; //TMS_RESULT_DOES_NOT_EXIST
+            }
+        }
+
+    TRACE_PRN_IF_ERR(err);
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::InitializeComplete
+// A callback from the DevSound indicating completion of the initialization.
+// It will send config data to the D/S and configure the encoder via CI.
+// If everything goes well, the state of the thread is set EReady.
+// The initialization completion message is sent back to the main thread.
+// -----------------------------------------------------------------------------
+//
+void TMSVoIPUplink::InitializeComplete(TInt aError)
+    {
+    TRACE_PRN_FN_ENT;
+
+    gint err = aError;
+
+    if (err == TMS_RESULT_SUCCESS && iDevSound)
+        {
+        TMMFCapabilities conf;
+        conf = iDevSound->Config();
+        conf.iRate = EMMFSampleRate8000Hz;
+        conf.iChannels = EMMFMono;
+        TRAP(err, iDevSound->SetConfigL(conf));
+        if (err == TMS_RESULT_SUCCESS)
+            {
+            // We are ready to stream even in case of CI setting failure
+            iStatus = EReady;
+            iMaxGain = iDevSound->MaxGain();
+            }
+
+        // Init Custom Interface API to the Encoder
+        err = SetCodecCi();
+        if (err != TMS_RESULT_SUCCESS)
+            {
+            // DEBUG only
+            // Can ignore error - although encoder is not fully configured but
+            // it can still run in the default mode.
+            TRACE_PRN_IF_ERR(err);
+            }
+        }
+
+    // TODO: Notify client
+
+    TRACE_PRN_IF_ERR(err);
+    TRACE_PRN_FN_EXT;
+    }
+
+// -----------------------------------------------------------------------------
+// TMSVoIPUplink::RecordError
+// From MDevSoundObserver
+// Recording error is send to the main thread.
+// The state of recorder is rolled back to EReady.
+// -----------------------------------------------------------------------------
+//
+void TMSVoIPUplink::RecordError(TInt /*aError*/)
+    {
+    //TRACE_PRN_IF_ERR(aError);
+
+#ifdef _DEBUG
+    iSamplesRecCount = 0;
+#endif
+    iStatus = EReady;
+
+    // TODO: Notify client
+    }
+
+// End of file
+