/* ------------------------------------------------------------------
 * Copyright (C) 1998-2010 PacketVideo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 * -------------------------------------------------------------------
 */
// ----------------------------------------------------------------------
//
// This Software is an original work of authorship of PacketVideo Corporation.
// Portions of the Software were developed in collaboration with NTT  DoCoMo,
// Inc. or were derived from the public domain or materials licensed from
// third parties.  Title and ownership, including all intellectual property
// rights in and to the Software shall remain with PacketVideo Corporation
// and NTT DoCoMo, Inc.
//
// -----------------------------------------------------------------------

#include    "tscmain.h"
#include    "tsc_sub.h"     /* Sub Routine Information Header                */
#include    "tsc_component.h"

#define MAX_VENDOR_ID_OID_LEN 512 /* Max len of object identifier sequence */
/*****************************************************************************/
/*  function name        : Tsc_IdcVi                                         */
/*  function outline     : VendorIdentification procedure                    */
/*  function discription : Tsc_IdcVi( void )                                 */
/*  input data           : None                                              */
/*  output data          : None                                              */
/*  draw time            : '96.11.29                                         */
/*---------------------------------------------------------------------------*/
/*  amendent career      :                                                   */
/*                                                                           */
/*              Copyright (C) 1996 NTT DoCoMo                                */
/*****************************************************************************/
void TSC_324m::Tsc_IdcVi(void)
{
    S_ControlMsgHeader infHeader;
    PS_VendorIdentification      pVendorIdentification;

    if (iVendor == NULL)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "TSC_324m:Tsc_IdcVi - Not sending vendor id\n"));
        return;
    }
    /* Buffer Allocate */
    pVendorIdentification = (PS_VendorIdentification)OSCL_DEFAULT_MALLOC(sizeof(S_VendorIdentification));
    oscl_memset(pVendorIdentification, 0, sizeof(S_VendorIdentification));
    if (iVendor->GetVendorType() == EObjectIdentifier)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "TSC_324m:Tsc_IdcVi - EObjectIdentifier\n"));
        pVendorIdentification->vendor.index = 0; /* object */
        pVendorIdentification->vendor.object = (PS_OBJECTIDENT) OSCL_DEFAULT_MALLOC(sizeof(S_OBJECTIDENT));
        uint16 sz = 0;
        uint8* data = ((TPVH245VendorObjectIdentifier*)iVendor)->GetVendor(&sz);
        pVendorIdentification->vendor.object->size = sz;
        pVendorIdentification->vendor.object->data = (uint8*)OSCL_DEFAULT_MALLOC(sz);
        oscl_memcpy(pVendorIdentification->vendor.object->data, data, sz);
    }
    else if (iVendor->GetVendorType() == EH221NonStandard)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "TSC_324m:Tsc_IdcVi - EH221NonStandard\n"));
        pVendorIdentification->vendor.index = 1; /* H221Nonstandard */
        pVendorIdentification->vendor.h221NonStandard =
            (struct _H221NonStandard *)OSCL_DEFAULT_MALLOC(sizeof(struct _H221NonStandard));
        pVendorIdentification->vendor.h221NonStandard->manufacturerCode =
            (uint16)((TPVVendorH221NonStandard*)iVendor)->GetManufacturerCode();
        pVendorIdentification->vendor.h221NonStandard->t35CountryCode =
            ((TPVVendorH221NonStandard*)iVendor)->GetT35CountryCode();
        pVendorIdentification->vendor.h221NonStandard->t35Extension =
            ((TPVVendorH221NonStandard*)iVendor)->GetT35Extension();
    }
    else
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "TSC_324m:Tsc_IdcVi - ERROR - Invalid vendor type\n"));
        OSCL_DEFAULT_FREE(pVendorIdentification);
        return;
    }
    pVendorIdentification->option_of_productNumber = false;
    if (iProductNumberLen)
    {
        pVendorIdentification->option_of_productNumber = true;
        pVendorIdentification->productNumber.size =
            (uint16)iProductNumberLen;
        pVendorIdentification->productNumber.data =
            (uint8*)OSCL_DEFAULT_MALLOC(iProductNumberLen);
        oscl_memcpy(pVendorIdentification->productNumber.data,
                    iProductNumber, iProductNumberLen);
    }
    pVendorIdentification->option_of_versionNumber = false;
    if (iVersionNumberLen)
    {
        pVendorIdentification->option_of_versionNumber = true;
        pVendorIdentification->versionNumber.size =
            (uint16)iVersionNumberLen;
        pVendorIdentification->versionNumber.data =
            (uint8*)OSCL_DEFAULT_MALLOC(iVersionNumberLen);
        oscl_memcpy(pVendorIdentification->versionNumber.data,
                    iVersionNumber, iVersionNumberLen);
    }

    Tsc_SendDataSet(&infHeader, H245_PRIMITIVE, E_PtvId_Idc_Vi, 0, 0,
                    (uint8*)pVendorIdentification, sizeof(S_VendorIdentification));
    /* Primitive Send */
    iH245->DispatchControlMessage(&infHeader);
    Delete_VendorIdentification(pVendorIdentification);
    OSCL_DEFAULT_FREE(pVendorIdentification);
    return;
}

