diff -r f5c5c82a163e -r 3570217d8c21 mmserv/tms/tmscallserver/src/tmsipcalluplinkds.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmserv/tms/tmscallserver/src/tmsipcalluplinkds.cpp Tue May 11 16:42:02 2010 +0300 @@ -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 +#include +#include +#include +#include +#include +#include "tmsutility.h" +#include "tmsipcallstream.h" + +using namespace TMS; + +// ----------------------------------------------------------------------------- +// TMSIPUplink::TMSIPUplink +// Standard Constructor +// ----------------------------------------------------------------------------- +// +TMSIPUplink::TMSIPUplink() + { + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::~TMSIPUplink +// Standard Constructor +// ----------------------------------------------------------------------------- +// +TMSIPUplink::~TMSIPUplink() + { + TRACE_PRN_FN_ENT; + + Stop(); + + delete iSpeechEncoderConfig; + delete iG711EncoderIntfc; + delete iG729EncoderIntfc; + delete iIlbcEncoderIntfc; + + TRACE_PRN_FN_EXT; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::NewL +// Symbian two-phase constructor +// ----------------------------------------------------------------------------- +// +TMSIPUplink* TMSIPUplink::NewL(const guint32 codecID, + const TMMFPrioritySettings priority) + { + TMSIPUplink* self = new (ELeave) TMSIPUplink(); + CleanupStack::PushL(self); + self->ConstructL(codecID, priority); + CleanupStack::Pop(self); + return self; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::ConstructL +// Part two of Symbian two phase construction +// ----------------------------------------------------------------------------- +// +void TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::Start +// +// ----------------------------------------------------------------------------- +// +void TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::Stop +// +// ----------------------------------------------------------------------------- +// +void TMSIPUplink::Stop() + { + TRACE_PRN_FN_ENT; + + if (iStatus == EStreaming && iDevSound) + { + iDevSound->Stop(); + iStatus = EReady; + } + else + { + //TODO: Notify main thread + } + TRACE_PRN_FN_EXT; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::BufferToBeEmptied +// From MDevSoundObserver +// ----------------------------------------------------------------------------- +// +void TMSIPUplink::BufferToBeEmptied(CMMFBuffer* aBuffer) + { + iDevSoundBufPtr = static_cast(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); + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::BufferEmptied +// +// ----------------------------------------------------------------------------- +// +void TMSIPUplink::BufferEmptied() + { + //TRACE_PRN_N(_L("TMS->UPL->BE")); + if (iDevSound) + { + iDevSound->RecordData(); + } + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::SetCodecCi +// +// ----------------------------------------------------------------------------- +// +gint TMSIPUplink::SetCodecCi() + { + TRAPD(err, SetCodecCiL()); + return err; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::SetCodecCiL +// +// ----------------------------------------------------------------------------- +// +void TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::SetGain +// +// ----------------------------------------------------------------------------- +// +gint TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::GetGain +// +// ----------------------------------------------------------------------------- +// +gint TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::GetMaxGain +// +// ----------------------------------------------------------------------------- +// +gint TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::GetDataXferChunkHndl +// +// ----------------------------------------------------------------------------- +// +gint TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::SetIlbcCodecMode +// +// ----------------------------------------------------------------------------- +// +gint TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::GetIlbcCodecMode +// +// ----------------------------------------------------------------------------- +// +gint TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::SetG711CodecMode +// +// ----------------------------------------------------------------------------- +// +gint TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::GetG711CodecMode +// +// ----------------------------------------------------------------------------- +// +gint TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::GetSupportedBitrates +// +// ----------------------------------------------------------------------------- +// +gint TMSIPUplink::GetSupportedBitrates(RArray& bitrates) + { + gint err = TMS_RESULT_DOES_NOT_EXIST; + bitrates.Reset(); + + if (iSpeechEncoderConfig) + { + err = iSpeechEncoderConfig->GetSupportedBitrates(bitrates); + } + + TRACE_PRN_IF_ERR(err); + return err; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::SetBitrate +// +// ----------------------------------------------------------------------------- +// +gint TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::GetBitrate +// +// ----------------------------------------------------------------------------- +// +gint TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::SetVad +// +// ----------------------------------------------------------------------------- +// +gint TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::GetVad +// +// ----------------------------------------------------------------------------- +// +gint TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::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 TMSIPUplink::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; + } + +// ----------------------------------------------------------------------------- +// TMSIPUplink::RecordError +// From MDevSoundObserver +// Recording error is send to the main thread. +// The state of recorder is rolled back to EReady. +// ----------------------------------------------------------------------------- +// +void TMSIPUplink::RecordError(TInt /*aError*/) + { + //TRACE_PRN_IF_ERR(aError); + +#ifdef _DEBUG + iSamplesRecCount = 0; +#endif + iStatus = EReady; + + // TODO: Notify client + } + +// End of file +