uint32 TSC_324m::VendorIdRecv(PS_ControlMsgHeader  pReceiveInf)
{
    PS_VendorIdentification  pVendorIdentification =
        (PS_VendorIdentification)pReceiveInf->pParameter;

    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "TSC_324m: Vendor Id Received - vendor index(%d), opn(%d), ovn(%d)\n",
                     pVendorIdentification->vendor.index,
                     pVendorIdentification->option_of_productNumber,
                     pVendorIdentification->option_of_versionNumber));
    Cleanup();

    if (pVendorIdentification->vendor.index == 0) // object identifier
    {
        if (pVendorIdentification->vendor.object->size &&
                (pVendorIdentification->vendor.object->size < MAX_VENDOR_ID_OID_LEN))
        {
            if (pVendorIdentification->vendor.object->data[pVendorIdentification->vendor.object->size - 1] == '\0')
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                                (0, "TSC_324m: Vendor Id - %s\n",
                                 pVendorIdentification->vendor.object->data));
            }
            iVendorR = OSCL_NEW(TPVH245VendorObjectIdentifier,
                                ((uint8*)pVendorIdentification->vendor.object->data,
                                 pVendorIdentification->vendor.object->size));
        }
        else
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "TSC_324m:VendorIdRecv - Error - invalid length(%d)\n",
                             pVendorIdentification->vendor.object->size));
            return GetTerminalStatus();
        }
    }
    else if (pVendorIdentification->vendor.index == 1) // H221NonStandard
    {
        iVendorR = OSCL_NEW(TPVVendorH221NonStandard,
                            (pVendorIdentification->vendor.h221NonStandard->t35CountryCode,
                             pVendorIdentification->vendor.h221NonStandard->t35Extension,
                             pVendorIdentification->vendor.h221NonStandard->manufacturerCode));
    }
    else
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "TSC_324m:VendorIdRecv - Error - invalid index(%d)\n",
                         pVendorIdentification->vendor.index));
        return GetTerminalStatus();
    }
    if (pVendorIdentification->option_of_productNumber)
    {
        iProductNumberLenR = pVendorIdentification->productNumber.size;
    }
    if (iProductNumberLenR)
    {
        if (pVendorIdentification->productNumber.data[iProductNumberLenR-1] == '\0')
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "TSC_324m: Product Number - %s\n",
                             pVendorIdentification->productNumber.data));
        }
        iProductNumberR = (uint8*)OSCL_DEFAULT_MALLOC(iProductNumberLenR);
        oscl_memcpy(iProductNumberR, pVendorIdentification->productNumber.data,
                    iProductNumberLenR);
    }
    if (pVendorIdentification->option_of_versionNumber)
    {
        iVersionNumberLenR = pVendorIdentification->versionNumber.size;
    }
    if (iVersionNumberLenR)
    {
        if (pVendorIdentification->versionNumber.data[iVersionNumberLenR-1] == '\0')
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "TSC_324m: Version Number - %s\n",
                             pVendorIdentification->versionNumber.data));
        }
        iVersionNumberR = (uint8*)OSCL_DEFAULT_MALLOC(iVersionNumberLenR);
        oscl_memcpy(iVersionNumberR, pVendorIdentification->versionNumber.data, iVersionNumberLenR);
    }
    if (iTSC_324mObserver)
    {
        iTSC_324mObserver->IncomingVendorId(iVendorR, iProductNumberR,
                                            (uint16)iProductNumberLenR, iVersionNumberR, (uint16)iVersionNumberLenR);
    }
    return GetTerminalStatus();
}


//-----------------------------------------------------------------------------
// Tsc_UII_DTMF()                                              (RAN-UII)
//
// This routine sends a DTMF signal via H.245 UserInputIndication message.
// It takes two input values:
//
//   uint8   dtmf_value      (ascii value of a character in [0123456789#*ABCD!])
//   uint16  dtmf_duration   (duration of pulse in mSec; 0 means no duration)
//-----------------------------------------------------------------------------
void TSC_324m::Tsc_UII_DTMF(uint8 dtmf_value, uint16 dtmf_duration)
{
    S_ControlMsgHeader           infHeader;
    PS_UserInputIndication       pUserInputIndication;

    // Allocate the UII structure
    pUserInputIndication = (PS_UserInputIndication)OSCL_DEFAULT_MALLOC(sizeof(S_UserInputIndication));

    // Fill in the 'signal'
    pUserInputIndication->index = 3;  /* signal */
    pUserInputIndication->signal = (PS_Signal) OSCL_DEFAULT_MALLOC(sizeof(S_Signal));

    pUserInputIndication->signal->option_of_signalRtp = 0;
    pUserInputIndication->signal->signalType.size = 1;
    pUserInputIndication->signal->signalType.data = (uint8*) OSCL_DEFAULT_MALLOC(1 * sizeof(uint8));
    pUserInputIndication->signal->signalType.data[0] = dtmf_value;

    if (dtmf_duration == 0)
    {
        pUserInputIndication->signal->option_of_duration = 0;
    }
    else
    {
        pUserInputIndication->signal->option_of_duration = 1;
        pUserInputIndication->signal->duration = dtmf_duration;
    }

    // Send the message
    Tsc_SendDataSet(&infHeader, H245_PRIMITIVE, E_PtvId_Idc_Ui, 0, 0, (uint8*)pUserInputIndication,
                    sizeof(S_UserInputIndication));
    iH245->DispatchControlMessage(&infHeader);
    Delete_UserInputIndication(pUserInputIndication);
    OSCL_DEFAULT_FREE(pUserInputIndication);
    return;
}

void TSC_324m::Tsc_UII_Alphanumeric(const uint8* str, uint16 str_len)
{
    S_ControlMsgHeader           infHeader;
    PS_UserInputIndication       pUserInputIndication;
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "TSC_324m:Tsc_UII_Alphanumeric - len(%d)", str_len));

    // Allocate the UII structure
    pUserInputIndication = (PS_UserInputIndication)OSCL_DEFAULT_MALLOC(sizeof(S_UserInputIndication));

    // Fill in the 'signal'
    pUserInputIndication->index = 1;  /* alphanumeric */
    pUserInputIndication->alphanumeric = (PS_int8STRING) OSCL_DEFAULT_MALLOC(sizeof(S_int8STRING));
    pUserInputIndication->alphanumeric->size = str_len;
    pUserInputIndication->alphanumeric->data = (uint8*) OSCL_DEFAULT_MALLOC(str_len * sizeof(uint8));
    oscl_memcpy(pUserInputIndication->alphanumeric->data, str, str_len);

    // Send the message
    Tsc_SendDataSet(&infHeader, H245_PRIMITIVE, E_PtvId_Idc_Ui, 0, 0, (uint8*)pUserInputIndication,
                    sizeof(S_UserInputIndication));
    iH245->DispatchControlMessage(&infHeader);
    Delete_UserInputIndication(pUserInputIndication);
    OSCL_DEFAULT_FREE(pUserInputIndication);
    return;
}

uint32 TSC_324m::UserInputIndicationRecv(PS_ControlMsgHeader  pReceiveInf)
{
    PS_UserInputIndication pUserInputIndication  = (PS_UserInputIndication)pReceiveInf->pParameter;
    void* ptr = NULL;
    CPVUserInput *pUserInput = NULL;
    uint16 duration = 0;

    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "TSC_324m: User Input Indication Received - index(%d)\n", pUserInputIndication->index));
    switch (pUserInputIndication->index)
    {
        case 1: /* alphanumeric */
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "TSC_324m: User Input Indication Received - alphanumeric size(%d)",
                             pUserInputIndication->alphanumeric->size));

            ptr = OSCL_DEFAULT_MALLOC(sizeof(CPVUserInputAlphanumeric));
            pUserInput = OSCL_PLACEMENT_NEW(ptr, CPVUserInputAlphanumeric(pUserInputIndication->alphanumeric->data,
                                            pUserInputIndication->alphanumeric->size));
            break;
        case 3: /* signal */
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "TSC_324m: User Input Indication Received - signal option_of_duration(%d), option_of_signalRtp(%d), signalType(%d)", pUserInputIndication->signal->option_of_duration, pUserInputIndication->signal->option_of_signalRtp, pUserInputIndication->signal->signalType.size));

            ptr = OSCL_DEFAULT_MALLOC(sizeof(CPVUserInputDtmf));

            if (pUserInputIndication->signal->option_of_duration)
            {
                duration = pUserInputIndication->signal->duration;
            }
            pUserInput = OSCL_PLACEMENT_NEW(ptr, CPVUserInputDtmf(*pUserInputIndication->signal->signalType.data,
                                            false, duration));
            break;
        default:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "TSC_324m: User Input Indication Received - unrecognized type\n"));
            return GetTerminalStatus();
    }

    OSCL_TRAPSTACK_PUSH(pUserInput);

    if (iTSC_324mObserver)
        iTSC_324mObserver->UserInputReceived(pUserInput);

    OSCL_TRAPSTACK_POP(); // pUserInput

    pUserInput->removeRef();

    return GetTerminalStatus();
}

void TSC_324m::IndicationMisc(TIndicationMisc type,
                              TPVChannelId channelId,
                              uint32 param,
                              OsclAny* param1)
{
    OSCL_UNUSED_ARG(param1);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "TSC_324m::IndicationMisc type(%d), channelId(%d), param(%d), param1(%x)",
                     type, channelId, param, param1));

    S_ControlMsgHeader infHeader;
    S_MiscellaneousIndication miscellaneousIndication;
    oscl_memset(&miscellaneousIndication, 0, sizeof(S_MiscellaneousIndication));

    switch (type)
    {
        case EVideoTemporalSpatialTradeOffIdc:
            miscellaneousIndication.logicalChannelNumber = (uint16)channelId;
            miscellaneousIndication.miType.index = EVideoTemporalSpatialTradeOffIdc;
            miscellaneousIndication.miType.videoTemporalSpatialTradeOff = (uint8)param;
            break;
        case ELogicalChannelActiveIdc:
            miscellaneousIndication.logicalChannelNumber = (uint16)channelId;
            miscellaneousIndication.miType.index = ELogicalChannelActiveIdc;
            break;
        case ELogicalChannelInactiveIdc:
            miscellaneousIndication.logicalChannelNumber = (uint16)channelId;
            miscellaneousIndication.miType.index = ELogicalChannelInactiveIdc;
            break;
        default:
            return;
    }

    Tsc_SendDataSet(&infHeader, H245_PRIMITIVE, E_PtvId_Idc_Mscl, 0, 0,
                    (uint8*)&miscellaneousIndication, sizeof(S_MiscellaneousIndication));
    iH245->DispatchControlMessage(&infHeader);
}

void TSC_324m::Tsc_IdcSkew(TPVChannelId lcn1, TPVChannelId lcn2, uint16 skew)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "TSC_324m::Tsc_IdcSkew lcn1(%d), lcn2(%d), skew(%d)",
                     lcn1, lcn2, skew));
    S_ControlMsgHeader infHeader;
    S_H223SkewIndication skewIndication;
    oscl_memset(&skewIndication, 0, sizeof(S_H223SkewIndication));
    skewIndication.logicalChannelNumber1 = (uint16)lcn1;
    skewIndication.logicalChannelNumber2 = (uint16)lcn2;
    skewIndication.skew = skew;

    Tsc_SendDataSet(&infHeader, H245_PRIMITIVE, E_PtvId_Idc_H223skw, 0, 0,
                    (uint8*)&skewIndication, sizeof(S_H223SkewIndication));
    iH245->DispatchControlMessage(&infHeader);
}

uint32 TSC_324m::MiscIndicationRecv(PS_ControlMsgHeader  pReceiveInf)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "TSC_324m::MiscIndicationRecv"));
    PS_MiscellaneousIndication indication = (PS_MiscellaneousIndication)pReceiveInf->pParameter;
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "TSC_324m::MiscIndicationRecv lcn(%d),index(%d)",
                     indication->logicalChannelNumber, indication->miType.index));
    switch (indication->miType.index)
    {
        case 0:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "TSC_324m::MiscIndicationRecv LogicalChannelActive"));
            if (iTSC_324mObserver)
            {
                CPVLogicalChannelIndication* pLCIndication = OSCL_NEW(CPVLogicalChannelIndication,
                        (indication->logicalChannelNumber));
                OSCL_TRAPSTACK_PUSH(pLCIndication);
                iTSC_324mObserver->LogicalChannelActiveIndicationReceived(pLCIndication);
                OSCL_TRAPSTACK_POP(); // pLCIndication
                pLCIndication->removeRef();
            }
            break;
        case 1:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "TSC_324m::MiscIndicationRecv LogicalChannelInactive"));
            if (iTSC_324mObserver)
            {
                CPVLogicalChannelIndication* pLCIndication = OSCL_NEW(CPVLogicalChannelIndication,
                        (indication->logicalChannelNumber));
                OSCL_TRAPSTACK_PUSH(pLCIndication);
                iTSC_324mObserver->LogicalChannelInactiveIndicationReceived(pLCIndication);
                OSCL_TRAPSTACK_POP(); // pLCIndication
                pLCIndication->removeRef();
            }
            break;
        case 9:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "TSC_324m::MiscIndicationRecv videoSpatialTemporalTradeoff(%d)",
                             indication->miType.videoTemporalSpatialTradeOff));
            if (iTSC_324mObserver)
            {
                CPVVideoSpatialTemporalTradeoff* pVideoSpatial = OSCL_NEW(CPVVideoSpatialTemporalTradeoff,
                        (indication->logicalChannelNumber, indication->miType.videoTemporalSpatialTradeOff));
                OSCL_TRAPSTACK_PUSH(pVideoSpatial);

                iTSC_324mObserver->VideoSpatialTemporalTradeoffIndicationReceived(pVideoSpatial);
                OSCL_TRAPSTACK_POP(); // pVideoSpatial
                pVideoSpatial->removeRef();
            }
            break;
        default:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "TSC_324m::MiscIndicationRecv Indication not handled"));
            break;
    }
    return GetTerminalStatus();
}

uint32 TSC_324m::SkewIndicationRecv(PS_ControlMsgHeader  pReceiveInf)
{
    PS_H223SkewIndication indication = (PS_H223SkewIndication)pReceiveInf->pParameter;
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "TSC_324m::SkewIndicationRecv lcn1(%d), lcn2(%d), skew(%d)",
                     indication->logicalChannelNumber1,
                     indication->logicalChannelNumber2,
                     indication->skew));
    uint16 skew = indication->skew;
    if (skew > PV_2WAY_MAX_SKEW_MS)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                        (0, "TSC_324m::SkewIndicationRecv skew(%d) > max skew(%d)",
                         indication->skew, PV_2WAY_MAX_SKEW_MS));
        skew = PV_2WAY_MAX_SKEW_MS;
    }

    /* Validate the skew indication */
    OlcParam* olcparam = iTSCcomponent->FindOlc(INCOMING, PV_AUDIO, OLC_ESTABLISHED);
    if (!olcparam)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
                        (0, "TSC_324m::SkewIndicationRecv Established incoming audio lcn not found"));
        return GetTerminalStatus() ;
    }
    if (indication->logicalChannelNumber2 != olcparam->GetChannelId())
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
                        (0, "TSC_324m::SkewIndicationRecv indication->logicalChannelNumber2=%d != audio lcn id=%d",
                         indication->logicalChannelNumber2, olcparam->GetChannelId()));
    }

    olcparam = iTSCcomponent->FindOlc(INCOMING, PV_VIDEO, OLC_ESTABLISHED);
    if (!olcparam)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
                        (0, "TSC_324m::SkewIndicationRecv Established incoming video lcn not found"));
        return GetTerminalStatus() ;
    }
    if (indication->logicalChannelNumber1 != olcparam->GetChannelId())
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
                        (0, "TSC_324m::SkewIndicationRecv indication->logicalChannelNumber1=%d != video lcn id=%d",
                         indication->logicalChannelNumber1, olcparam->GetChannelId()));
    }

    if (iTSC_324mObserver)
    {
        iTSC_324mObserver->SkewIndicationReceived(indication->logicalChannelNumber1,
                indication->logicalChannelNumber2, skew);
    }
    //Obtain logical channel #1, and transmit the skew duration
    OsclSharedPtr<H223IncomingChannel> channel;
    PVMFStatus retVal = iH223->GetIncomingChannel(indication->logicalChannelNumber1, channel);

    if (retVal != PVMFSuccess)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "TSC_324m::SkewIndicationRecv Error - Failed to lookup logical channel %d", indication->logicalChannelNumber1));
        return GetTerminalStatus();
    }

    return GetTerminalStatus();
}

void TSC_324m::SendFunctionNotSupportedIndication(uint16 cause,
        uint8* function,
        uint16 len)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "TSC_324m::SendFunctionNotSupportedIndication"));
    S_ControlMsgHeader infHeader;
    S_FunctionNotSupported fnsIndication;
    oscl_memset(&fnsIndication, 0, sizeof(S_FunctionNotSupported));
    fnsIndication.fnsCause.index = cause;
    if (function && len)
    {
        fnsIndication.option_of_returnedFunction = 1;
        fnsIndication.returnedFunction.size = len;
        fnsIndication.returnedFunction.data = function;
    }
    Tsc_SendDataSet(&infHeader, H245_PRIMITIVE, E_PtvId_Idc_Fns, 0, 0,
                    (uint8*)&fnsIndication, sizeof(S_FunctionNotSupported));
    iH245->DispatchControlMessage(&infHeader);
    return;
}

uint32 TSC_324m::FunctionNotSupportedIndicationReceived(PS_ControlMsgHeader  pReceiveInf)
{
    OSCL_UNUSED_ARG(pReceiveInf);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "TSC_324m::FunctionNotSupportedIndicationReceived"));
    return GetTerminalStatus();
}

uint32 TSC_324m::FlowControlIndicationReceived(PS_ControlMsgHeader  pReceiveInf)
{
    OSCL_UNUSED_ARG(pReceiveInf);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "TSC_324m::FlowControlIndicationReceived"));
    return GetTerminalStatus();
}

