Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 // ----------------------------------------------------------------------
     19 //
     20 // This Software is an original work of authorship of PacketVideo Corporation.
     21 // Portions of the Software were developed in collaboration with NTT  DoCoMo,
     22 // Inc. or were derived from the public domain or materials licensed from
     23 // third parties.  Title and ownership, including all intellectual property
     24 // rights in and to the Software shall remain with PacketVideo Corporation
     25 // and NTT DoCoMo, Inc.
     26 //
     27 // -----------------------------------------------------------------------
     28 
     29 #include "h223.h"
     30 #include "tsc_h324m_config.h"
     31 #include "tsc_component.h"
     32 #include "tsc_constants.h"
     33 #include "tsc_statemanager.h"
     34 #include "tsc_capability.h"
     35 #include "tsc_lc.h"
     36 #include "tsc_blc.h"
     37 #include "tsc_clc.h"
     38 #include "tsc_channelcontrol.h"
     39 #include "tsc_mt.h"
     40 #ifdef MEM_TRACK
     41 #include "oscl_mem.h"
     42 #include "oscl_mem_audit.h"
     43 #endif
     44 
     45 
     46 
     47 #define PV_2WAY_TSC_WAIT_FOR_OBLC_TIMER_ID "PV_2WAY_TSC_WAIT_FOR_OBLC_TIMER"
     48 #define PV_2WAY_TSC_WAIT_FOR_OBLC_TIMER_INTERVAL 1 /* 1 s */
     49 
     50 #define TSC_MAX_OUTSTANDING_PREFMSG_PDUS 32
     51 
     52 
     53 TSC_component::TSC_component(TSC_statemanager& aTSCStateManager,
     54                              TSC_capability& aTSCcapability,
     55                              TSC_lc& aTSClc,
     56                              TSC_blc& aTSCblc,
     57                              TSC_clc& aTSCclc,
     58                              TSC_mt& aTSCmt):
     59         iTSCstatemanager(aTSCStateManager),
     60         iTSCcapability(aTSCcapability),
     61         iTSClc(aTSClc),
     62         iTSCblc(aTSCblc),
     63         iTSCclc(aTSCclc),
     64         iTSCmt(aTSCmt),
     65         iH245(NULL),
     66         iH223(NULL),
     67         iLocalTcs(NULL),
     68         iWaitingForOblcTimer(NULL),
     69         iOutgoingChannelConfig(NULL),
     70         iIncomingChannelConfig(NULL),
     71         iTSCObserver(NULL),
     72         iTSCchannelcontrol(iOlcs, aTSCStateManager, aTSCblc,
     73                            aTSCmt, aTSClc, aTSCcapability, aTSCclc, *this)
     74 {
     75     iLogger = PVLogger::GetLoggerObject("3g324m.h245user");
     76     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
     77                     (0, "TSC_component::TSC_component"));
     78 
     79 }
     80 
     81 void TSC_component::SetMembers(H245* aH245, H223* aH223, TSCObserver* aTSCObserver)
     82 {
     83     iTSCObserver = aTSCObserver;
     84     iTSCchannelcontrol.SetMembers(aH223, aTSCObserver);
     85     iH245 = aH245;
     86     iH223 = aH223;
     87     MembersSet();
     88 }
     89 
     90 
     91 void TSC_component::InitVarsSession()
     92 {
     93     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
     94                     (0, "TSC_component::InitVarsSession"));
     95     iRemoteAl1Audio = OFF;
     96     iRemoteAl2Audio = OFF;
     97     iRemoteAl3Audio = OFF;
     98     iRemoteAl1Video = OFF;
     99     iRemoteAl2Video = OFF;
    100     iRemoteAl3Video = OFF;
    101     iVideoLayer = PVT_AL_UNKNOWN;
    102     if (iLocalTcs)
    103     {
    104         Delete_TerminalCapabilitySet(iLocalTcs);
    105         OSCL_DEFAULT_FREE(iLocalTcs);
    106         iLocalTcs = NULL;
    107     }
    108     iRemoteTcs.Unbind();
    109 
    110     iOlcs.SetCurrLcn(FIRST_OUTGOING_LCN);
    111 }
    112 
    113 void TSC_component::InitVarsLocal()
    114 {
    115     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    116                     (0, "TSC_component::InitVarsLocal"));
    117     iAl3ControlFieldOctets = DEFAULT_AL3_CONTROL_FIELD_OCTETS;
    118     iAl2WithSn = true;
    119 
    120     iAllowAl1Video = ON;
    121     iAllowAl2Video = ON;
    122     iAllowAl3Video = ON;
    123     iAllowAl1Audio = OFF;
    124     iAllowAl2Audio = ON;
    125     iAllowAl3Audio = OFF;
    126     iUseAl1Video = true;
    127     iUseAl2Video = true;
    128     iUseAl3Video = true;
    129 }
    130 
    131 void TSC_component::InitTsc()
    132 {
    133     iWaitingForOblcTimer = OSCL_NEW(OsclTimer<OsclMemAllocator>,
    134                                     (PV_2WAY_TSC_WAIT_FOR_OBLC_TIMER_ID, PV_2WAY_TSC_WAIT_FOR_OBLC_TIMER_INTERVAL));
    135     iWaitingForOblcTimer->SetObserver(this);
    136 }
    137 
    138 void TSC_component::ResetTsc()
    139 {
    140     if (iOutgoingChannelConfig)
    141     {
    142         OSCL_DELETE(iOutgoingChannelConfig);
    143         iOutgoingChannelConfig = NULL;
    144     }
    145 
    146     if (iIncomingChannelConfig)
    147     {
    148         OSCL_DELETE(iIncomingChannelConfig);
    149         iIncomingChannelConfig = NULL;
    150     }
    151 
    152     if (iWaitingForOblcTimer)
    153     {
    154         iWaitingForOblcTimer->Clear();
    155         OSCL_DELETE(iWaitingForOblcTimer);
    156         iWaitingForOblcTimer = NULL;
    157     }
    158 }
    159 
    160 void TSC_component::Disconnect()
    161 {
    162 
    163     iWaitingForOblcTimer->Clear();
    164 }
    165 
    166 CPVMultiplexEntryDescriptor* TSC_component::GenerateSingleDescriptor(uint8 entry_num,
    167         TPVChannelId lcn1)
    168 {
    169     PS_MultiplexEntryDescriptor h245_desc =
    170         (PS_MultiplexEntryDescriptor)OSCL_DEFAULT_MALLOC(sizeof(S_MultiplexEntryDescriptor));
    171     h245_desc->multiplexTableEntryNumber = entry_num;
    172     h245_desc->option_of_elementList = true;
    173     h245_desc->size_of_elementList = 1;
    174     h245_desc->elementList =
    175         (PS_MultiplexElement)OSCL_DEFAULT_MALLOC(sizeof(S_MultiplexElement));
    176 
    177     PS_MultiplexElement elem =  h245_desc->elementList;
    178     elem->muxType.index = 0; // logical channel = 0, 1 = sub-elem list
    179     elem->muxType.logicalChannelNumber = (uint16)lcn1;
    180     elem->muxType.size = 1; // size of element list
    181     elem->repeatCount.index = 1; // ucf
    182     elem->repeatCount.finite = 0;
    183 
    184     CPVMultiplexEntryDescriptor* ret =
    185         CPVMultiplexEntryDescriptor::NewL(h245_desc, 128);
    186     Delete_MultiplexEntryDescriptor(h245_desc);
    187     OSCL_DEFAULT_FREE(h245_desc);
    188 
    189     return ret;
    190 }
    191 
    192 PS_AdaptationLayerType
    193 TSC_component::GetOutgoingLayer(PV2WayMediaType media_type, uint32 max_sample_size)
    194 {
    195     PS_AdaptationLayerType al_type =
    196         (PS_AdaptationLayerType)OSCL_DEFAULT_MALLOC(sizeof(S_AdaptationLayerType));
    197     int room_for_sn = 0;
    198 
    199     oscl_memset(al_type, 0, sizeof(S_AdaptationLayerType));
    200     uint32 max_sdu_size = 0;
    201     switch (media_type)
    202     {
    203         case PV_AUDIO:
    204             if (iRemoteAl2Audio)
    205             {
    206                 max_sdu_size = iH223->GetSduSize(OUTGOING, E_EP_MEDIUM);
    207                 room_for_sn = max_sdu_size - max_sample_size - 1; /* 1 byte for CRC */
    208                 room_for_sn = (room_for_sn > 1) ? 1 : room_for_sn;
    209                 if (room_for_sn >= 0)
    210                 {
    211                     al_type->index = (uint16)(3 + room_for_sn);
    212                     return al_type;
    213                 }
    214             }
    215             if (iRemoteAl3Audio)
    216             {
    217                 max_sdu_size = iH223->GetSduSize(OUTGOING, E_EP_HIGH);
    218                 room_for_sn = max_sdu_size - max_sample_size - 2; /* 2 bytes for CRC */
    219                 if (room_for_sn >= 0)
    220                 {
    221                     PS_Al3 al3 = (PS_Al3)OSCL_DEFAULT_MALLOC(sizeof(S_Al3));
    222                     al3->controlFieldOctets = (int8)((room_for_sn >
    223                                                       (int)iAl3ControlFieldOctets) ? iAl3ControlFieldOctets : room_for_sn);
    224                     al3->sendBufferSize = DEF_AL3_SEND_BUFFER_SIZE;
    225                     al_type->index = 5;
    226                     al_type->al3 = al3;
    227                     return al_type;
    228                 }
    229             }
    230             if (iRemoteAl1Audio)
    231             {
    232                 max_sdu_size = iH223->GetSduSize(OUTGOING, E_EP_LOW);
    233                 room_for_sn = max_sdu_size - max_sample_size;
    234                 room_for_sn = (room_for_sn > 1) ? 1 : room_for_sn;
    235                 if (max_sdu_size >= max_sample_size)
    236                 {
    237                     al_type->index = 1;
    238                     return al_type;
    239                 }
    240             }
    241             break;
    242         case PV_VIDEO:
    243             if (iUseAl2Video && iRemoteAl2Video)
    244             {
    245                 al_type->index = (uint16)(iAl2WithSn ? 4 : 3);
    246                 return al_type;
    247             }
    248             if (iUseAl3Video && iRemoteAl3Video)
    249             {
    250                 PS_Al3 al3 = (PS_Al3)OSCL_DEFAULT_MALLOC(sizeof(S_Al3));
    251                 al3->controlFieldOctets = (int8)iAl3ControlFieldOctets;
    252                 al3->sendBufferSize = DEF_AL3_SEND_BUFFER_SIZE;
    253                 al_type->index = 5;
    254                 al_type->al3 = al3;
    255                 return al_type;
    256             }
    257             if (iUseAl1Video && iRemoteAl1Video)
    258             {
    259                 al_type->index = 1;
    260                 return al_type;
    261             }
    262             break;
    263         default:
    264             break;
    265     }
    266     OSCL_DEFAULT_FREE(al_type);
    267     return NULL;
    268 }
    269 
    270 void TSC_component::SetAlConfig(PV2WayMediaType media_type,
    271                                 TPVAdaptationLayer layer,
    272                                 bool allow)
    273 {
    274     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    275                     (0, "TSC_component::SetAlConfig"));
    276     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    277                     (0, "TSC_component::SetAlConfig media type(%d), layer(%d), allow(%d)",
    278                      media_type, layer, allow));
    279 
    280     switch (media_type)
    281     {
    282         case PV_AUDIO:
    283             if (layer == PVT_AL1)
    284                 iAllowAl1Audio = allow;
    285             else if (layer == PVT_AL2)
    286                 iAllowAl2Audio = allow;
    287             else if (layer == PVT_AL3)
    288                 iAllowAl3Audio = allow;
    289             break;
    290         case PV_VIDEO:
    291             if (layer == PVT_AL1)
    292                 iAllowAl1Video = allow;
    293             else if (layer == PVT_AL2)
    294                 iAllowAl2Video = allow;
    295             else if (layer == PVT_AL3)
    296                 iAllowAl3Video = allow;
    297             break;
    298         case PV_DATA:
    299         default:
    300             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    301                             (0, "TSC_component::SetAlConfig Invalid media type"));
    302     }
    303 }
    304 
    305 //////////////////////////////////////////////////////////////////////////
    306 // Start the CE process by sending this terminals capabilites to the peer terminal
    307 //////////////////////////////////////////////////////////////////////////
    308 bool TSC_component::CEStart()
    309 {
    310     if (!iIncomingChannelConfig || !iIncomingChannelConfig->size())
    311     {
    312         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    313                         (0, "TSC_component::CEStart- Incoming channel config not set"));
    314         return false;
    315     }
    316 
    317     iTSCstatemanager.WriteState(TSC_CE_SEND, STARTED);
    318 
    319     MultiplexCapabilityInfo mux_cap_info;
    320     mux_cap_info.iAllowAl1Video = iAllowAl1Video;
    321     mux_cap_info.iAllowAl2Video = iAllowAl2Video;
    322     mux_cap_info.iAllowAl3Video = iAllowAl3Video;
    323     mux_cap_info.iAllowAl1Audio = iAllowAl1Audio;
    324     mux_cap_info.iAllowAl2Audio = iAllowAl2Audio;
    325     mux_cap_info.iAllowAl3Audio = iAllowAl3Audio;
    326     mux_cap_info.iMaximumAl2SDUSize = iH223->GetSduSize(INCOMING, E_EP_MEDIUM);
    327     mux_cap_info.iMaximumAl3SDUSize = iH223->GetSduSize(INCOMING, E_EP_HIGH);
    328     Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator> outgoing_codecs;
    329     Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator> incoming_codecs;
    330     for (unsigned n = 0; n < iIncomingChannelConfig->size(); n++)
    331     {
    332         Oscl_Vector<FormatCapabilityInfo, OsclMemAllocator>* codecs =
    333             (*iIncomingChannelConfig)[n].GetCodecs();
    334         if (!codecs)
    335         {
    336             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    337                             (0, "TSC_component::CEStart No codecs specified for format type(%d)",
    338                              (*iIncomingChannelConfig)[n].GetMediaType()));
    339             continue;
    340         }
    341         for (unsigned m = 0; m < codecs->size(); m++)
    342         {
    343             CodecCapabilityInfo* info = NULL;
    344             PVCodecType_t codec_type = PVMFFormatTypeToPVCodecType((*codecs)[m].format);
    345             TPVDirection dir = (*codecs)[m].dir;
    346             if (GetMediaType(codec_type) == PV_VIDEO)
    347             {
    348                 info = new VideoCodecCapabilityInfo;
    349                 ((VideoCodecCapabilityInfo*)info)->resolutions =
    350                     iTSCcapability.GetResolutions(dir);
    351             }
    352             else
    353             {
    354                 info = new CodecCapabilityInfo;
    355             }
    356             info->codec = codec_type;
    357             info->dir = dir;
    358             incoming_codecs.push_back(info);
    359         }
    360     }
    361     if (iLocalTcs)
    362     {
    363         Delete_TerminalCapabilitySet(iLocalTcs);
    364         OSCL_DEFAULT_FREE(iLocalTcs);
    365         iLocalTcs = NULL;
    366     }
    367     iLocalTcs = GenerateTcs(mux_cap_info, outgoing_codecs, incoming_codecs);
    368     CustomGenerateTcs(iLocalTcs);
    369 
    370     CE* Ce = iH245->GetCE();
    371     if (Ce) Ce->TransferRequest(iLocalTcs);
    372 
    373     for (unsigned i = 0; i < incoming_codecs.size(); i++)
    374     {
    375         delete incoming_codecs[i];
    376     }
    377     return true;
    378 }
    379 
    380 TPVStatusCode TSC_component::SetTerminalParam(CPVTerminalParam& params)
    381 {
    382     CPVH324MParam* h324params = (CPVH324MParam*) & params;
    383     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    384                     (0, "TSC_component:SetTerminalParam - AL1(%d), AL2(%d), AL3(%d)",
    385                      h324params->iAllowAl1Video,
    386                      h324params->iAllowAl2Video,
    387                      h324params->iAllowAl3Video));
    388 
    389     iAllowAl1Video = h324params->iAllowAl1Video;
    390     iAllowAl2Video = h324params->iAllowAl2Video;
    391     iAllowAl3Video = h324params->iAllowAl3Video;
    392     iUseAl1Video = h324params->iUseAl1Video;
    393     iUseAl2Video = h324params->iUseAl2Video;
    394     iUseAl3Video = h324params->iUseAl3Video;
    395 
    396     iVideoLayer = h324params->iVideoLayer;
    397 
    398     return EPVT_Success;
    399 }
    400 
    401 void TSC_component::GetTerminalParam(CPVH324MParam& ah324param)
    402 {
    403     ah324param.iAllowAl1Video = iAllowAl1Video ? true : false;
    404     ah324param.iAllowAl2Video = iAllowAl2Video ? true : false;
    405     ah324param.iAllowAl3Video = iAllowAl3Video ? true : false;
    406     ah324param.iVideoLayer = iVideoLayer;
    407 }
    408 
    409 bool TSC_component::IsSupported(TPVDirection dir,
    410                                 PVCodecType_t codec,
    411                                 FormatCapabilityInfo& capability_info)
    412 {
    413     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    414                     (0, "TSC_component::IsSupported dir(%d), codec(%d)", dir, codec));
    415     if (codec == PV_CODEC_TYPE_NONE)
    416     {
    417         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    418                         (0, "TSC_component::IsSupported No codec is always ok"));
    419         return true;
    420     }
    421     Oscl_Vector<H324ChannelParameters, PVMFTscAlloc>* config = (dir == OUTGOING) ?
    422             iOutgoingChannelConfig : iIncomingChannelConfig;
    423     if (!config)
    424     {
    425         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    426                         (0, "TSC_component::IsSupported No config available"));
    427         return false;
    428     }
    429     for (unsigned n = 0; n < config->size(); n++)
    430     {
    431         H324ChannelParameters& param = (*config)[n];
    432         if (param.GetMediaType() != GetMediaType(codec))
    433             continue;
    434         Oscl_Vector<FormatCapabilityInfo, OsclMemAllocator>* codecs = param.GetCodecs();
    435         if (!codecs)
    436         {
    437             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    438                             (0, "TSC_component::IsSupported No codecs specified"));
    439             return false;
    440         }
    441         for (unsigned m = 0; m < codecs->size(); m++)
    442         {
    443             if ((*codecs)[m].format == PVCodecTypeToPVMFFormatType(codec))
    444             {
    445                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    446                                 (0, "TSC_component::IsSupported Match found"));
    447                 capability_info = (*codecs)[m];
    448                 return true;
    449             }
    450         }
    451     }
    452     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    453                     (0, "TSC_component::IsSupported No match found"));
    454     return false;
    455 }
    456 
    457 bool TSC_component::IsSupported(TPVDirection dir,
    458                                 PV2WayMediaType media_type,
    459                                 CodecCapabilityInfo& codec_info)
    460 {
    461     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    462                     (0, "TSC_component::IsSupported dir(%d), media_type(%d)", dir, media_type));
    463     if (media_type == PV_MEDIA_NONE)
    464     {
    465         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    466                         (0, "TSC_component::IsSupported No media is always ok"));
    467         return true;
    468     }
    469     Oscl_Vector<H324ChannelParameters, PVMFTscAlloc>* config = (dir == OUTGOING) ?
    470             iOutgoingChannelConfig : iIncomingChannelConfig;
    471     if (!config)
    472     {
    473         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    474                         (0, "TSC_component::IsSupported No config available"));
    475         return false;
    476     }
    477     for (unsigned n = 0; n < config->size(); n++)
    478     {
    479         H324ChannelParameters& param = (*config)[n];
    480         if (param.GetMediaType() != media_type)
    481             continue;
    482         Oscl_Vector<FormatCapabilityInfo, OsclMemAllocator>* codecs = param.GetCodecs();
    483         if (!codecs)
    484         {
    485             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    486                             (0, "TSC_component::IsSupported No codecs specified"));
    487             return false;
    488         }
    489         codec_info.codec = PVMFFormatTypeToPVCodecType((*codecs)[0].format);
    490         codec_info.dir = (*codecs)[0].dir;
    491         return true;
    492     }
    493     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    494                     (0, "TSC_component::IsSupported No match found"));
    495     return false;
    496 }
    497 ////////////////////////////////////////////////////////////////////////////
    498 // ExtractTcsParameters()                       (RAN-32K)
    499 //
    500 // This routine takes the incoming TerminalCapabilitySet
    501 //   and extracts the following useful parameters:
    502 //      {h263_qcifMPI, h263_maxBitRate, mpeg4_maxBitRate}
    503 // The parameters are stored in globals and may be sent
    504 //   later to the application.
    505 ////////////////////////////////////////////////////////////////////////////
    506 void TSC_component::ExtractTcsParameters(PS_TerminalCapabilitySet pTcs)
    507 {
    508     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    509                     (0, "TSC_component::ExtractTcsParameters"));
    510 
    511     if (pTcs->option_of_multiplexCapability)
    512     {
    513         PS_MultiplexCapability muxcaps = &pTcs->multiplexCapability;
    514         if (muxcaps->index == 2)
    515         {
    516 
    517             PS_H223Capability h223caps = muxcaps->h223Capability;
    518             iRemoteAl1Audio = h223caps->audioWithAL1;
    519             iRemoteAl2Audio = h223caps->audioWithAL2;
    520             iRemoteAl3Audio = h223caps->audioWithAL3;
    521             iRemoteAl1Video = h223caps->videoWithAL1;
    522             iRemoteAl2Video = h223caps->videoWithAL2;
    523             iRemoteAl3Video = h223caps->videoWithAL3;
    524             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    525                             (0, "TSC_component::ExtractTcsParameters Remote audio caps AL1(%d), AL2(%d), AL3(%d)",
    526                              iRemoteAl1Audio, iRemoteAl2Audio, iRemoteAl3Audio));
    527             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    528                             (0, "TSC_component::ExtractTcsParameters Remote video caps AL1(%d), AL2(%d), AL3(%d)",
    529                              iRemoteAl1Video, iRemoteAl2Video, iRemoteAl3Video));
    530             // -------------------------------------
    531             // Decide which Video Layer to use (RAN)
    532             // -------------------------------------
    533             /* If both terminals support AL2, use AL2 */
    534             if (iUseAl2Video && iRemoteAl2Video)
    535             {
    536                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    537                                 (0, "TSC_component::ExtractTcsParameters Video Layer Decision is AL2"));
    538                 iVideoLayer = PVT_AL2;
    539             }
    540             /* If not, check for mutual AL3 support */
    541             else if (iUseAl3Video && iRemoteAl3Video)
    542             {
    543                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    544                                 (0, "TSC_component::ExtractTcsParameters Video Layer Decision is AL3"));
    545                 iVideoLayer = PVT_AL3;
    546             }
    547             /* If not, check for mutual AL1 support */
    548             else if (iUseAl1Video && iRemoteAl1Video)
    549             {
    550                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    551                                 (0, "TSC_component::ExtractTcsParameters Video Layer Decision is AL1"));
    552                 iVideoLayer = PVT_AL1;
    553             }
    554         }
    555     }
    556 }
    557 
    558 ////////////////////////////////////////////////////////////////////////
    559 // CE User - Transfer.Indication primitive received from H.245
    560 ////////////////////////////////////////////////////////////////////////
    561 void TSC_component::CETransferIndication(OsclSharedPtr<S_TerminalCapabilitySet> tcs,
    562         uint32 aTerminalStatus)
    563 {
    564     if (aTerminalStatus == PhaseD_CSUP)
    565     {
    566         iRemoteTcs = tcs;
    567     }
    568 
    569     else if (aTerminalStatus == PhaseE_Comm)
    570     {
    571         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    572                         (0, "TSC_component::CETransferIndication TCS received during PhaseE_Comm"));
    573         if (tcs->option_of_multiplexCapability)
    574         {
    575             /* Save any required CE data */
    576             iRemoteAl2Video =
    577                 tcs->multiplexCapability.h223Capability->videoWithAL2;
    578             iRemoteAl3Video =
    579                 tcs->multiplexCapability.h223Capability->videoWithAL3;
    580         }
    581     }
    582 }
    583 
    584 // ========================================================
    585 // SetAl2Al3VideoFlags()                              (RAN)
    586 //
    587 // New API from application layer.  Sets the flags as follows:
    588 //   INPUT      gAllowAl2Video      gAllowAl3Video
    589 //     0               ON                 OFF
    590 //     1               OFF                ON
    591 //     2               ON                 ON
    592 // ========================================================
    593 void TSC_component::SetAl2Al3VideoFlags(int32 userInput)
    594 {
    595     iAllowAl2Video = iAllowAl3Video = ON;
    596     if (userInput == 0)
    597     {
    598         iAllowAl3Video = OFF;
    599     }
    600     else if (userInput == 1)
    601     {
    602         iAllowAl2Video = OFF;
    603     }
    604 }
    605 
    606 // ========================================================
    607 // GetAl2Al3VideoFlags()                              (RAN)
    608 //
    609 // Complements SetAl2Al3VideoFlags()
    610 // ========================================================
    611 int32 TSC_component::GetAl2Al3VideoFlags(void)
    612 {
    613     return(iAllowAl2Video + 2 * iAllowAl3Video - 1);
    614 }
    615 
    616 ////////////////////////////////////////////////
    617 //
    618 ////////////////////////////////////////////////
    619 Oscl_Vector < H324ChannelParameters,
    620 PVMFTscAlloc > * TSC_component::GetChannelConfig(TPVDirection dir)
    621 {
    622     if (dir == OUTGOING)
    623     {
    624         return iOutgoingChannelConfig;
    625     }
    626     return iIncomingChannelConfig;
    627 }
    628 
    629 void TSC_component::SetAl3ControlFieldOctets(unsigned cfo)
    630 {
    631     iAl3ControlFieldOctets = cfo;
    632 }
    633 
    634 void TSC_component::SetAl2Sn(int width)
    635 {
    636     iAl2WithSn = width ? true : false;
    637 }
    638 
    639 
    640 /*****************************************************************************/
    641 /*  function name        : LcEtbIdc           E_PtvId_Lc_Etb_Idc  */
    642 /*  function outline     : Status04/Event09 procedure                        */
    643 /*  function discription : Status04Event09( pReceiveInf )                */
    644 /*  input data           : PS_ControlMsgHeader         Receive InfHeader Pointer    */
    645 /*  output data          : uint32                 Terminal Status              */
    646 /*  draw time            : '96.10.09                                         */
    647 /*---------------------------------------------------------------------------*/
    648 /*  amendment career(x)  :                                                   */
    649 /*                                                                           */
    650 /*              Copyright (C) 1996 NTT DoCoMo                                */
    651 /*****************************************************************************/
    652 uint32 TSC_component::LcEtbIdc(PS_ControlMsgHeader  pReceiveInf)
    653 {
    654     TPVChannelId OpenLcn = (TPVChannelId)pReceiveInf->InfSupplement1 +
    655                            TSC_INCOMING_CHANNEL_MASK;
    656     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    657                     (0, "TSC_component::LcEtbIdc lcn(%d)", OpenLcn));
    658     PS_ForwardReverseParam pLcParam = (PS_ForwardReverseParam) pReceiveInf->pParameter;
    659     /* validate forRevParams */
    660     PVMFStatus forRevCheck = iTSCcapability.ValidateForwardReverseParams(pLcParam, INCOMING);
    661     if (forRevCheck != PVMFSuccess)
    662     {
    663         PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_EMERG,
    664                         (0, "TSC_component::LcEtbIdc ERROR  - Incoming forRevParams not supported.  Rejecting."));
    665         uint16 reason = (uint16)((forRevCheck == PVMFErrNotSupported) ? 2/* dataTypeNotSupported */ : 0/*unspecified*/);
    666         TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcn, reason);
    667         RemoveOlc(dir, OpenLcn);
    668         return PhaseE_Comm;
    669     }
    670     PS_H223LogicalChannelParameters pH223Lcp =
    671         pLcParam->forwardLogicalChannelParameters.multiplexParameters.h223LogicalChannelParameters;
    672     PS_DataType pDataType = &pLcParam->forwardLogicalChannelParameters.dataType;
    673     PV2WayMediaType media_type  = PV_MEDIA_NONE;
    674     PVCodecType_t incoming_codec_type = PV_CODEC_TYPE_NONE;
    675 
    676     incoming_codec_type = ::GetCodecType(pDataType);
    677     media_type = ::GetMediaType(pDataType);
    678     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    679                     (0, "TSC_component::LcEtbIdc lcn(%d), media type(%d), codec type(%d)",
    680                      OpenLcn, media_type, incoming_codec_type));
    681 
    682     OlcKey key(INCOMING, OpenLcn);
    683 
    684     if (iOlcs.count(key))
    685     {
    686         if (iOlcs[key]->GetState() == OLC_ESTABLISHED)
    687         {
    688             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    689                             (0, "TSC_component::LcEtbIdc Established incoming OLC found for same channel id. Rejecting OLC(%d)",
    690                              media_type, OpenLcn));
    691             TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcn, 0);  // unspecified
    692             RemoveOlc(dir, OpenLcn);
    693             return PhaseE_Comm;
    694         }
    695         else
    696         {
    697             ReleasePendingIncomingChannel(OpenLcn);
    698         }
    699     }
    700 
    701     /* pending incoming OLC for the same media type */
    702     Oscl_Vector<OlcParam*, OsclMemAllocator> pending_olc_list;
    703     // Search for pending and established channels
    704     if (iOlcs.FindOlcs(INCOMING, media_type, OLC_PENDING | OLC_ESTABLISHED,
    705                        pending_olc_list))
    706     {
    707         for (unsigned i = 0; i < pending_olc_list.size(); i++)
    708         {
    709             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    710                             (0, "TSC_component::LcEtbIdc Pending incoming OLC found for media type=%d, lcn=%d",
    711                              media_type, pending_olc_list[i]->GetChannelId()));
    712             if (!ReleasedPendingIncomingChannel(pending_olc_list[i]))
    713             {
    714                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    715                                 (0, "TSC_component::LcEtbIdc Established incoming OLC found for same media type. Rejecting OLC(%d)",
    716                                  media_type, OpenLcn));
    717                 TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcn, 0); /* unspecified */
    718                 RemoveOlc(dir, OpenLcn);
    719                 return PhaseE_Comm;
    720             }
    721         }
    722     }
    723 
    724     OlcParam* pending_outgoing_olc = NULL;
    725     PVCodecType_t to_be_opened_codec = PV_CODEC_TYPE_NONE;
    726 
    727     // Add pending olc to list
    728     iOlcs.AppendOlc(INCOMING, OpenLcn, pDataType, pH223Lcp);
    729     // is there is a pending outgoing OLC for the same media type ?
    730     if (iOlcs.FindOlcs(OUTGOING, media_type, OLC_PENDING, pending_olc_list))
    731     {
    732         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    733                         (0, "TSC_component::LcEtbIdc Pending outgoing OLCs(%d) found for incoming media type(%d).",
    734                          pending_olc_list.size(), media_type, OpenLcn));
    735         OSCL_ASSERT(pending_olc_list.size() == 1);
    736         OlcParam* param = pending_outgoing_olc = pending_olc_list[0];
    737         if (param->GetDirectionality() == EPVT_BI_DIRECTIONAL)
    738         {
    739             pending_outgoing_olc = NULL;
    740             // There is an OLC/OBLC conflict
    741             if (iTSCstatemanager.ReadState(TSC_MSD_DECISION) == MASTER)
    742             {
    743                 // We are master, hence we reject the OLC
    744                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    745                                 (0, "TSC_component::LcEtbIdc BLC Already initiated by local. Rejecting OLC cause we are Master"));
    746                 TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcn, 10);  // Master slave conflict
    747                 RemoveOlc(dir, OpenLcn);
    748                 return PhaseE_Comm;
    749             }
    750             else  // We are Slave
    751             {
    752                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    753                                 (0, "TSC_component::LcEtbIdc BLC Already initiated by local. Closing BLC cause we are Slave"));
    754                 to_be_opened_codec = GetCodecType(param->GetForwardParams()->GetDataType());;
    755                 // Release the pending blc
    756                 iTSCblc.BlcRlsReq(RELEASE_CLOSE, param->GetChannelId(), 0);
    757                 ChannelReleased(OUTGOING, param->GetChannelId(), PVMFErrCancelled);
    758                 // Logical channel will be deleted from the mux when the engine calls ReleasePort
    759             }
    760         }
    761     }
    762 
    763 
    764     PVMFStatus tscCheck = ValidateOlcsWithTcs();
    765     if (tscCheck != PVMFSuccess)
    766     {
    767         if (pending_outgoing_olc)
    768         {
    769             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    770                             (0, "TSC_component::LcEtbIdc pending olcs."));
    771             if (iTSCstatemanager.ReadState(TSC_MSD_DECISION) == MASTER)
    772             {
    773                 // We are master, hence we reject the incoming OLC with code M/S conflict
    774                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    775                                 (0, "TSC_component::LcEtbIdc TCS violated with pending olcs from Master."));
    776                 TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcn, 10);  // Master slave conflict
    777                 RemoveOlc(dir, OpenLcn);
    778                 return PhaseE_Comm;
    779             }
    780             /* We should close the conflicting codec and reopen a replacement.  Assumption here is that the
    781                conflict is due to the media type of the current incoming channel.  This will not work if there
    782                are symmetry inter-dependencies between audio and video codecs in the TCS.  */
    783             pending_outgoing_olc->GetForwardParams()->GetBitrate();
    784             iTSClc.LcRlsReq(RELEASE_CLOSE,
    785                             pending_outgoing_olc->GetChannelId(), 0);
    786             ChannelReleased(OUTGOING,
    787                             pending_outgoing_olc->GetChannelId(), PVMFErrCancelled);
    788             FormatCapabilityInfo codec_caps;
    789             if (IsSupported(OUTGOING, incoming_codec_type, codec_caps))
    790             {
    791                 /* Verify if the capability sets can support it */
    792                 TPVChannelId tmp_lcn = iOlcs.GetNextAvailLcn();
    793                 iOlcs.AppendOlc(OUTGOING, tmp_lcn, pDataType, pH223Lcp);
    794                 if (ValidateOlcsWithTcs() == PVMFSuccess)
    795                 {
    796                     to_be_opened_codec = incoming_codec_type;
    797                 }
    798                 else
    799                 {
    800                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    801                                     (0, "TSC_component::LcEtbIdc Cannot open a replacement channel as incoming codec is not supported"));
    802                 }
    803                 RemoveOlc(OUTGOING, tmp_lcn);
    804             }
    805             else
    806             {
    807                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    808                                 (0, "TSC_component::LcEtbIdc Incoming codec not supported for transmit"));
    809             }
    810         }
    811         else
    812         {
    813             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    814                             (0, "TSC_component::LcEtbIdc no pending olcs."));
    815             // There were no pending OLCs from the local terminal.
    816             TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcn, 3);  // dataTypeNotAvailable
    817             RemoveOlc(dir, OpenLcn);
    818             return PhaseE_Comm;
    819         }
    820     }
    821 
    822     int leave_status = OpenLogicalChannel(OpenLcn, pDataType, pH223Lcp);
    823     if (leave_status != 0)
    824     {
    825         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    826                         (0, "TSC_component::LcEtbIdc - Memory Allocation Failed."));
    827         return leave_status;
    828     }
    829 
    830     uint8* fsi = NULL;
    831     uint32 fsi_len = ::GetFormatSpecificInfo(pDataType, fsi);
    832     iTSCObserver->IncomingChannel(OpenLcn, incoming_codec_type, fsi, fsi_len);
    833 
    834     // ESTABLISH.response(LC) Primitive Send
    835     iTSClc.LcEtbRps(OpenLcn);
    836 
    837     SetCustomMultiplex(pReceiveInf, media_type);
    838     if (to_be_opened_codec == PV_CODEC_TYPE_NONE)
    839         return PhaseE_Comm;
    840     FormatCapabilityInfo fci;
    841     IsSupported(OUTGOING, to_be_opened_codec, fci);
    842     PS_AdaptationLayerType al_type = GetOutgoingLayer(media_type, fci.max_sample_size);
    843     if (al_type == NULL)
    844     {
    845         OSCL_LEAVE(PVMFErrNoMemory);
    846     }
    847     OpenOutgoingChannel(to_be_opened_codec, al_type);
    848     Delete_AdaptationLayerType(al_type);
    849     OSCL_DEFAULT_FREE(al_type);
    850     iTSCmt.MtTrfReq(iOlcs);
    851     return PhaseE_Comm;
    852 }
    853 
    854 uint32 TSC_component::OpenLogicalChannel(TPVChannelId OpenLcn,
    855         PS_DataType pDataType,
    856         PS_H223LogicalChannelParameters pH223Lcp)
    857 {
    858     int leave_status = 0;
    859     OlcParam* param = NULL;
    860     OSCL_TRY(leave_status, param = OpenLogicalChannel(INCOMING,
    861                                    OpenLcn, CHANNEL_ID_UNKNOWN, pDataType, pH223Lcp));
    862     OSCL_FIRST_CATCH_ANY(leave_status, void());
    863     if (leave_status != 0)
    864     {
    865         TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcn, 0);  // unspecified
    866         RemoveOlc(dir, OpenLcn);
    867         return PhaseE_Comm;
    868     }
    869     param->SetState(OLC_ESTABLISHED);
    870     return leave_status;
    871 }
    872 
    873 /*****************************************************************************/
    874 /*  function name        : Status04Event14          E_PtvId_Blc_Etb_Idc  */
    875 /*  function outline     : Status04/Event14 procedure                        */
    876 /*  function discription : Status04Event14( pReceiveInf )                */
    877 /*  input data           : PS_ControlMsgHeader         Receive InfHeader Pointer    */
    878 /*  output data          : uint32                 Terminal Status              */
    879 /*  draw time            : '96.10.09                                         */
    880 /*---------------------------------------------------------------------------*/
    881 /*  amendment career(x)  :                                                   */
    882 /*                                                                           */
    883 /*              Copyright (C) 1996 NTT DoCoMo                                */
    884 /*****************************************************************************/
    885 uint32 TSC_component::BlcEtbIdc(PS_ControlMsgHeader  pReceiveInf)
    886 {
    887     TPVChannelId OpenLcnB = pReceiveInf->InfSupplement1 + TSC_INCOMING_CHANNEL_MASK; /* incoming lcn */
    888     TPVChannelId OpenLcnF = CHANNEL_ID_UNKNOWN; /* outgoing lcn */
    889     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    890                     (0, "TSC_component::BlcEtbIdc lcn(%d)", OpenLcnB));
    891     /* Function prototypes */
    892     uint8* GetDecoderConfigFromOLC(PS_ForwardReverseParam pPara, uint32 forRev, uint16 *nOctets);
    893     PS_ForwardReverseParam forRevParams = (PS_ForwardReverseParam)pReceiveInf->pParameter;
    894 
    895     /* validate forRevParams */
    896     PVMFStatus forRevCheck = iTSCcapability.ValidateForwardReverseParams(forRevParams, INCOMING);
    897     if (forRevCheck != PVMFSuccess)
    898     {
    899         PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_EMERG,
    900                         (0, "TSC_component::BlcEtbIdc ERROR  - Incoming forRevParams not supported.  Rejecting."));
    901         uint16 reason = (uint16)((forRevCheck == PVMFErrNotSupported) ? 2/* dataTypeNotSupported */ : 0/*unspecified*/);
    902         TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcnB, reason);
    903         RemoveOlc(dir, OpenLcnB);
    904         return PhaseE_Comm;
    905     }
    906 
    907     PS_ForwardLogicalChannelParameters forwardParams = &forRevParams->forwardLogicalChannelParameters;
    908     PS_ReverseLogicalChannelParameters reverseParams = &forRevParams->reverseLogicalChannelParameters;
    909     PVCodecType_t in_codec_type = ::GetCodecType(&forwardParams->dataType);
    910     PVCodecType_t out_codec_type = ::GetCodecType(&reverseParams->dataType);
    911     PV2WayMediaType out_media_type = ::GetMediaType(&reverseParams->dataType);
    912     OSCL_UNUSED_ARG(out_media_type);
    913     PV2WayMediaType in_media_type = ::GetMediaType(&forwardParams->dataType);
    914     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    915                     (0, "TSC_component::BlcEtbIdc in media type(%d), in codec type(%d), out media type(%d), out codec type(%d)", in_media_type, in_codec_type, out_media_type, out_codec_type));
    916 
    917     /* Do we support the outgoing codec ? */
    918     FormatCapabilityInfo codec_caps;
    919     if (!IsSupported(OUTGOING, out_codec_type, codec_caps) ||
    920             !IsSupported(INCOMING, in_codec_type, codec_caps))
    921     {
    922         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    923                         (0, "TSC_component::BlcEtbIdc Outgoing/incoming codec not supported for transmit"));
    924         TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_REJECT, OpenLcnB, 2); /* dataTypeNotSupported */
    925         RemoveOlc(dir, OpenLcnB);
    926         return(PhaseE_Comm);
    927     }
    928 
    929     unsigned outgoing_bitrate = 0;
    930     if (out_codec_type != PV_CODEC_TYPE_NONE)
    931     {
    932         outgoing_bitrate = GetOutgoingBitrate(out_codec_type);
    933         if (outgoing_bitrate <= 0)
    934         {
    935             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    936                             (0, "TSC_component::BlcEtbIdc No bandwidth allocated for outgoing media type(%d)",
    937                              out_media_type));
    938             TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_REJECT, OpenLcnB, 3); /* dataTypeNotAvailable */
    939             RemoveOlc(dir, OpenLcnB);
    940             return PhaseE_Comm ;
    941         }
    942     }
    943 
    944     /* Cancel waiting for OBLC */
    945     if (iWaitingForOblc)
    946     {
    947         if (out_codec_type != iWaitingForOblcCodec)
    948         {
    949             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    950                             (0, "TSC_component::BlcEtbIdc Reverse codec in BLC(%d) does not match iWaitingForOblcCodec(%d)",
    951                              out_codec_type, iWaitingForOblcCodec));
    952         }
    953     }
    954     iWaitingForOblc = false;
    955     iWaitingForOblcTimer->Clear();
    956     iWaitingForOblcCodec = PV_CODEC_TYPE_NONE;
    957 
    958     Oscl_Vector<OlcParam*, OsclMemAllocator> pending_olc_list;
    959     /* Pending incoming OLC for the same media type */
    960     if (iOlcs.FindOlcs(INCOMING, in_media_type, OLC_PENDING | OLC_ESTABLISHED, pending_olc_list))
    961     {
    962         for (unsigned i = 0; i < pending_olc_list.size(); i++)
    963         {
    964             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    965                             (0, "TSC_component::BlcEtbIdc Pending incoming OLC found for media type=%d, lcn=%d",
    966                              in_media_type, pending_olc_list[i]->GetChannelId()));
    967             if (!ReleasedPendingIncomingChannel(pending_olc_list[i]))
    968             {
    969                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    970                                 (0, "TSC_component::BlcEtbIdc Established incoming OLC found for same media type. Rejecting OLC(%d)", in_media_type, OpenLcnB));
    971                 TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_REJECT, OpenLcnB, 0); /* unspecified */
    972                 RemoveOlc(dir, OpenLcnB);
    973                 return PhaseE_Comm;
    974             }
    975 
    976         }
    977     }
    978 
    979     /* if there are established outgoing channels for the same media type, close them */
    980     if (out_codec_type != PV_CODEC_TYPE_NONE &&
    981             iOlcs.FindOlcs(OUTGOING, in_media_type, OLC_ESTABLISHED, pending_olc_list))
    982     {
    983         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    984                         (0, "TSC_component::BlcEtbIdc Established outgoing OLC found for same media type(%d). Closing down the OLCS", in_media_type));
    985         for (unsigned i = 0; i < pending_olc_list.size(); i++)
    986         {
    987             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    988                             (0, "TSC_component::BlcEtbIdc Established outgoing OLC found for media type=%d, lcn=%d",
    989                              in_media_type, pending_olc_list[i]->GetChannelId()));
    990             ChannelReleased(OUTGOING, pending_olc_list[i]->GetChannelId(), PVMFFailure);
    991         }
    992     }
    993 
    994     PVCodecType_t to_be_opened_codec = PV_CODEC_TYPE_NONE;
    995     /* is there is a pending outgoing OLC for the same media type ?*/
    996     if (iOlcs.FindOlcs(OUTGOING, in_media_type, OLC_PENDING, pending_olc_list))
    997     {
    998         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
    999                         (0, "TSC_component::BlcEtbIdc Pending outgoing OLCs(%d) found for incoming media type(%d).",
   1000                          pending_olc_list.size(), in_media_type, OpenLcnB));
   1001         OSCL_ASSERT(pending_olc_list.size() == 1);
   1002         OlcParam* param = pending_olc_list[0];
   1003         if (param->GetDirectionality() == EPVT_BI_DIRECTIONAL || /* Bi-dir: always causes conflict*/
   1004                 out_codec_type != PV_CODEC_TYPE_NONE)  /*Uni-dir: no conflict if reverse params are NULL */
   1005         {
   1006             /* OLCs are conflicting */
   1007             if (iTSCstatemanager.ReadState(TSC_MSD_DECISION) == MASTER)
   1008             {
   1009                 /* We are master, hence we reject the incoming OLC */
   1010                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1011                                 (0, "TSC_component::BlcEtbIdc BLC Already initiated by local. Rejecting OBLC cause we are Master"));
   1012                 TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_REJECT, OpenLcnB, 10);  /* Master slave conflict */
   1013                 RemoveOlc(dir, OpenLcnB);
   1014                 return PhaseE_Comm ;
   1015             }
   1016             /* we are slave */
   1017             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1018                             (0, "TSC_component::BlcEtbIdc LC Already initiated by local. Closing it cause we are Slave"));
   1019             if (out_codec_type == PV_CODEC_TYPE_NONE)
   1020             {
   1021                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1022                                 (0, "TSC_component::BlcEtbIdc Reverse DataType==NULL; Need to open replacement OLC/OBLC"));
   1023                 to_be_opened_codec = GetCodecType(param->GetForwardParams()->GetDataType());
   1024             }
   1025             ReleaseOlc(param, 0);
   1026             ChannelReleased(OUTGOING, param->GetChannelId(), PVMFErrCancelled);
   1027         }
   1028     }
   1029     pending_olc_list.clear();
   1030     /* Generate logical channel number */
   1031     OpenLcnF = iOlcs.GetNextAvailLcn();
   1032     OlcParam* prm = iOlcs.AppendOlc(INCOMING, OpenLcnB,
   1033                                     &forwardParams->dataType,
   1034                                     forwardParams->multiplexParameters.h223LogicalChannelParameters,
   1035                                     OpenLcnF,
   1036                                     &reverseParams->dataType,
   1037                                     reverseParams->rlcMultiplexParameters.h223LogicalChannelParameters);
   1038 
   1039     prm->GetReverseParams()->SetChannelId(OpenLcnF);
   1040     /* Validate the TCS's */
   1041     PVMFStatus tscCheck = ValidateOlcsWithTcs();
   1042     bool transfer_mux_tables = false;
   1043     if (tscCheck != PVMFSuccess)
   1044     {
   1045         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1046                         (0, "TSC_component::BlcEtbIdc TCS check failed"));
   1047         TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_REJECT, OpenLcnB, 2);  /* dataTypeNotSupported */
   1048         RemoveOlc(dir, OpenLcnB);
   1049     }
   1050     else
   1051     {
   1052         PVMFStatus RvsParametersOkay = VerifyReverseParameters(forRevParams, iTSCObserver);
   1053         if (RvsParametersOkay == PVMFSuccess)
   1054         {
   1055             AcceptBLCRequest(OpenLcnF, OpenLcnB, forRevParams);
   1056         }
   1057         else
   1058         {
   1059             /* RvsParameters are unsuitable; reject the OLC */
   1060             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1061                             (0, "TSC_component::BlcEtbIdc - Rejecting BLC request (%d).  Reverse parameters not ok.",
   1062                              OpenLcnB));
   1063             TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_REJECT, OpenLcnB, 1);  /* unsuitableReverseParameters */
   1064             RemoveOlc(dir, OpenLcnB);
   1065             /* Fill the data type for the outgoing codec */
   1066             PS_DataType pDataType = GetOutgoingDataType(out_codec_type, outgoing_bitrate);
   1067             /*  Fill the outgoing h223 logical channel parameters */
   1068             PS_H223LogicalChannelParameters pH223Params =
   1069                 GetH223LogicalChannelParameters((uint8)IndexForAdaptationLayer(PVT_AL3),
   1070                                                 iTSCcapability.IsSegmentable(OUTGOING, in_media_type),
   1071                                                 iAl3ControlFieldOctets);
   1072 
   1073             // Use AL3 for OBLC
   1074             PS_AdaptationLayerType al_type = (PS_AdaptationLayerType)OSCL_DEFAULT_MALLOC(sizeof(S_AdaptationLayerType));
   1075             if (al_type == NULL)
   1076             {
   1077                 OSCL_LEAVE(PVMFErrNoMemory);
   1078             }
   1079             PS_Al3 al3 = (PS_Al3)OSCL_DEFAULT_MALLOC(sizeof(S_Al3));
   1080             al3->controlFieldOctets = iAl3ControlFieldOctets;
   1081             al3->sendBufferSize = DEF_AL3_SEND_BUFFER_SIZE;
   1082             al_type->index = 5;
   1083             al_type->al3 = al3;
   1084 
   1085             OpenOutgoingChannel(out_codec_type,
   1086                                 al_type,
   1087                                 &forRevParams->forwardLogicalChannelParameters.dataType,
   1088                                 forRevParams->forwardLogicalChannelParameters.multiplexParameters.h223LogicalChannelParameters);
   1089 
   1090             iOlcs.AppendOlc(OUTGOING, OpenLcnF, pDataType, pH223Params,
   1091                             CHANNEL_ID_UNKNOWN, &forRevParams->forwardLogicalChannelParameters.dataType,
   1092                             forRevParams->forwardLogicalChannelParameters.multiplexParameters.h223LogicalChannelParameters);
   1093             transfer_mux_tables = true;
   1094             Delete_AdaptationLayerType(al_type);
   1095             OSCL_DEFAULT_FREE(al_type);
   1096             Delete_DataType(pDataType);
   1097             OSCL_DEFAULT_FREE(pDataType);
   1098             Delete_H223LogicalChannelParameters(pH223Params);
   1099             OSCL_DEFAULT_FREE(pH223Params);
   1100         }
   1101     }
   1102 
   1103     if (to_be_opened_codec != PV_CODEC_TYPE_NONE)
   1104     {
   1105         FormatCapabilityInfo fci;
   1106         IsSupported(OUTGOING, to_be_opened_codec, fci);
   1107         PS_AdaptationLayerType al_type = GetOutgoingLayer(::GetMediaType(to_be_opened_codec),
   1108                                          fci.max_sample_size);
   1109         if (al_type == NULL)
   1110         {
   1111             OSCL_LEAVE(PVMFErrNoMemory);
   1112         }
   1113         OpenOutgoingChannel(to_be_opened_codec, al_type);
   1114         Delete_AdaptationLayerType(al_type);
   1115         OSCL_DEFAULT_FREE(al_type);
   1116         transfer_mux_tables = true;
   1117     }
   1118     if (transfer_mux_tables)
   1119     {
   1120         iTSCmt.MtTrfReq(iOlcs);
   1121     }
   1122     return(PhaseE_Comm);
   1123 }
   1124 
   1125 PVMFStatus TSC_component::VerifyReverseParameters(PS_ForwardReverseParam forRevParams,
   1126         TSCObserver* aObserver)
   1127 {
   1128     OSCL_UNUSED_ARG(aObserver);
   1129     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1130                     (0, "TSC_capability::VerifyReverseParameters"));
   1131     PVMFStatus status;
   1132     bool returnNow = iTSCcapability.VerifyReverseParameters(forRevParams, iTSCObserver, status);
   1133 
   1134     if (returnNow)
   1135     {
   1136         return status;
   1137     }
   1138     PVCodecType_t codec = GetCodecType(&forRevParams->reverseLogicalChannelParameters.dataType);
   1139     PV2WayMediaType media_type = GetMediaType(codec);
   1140     uint8* decodeConfigInfoOblc = NULL;
   1141     unsigned decodeConfigInfoSzOblc =
   1142         ::GetFormatSpecificInfo(&forRevParams->reverseLogicalChannelParameters.dataType,
   1143                                 decodeConfigInfoOblc);
   1144     // get the outgoing FSI if any
   1145     for (unsigned n = 0; n < iOutgoingChannelConfig->size(); n++)
   1146     {
   1147         PV2WayMediaType channelMediaType = (*iOutgoingChannelConfig)[n].GetMediaType();
   1148         if (channelMediaType != media_type)
   1149         {
   1150             continue;
   1151         }
   1152         Oscl_Vector<FormatCapabilityInfo, OsclMemAllocator>* formats =
   1153             (*iOutgoingChannelConfig)[n].GetCodecs();
   1154         if (!formats)
   1155         {
   1156             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1157                             (0, "TSC_component::VerifyReverseParameters No formats specified for media type(%d)",
   1158                              channelMediaType));
   1159             continue;
   1160         }
   1161         for (unsigned m = 0; m < formats->size(); m++)
   1162         {
   1163             PVCodecType_t codec_type_outgoing = PVMFFormatTypeToPVCodecType((*formats)[m].format);
   1164             if (codec_type_outgoing != codec)
   1165                 continue;
   1166             if ((*formats)[m].fsi == NULL || (*formats)[m].fsi_len == 0)
   1167             {
   1168                 // There are no FSI restrictions
   1169                 return PVMFSuccess;
   1170             }
   1171             if (decodeConfigInfoSzOblc == (*formats)[m].fsi_len &&
   1172                     oscl_memcmp(decodeConfigInfoOblc, (*formats)[m].fsi, decodeConfigInfoSzOblc) == 0)
   1173             {
   1174                 return PVMFSuccess;
   1175             }
   1176         }
   1177     }
   1178 
   1179     return PVMFFailure;
   1180 }
   1181 
   1182 
   1183 PVMFStatus TSC_component::ValidateOlcsWithTcs()
   1184 {
   1185     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1186                     (0, "TSC_component::ValidateOlcsWithTcs"));
   1187     /* Verify if local TCS is satisfied */
   1188     Oscl_Vector<OlcFormatInfo, OsclMemAllocator> incoming_codecs;
   1189     if (!iOlcs.FindCodecs(INCOMING, PV_MEDIA_NONE, OLC_ESTABLISHED,
   1190                           PV_DIRECTION_BOTH, incoming_codecs))
   1191         return PVMFSuccess;
   1192     /* Set symmetry info in the codecs */
   1193     unsigned n = 0;
   1194     for (n = 0; n < incoming_codecs.size(); n++)
   1195     {
   1196         PV2WayMediaType media_type = GetMediaType(incoming_codecs[n].iCodec);
   1197         incoming_codecs[n].isSymmetric = iOlcs.IsSymmetric(media_type,
   1198                                          PV_DIRECTION_BOTH, OLC_PENDING | OLC_ESTABLISHED,
   1199                                          PV_DIRECTION_BOTH, OLC_PENDING | OLC_ESTABLISHED);
   1200     }
   1201     PVMFStatus status = VerifyCodecs(iLocalTcs, incoming_codecs, iLogger);
   1202     if (status != PVMFSuccess)
   1203     {
   1204         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1205                         (0, "TSC_component::ValidateOlcsWithTcs Codecs not compatible with local TCS"));
   1206         return status;
   1207     }
   1208 
   1209     /* Verify if remote TCS is satisfied */
   1210     Oscl_Vector<OlcFormatInfo, OsclMemAllocator> outgoing_codecs;
   1211     if (!iOlcs.FindCodecs(OUTGOING, PV_MEDIA_NONE,
   1212                           OLC_PENDING | OLC_ESTABLISHED, PV_DIRECTION_BOTH, outgoing_codecs))
   1213         return PVMFSuccess;
   1214     /* Set symmetry info in the codecs */
   1215     for (n = 0; n < outgoing_codecs.size(); n++)
   1216     {
   1217         PV2WayMediaType media_type = GetMediaType(outgoing_codecs[n].iCodec);
   1218         outgoing_codecs[n].isSymmetric = iOlcs.IsSymmetric(media_type,
   1219                                          PV_DIRECTION_BOTH,
   1220                                          OLC_PENDING | OLC_ESTABLISHED,
   1221                                          PV_DIRECTION_BOTH,
   1222                                          OLC_PENDING | OLC_ESTABLISHED);
   1223     }
   1224     status = VerifyCodecs(iRemoteTcs, outgoing_codecs, iLogger);
   1225     if (status != PVMFSuccess)
   1226     {
   1227         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1228                         (0, "TSC_component::ValidateOlcsWithTcs Codecs not compatible with remote TCS"));
   1229     }
   1230     return status;
   1231 }
   1232 
   1233 OsclAny TSC_component::TcsMsdComplete()
   1234 {
   1235     ClipCodecs(iRemoteTcs);
   1236 
   1237     if (!iOutgoingChannelConfig || iOutgoingChannelConfig->size() == 0)
   1238     {
   1239         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1240                         (0, "TSC_component::TcsMsdComplete No outgoing channels configured(%x)",
   1241                          iOutgoingChannelConfig));
   1242         return;
   1243     }
   1244 
   1245     //Oscl_Vector<OlcParam*, OsclMemAllocator> olc_list;
   1246     CPVMultiplexEntryDescriptorVector descriptors;
   1247 
   1248     // start OLCs
   1249     for (unsigned olcnum = 0; olcnum < iOutgoingChannelConfig->size(); olcnum++)
   1250     {
   1251         int index = -1;
   1252         PV2WayMediaType media_type = (*iOutgoingChannelConfig)[olcnum].GetMediaType();
   1253         if (!FindCodecForMediaType(media_type, iOutCodecList, &index))
   1254         {
   1255             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1256                             (0, "TSC_component::TcsMsdComplete No outgoing codec selected for media type=%d",
   1257                              media_type));
   1258             continue;
   1259         }
   1260         if (AlreadyAssigned(media_type))
   1261         {
   1262             continue;
   1263         }
   1264 
   1265 
   1266         PVCodecType_t incoming_codec = PV_CODEC_TYPE_NONE;
   1267         FormatCapabilityInfo fci;
   1268         IsSupported(OUTGOING, iOutCodecList[index]->codec, fci);
   1269         PS_AdaptationLayerType al_type = GetOutgoingLayer(media_type, fci.max_sample_size);
   1270         if (al_type == NULL)
   1271         {
   1272             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1273                             (0, "TSC_component::TcsMsdComplete Failed to allocate adaptation layer for media type=%d",
   1274                              media_type));
   1275             continue;
   1276         }
   1277         PS_DataType pDataTypeRvs = NULL;
   1278         PS_H223LogicalChannelParameters pH223ParamsRvs = NULL;
   1279         if (al_type->index == 5) /* AL3 */
   1280         {
   1281             incoming_codec = iOutCodecList[index]->codec;
   1282             pDataTypeRvs = GetOutgoingDataType(incoming_codec,
   1283                                                GetOutgoingBitrate(incoming_codec));
   1284             pH223ParamsRvs = GetH223LogicalChannelParameters((uint8)IndexForAdaptationLayer(PVT_AL3),
   1285                              iTSCcapability.IsSegmentable(INCOMING, media_type),
   1286                              iAl3ControlFieldOctets);
   1287         }
   1288 
   1289         OlcParam* olc_param = OpenOutgoingChannel(iOutCodecList[index]->codec,
   1290                               al_type, pDataTypeRvs, pH223ParamsRvs);
   1291         if (pH223ParamsRvs)
   1292         {
   1293             Delete_H223LogicalChannelParameters(pH223ParamsRvs);
   1294             OSCL_DEFAULT_FREE(pH223ParamsRvs);
   1295         }
   1296         if (pDataTypeRvs)
   1297         {
   1298             Delete_DataType(pDataTypeRvs);
   1299             OSCL_DEFAULT_FREE(pDataTypeRvs);
   1300         }
   1301         Delete_AdaptationLayerType(al_type);
   1302         OSCL_DEFAULT_FREE(al_type);
   1303         StartOlc(olc_param, media_type, descriptors);
   1304     }
   1305     if (FinishTcsMsdComplete(descriptors))
   1306     {
   1307         iTSCmt.MtTrfReq(iOlcs);
   1308     }
   1309     // Reset flags used to force AL
   1310     iUseAl1Video = true;
   1311     iUseAl2Video = true;
   1312     iUseAl3Video = true;
   1313 #ifdef MEM_TRACK
   1314     printf("\n Memory Stats After TcsMsdComplete");
   1315     MemStats();
   1316 #endif
   1317 }
   1318 
   1319 void TSC_component::SetOutgoingChannelConfig(Oscl_Vector<H324ChannelParameters, PVMFTscAlloc>& out_channel_config)
   1320 {
   1321     if (iOutgoingChannelConfig)
   1322     {
   1323         OSCL_DELETE(iOutgoingChannelConfig);
   1324         iOutgoingChannelConfig = NULL;
   1325     }
   1326     iOutgoingChannelConfig = new Oscl_Vector<H324ChannelParameters, PVMFTscAlloc>(out_channel_config);
   1327 
   1328 }
   1329 
   1330 void TSC_component::SetIncomingChannelConfig(Oscl_Vector<H324ChannelParameters, PVMFTscAlloc>& in_channel_config)
   1331 {
   1332     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1333                     (0, "TSC_component::SetIncomingChannelConfig size(%d)\n", in_channel_config.size()));
   1334     if (iIncomingChannelConfig)
   1335     {
   1336         OSCL_DELETE(iIncomingChannelConfig);
   1337         iIncomingChannelConfig = NULL;
   1338     }
   1339     iIncomingChannelConfig = new Oscl_Vector<H324ChannelParameters, PVMFTscAlloc>(in_channel_config);
   1340 }
   1341 
   1342 /*****************************************************************************/
   1343 /*  function name        : Status04Event10           E_PtvId_Lc_Etb_Cfm  */
   1344 /*  function outline     : Status04/Event10 procedure                        */
   1345 /*  function discription : Status04Event10( pReceiveInf )                */
   1346 /*  input data           : PS_ControlMsgHeader         Receive InfHeader Pointer    */
   1347 /*  output data          : uint32                 Terminal Status              */
   1348 /*  draw time            : '96.10.09                                         */
   1349 /*---------------------------------------------------------------------------*/
   1350 /*  amendment career(x)  :                                                   */
   1351 /*                                                                           */
   1352 /*              Copyright (C) 1996 NTT DoCoMo                                */
   1353 /*****************************************************************************/
   1354 uint32 TSC_component::LcEtbCfm(PS_ControlMsgHeader pReceiveInf)
   1355 {
   1356     TPVChannelId lcn = pReceiveInf->InfSupplement1;
   1357     /*OlcParam* olc_param = OpenLogicalChannel(OUTGOING, lcn);
   1358     }
   1359     return PhaseE_Comm;
   1360     */
   1361     OlcParam* olc_param = iOlcs.FindOlcGivenChannel(OUTGOING, lcn);
   1362     if (olc_param == NULL)
   1363     {
   1364         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1365                         (0, "TSC_component::LcEtbCfm ERROR Unable to lookup channel"));
   1366         return (PhaseE_Comm);
   1367     }
   1368     olc_param->SetState(OLC_ESTABLISHED);
   1369     CheckOutgoingChannel(olc_param, PVMFSuccess);
   1370     return PhaseE_Comm;
   1371 
   1372 }
   1373 
   1374 unsigned TSC_component::GetOutgoingBitrate(PVCodecType_t codec_type)
   1375 {
   1376     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1377                     (0, "TSC_component::GetOutgoingBitrate codec_type=%d", codec_type));
   1378     PV2WayMediaType media_type = GetMediaType(codec_type);
   1379     if (!iOutgoingChannelConfig || !iOutgoingChannelConfig->size())
   1380     {
   1381         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1382                         (0, "TSC_component::GetOutgoingBitrate outgoing channel config not found."));
   1383         return 0;
   1384     }
   1385     uint32 bitrate = 0;
   1386     for (unsigned n = 0; n < iOutgoingChannelConfig->size(); n++)
   1387     {
   1388         H324ChannelParameters& params = (*iOutgoingChannelConfig)[n];
   1389         if (params.GetMediaType() == media_type)
   1390         {
   1391             bitrate = params.GetBandwidth();
   1392             break;
   1393         }
   1394     }
   1395     if (bitrate == 0)
   1396     {
   1397         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1398                         (0, "TSC_component::GetOutgoingBitrate outgoing channel bitrate=0."));
   1399         return bitrate;
   1400     }
   1401     // lookup the bitrate from remote capabilities
   1402     uint32 br = iTSCcapability.GetRemoteBitrate(codec_type);
   1403     bitrate = (bitrate > br) ? br : bitrate;
   1404     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1405                     (0, "TSC_component::GetOutgoingBitrate outgoing channel bitrate=%d.", bitrate));
   1406     return bitrate;
   1407 }
   1408 
   1409 void TSC_component::GetChannelFormatAndCapabilities(TPVDirection dir,
   1410         Oscl_Vector<FormatCapabilityInfo, OsclMemAllocator>& formats)
   1411 {
   1412     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1413                     (0, "TSC_component::GetChannelFormatAndCapabilities"));
   1414     OlcList::iterator it = iOlcs.begin();
   1415 
   1416     while (it != iOlcs.end())
   1417     {
   1418         OlcList::value_type& val = (*it++);
   1419         OlcParam* olc = val.second;
   1420         H223ChannelParam* param = NULL;
   1421         if (olc->GetDirection() == dir)
   1422         {
   1423             param = olc->GetForwardParams();
   1424         }
   1425         else if (olc->GetReverseParams())
   1426         {
   1427             param = olc->GetReverseParams();
   1428         }
   1429         FormatCapabilityInfo fci;
   1430         fci.id = param->GetChannelId();
   1431         fci.dir = dir;
   1432         fci.format = PVCodecTypeToPVMFFormatType(param->GetMediaParam()->GetCodecType());
   1433         fci.bitrate = param->GetBitrate();
   1434         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1435                         (0, "TSC_component::GetChannelFormatAndCapabilities Adding(%d,%d,%s,%d) to list",
   1436                          fci.dir, fci.id, fci.format.getMIMEStrPtr(), fci.bitrate));
   1437         formats.push_back(fci);
   1438     }
   1439 }
   1440 
   1441 bool TSC_component::HasOlc(TPVDirection direction,
   1442                            TPVChannelId id,
   1443                            unsigned state)
   1444 {
   1445     if (state)
   1446     {
   1447         return iOlcs.HasOlc(direction, id, state);
   1448     }
   1449     else
   1450     {
   1451         return iOlcs.HasOlc(direction, id);
   1452     }
   1453 }
   1454 
   1455 OlcParam* TSC_component::FindOlcGivenChannel(TPVDirection direction,
   1456         TPVChannelId id)
   1457 {
   1458     return iOlcs.FindOlcGivenChannel(direction, id);
   1459 }
   1460 
   1461 OlcParam* TSC_component::FindOlc(TPVDirection direction,
   1462                                  PV2WayMediaType media_type,
   1463                                  unsigned state)
   1464 {
   1465     return iOlcs.FindOlc(direction, media_type, state);
   1466 }
   1467 
   1468 void TSC_component::LcnDataDetected(TPVChannelId lcn)
   1469 {
   1470     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1471                     (0, "TSC_component::LcnDataDetected - lcn=%d", lcn));
   1472     OlcParam* param = iOlcs.FindOlcGivenChannel(INCOMING, lcn);
   1473     if (param == NULL)
   1474     {
   1475         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1476                         (0, "TSC_component::LcnDataDetected - Failed to lookup channel, lcn=%d", lcn));
   1477         return;
   1478     }
   1479     if (param->GetReplacementFor() != CHANNEL_ID_UNKNOWN)
   1480     {
   1481         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1482                         (0, "TSC_component::LcnDataDetected - Replaced channel id=%d",
   1483                          param->GetReplacementFor()));
   1484         ChannelReleased(INCOMING, param->GetReplacementFor(), PV2WayErrReplaced);
   1485         param->SetReplacementFor((TPVChannelId)NULL);
   1486     }
   1487 }
   1488 
   1489 // =======================================================
   1490 // AcceptBLCRequest()
   1491 //
   1492 // WWUAPI - New Function
   1493 // =======================================================
   1494 OsclAny TSC_component::AcceptBLCRequest(TPVChannelId OpenLcnF,
   1495                                         TPVChannelId OpenLcnB,
   1496                                         PS_ForwardReverseParam forRevParams)
   1497 {
   1498     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1499                     (0, "TSC: AcceptBLCRequest reverse(%d), forward(%d)\n", OpenLcnB, OpenLcnF));
   1500     /* RvsParameters are okay; accept the OLC */
   1501     iTSCblc.BlcEtbRps(OpenLcnB - TSC_INCOMING_CHANNEL_MASK, OpenLcnF);
   1502     // Open the incoming and outgoing logical channels in the mux
   1503     OlcParam* param = OpenLogicalChannel(INCOMING,
   1504                                          OpenLcnB,
   1505                                          OpenLcnF,
   1506                                          &forRevParams->forwardLogicalChannelParameters.dataType,
   1507                                          forRevParams->forwardLogicalChannelParameters.multiplexParameters.h223LogicalChannelParameters,
   1508                                          &forRevParams->reverseLogicalChannelParameters.dataType,
   1509                                          forRevParams->reverseLogicalChannelParameters.rlcMultiplexParameters.h223LogicalChannelParameters);
   1510     param->SetState(OLC_ESTABLISHED);
   1511     /* Send updated MuxTable for outgoing part of the BLC */
   1512     iTSCmt.MtTrfReq(iOlcs);
   1513 
   1514     uint8* fsi = NULL;
   1515     uint32 fsi_len = ::GetFormatSpecificInfo(&forRevParams->forwardLogicalChannelParameters.dataType, fsi);
   1516     iTSCObserver->IncomingChannel(OpenLcnB,
   1517                                   GetCodecType(&forRevParams->forwardLogicalChannelParameters.dataType),
   1518                                   fsi, fsi_len);
   1519 
   1520     if (OpenLcnF == CHANNEL_ID_UNKNOWN ||
   1521             GetCodecType(param->GetReverseParams()->GetDataType()) == PV_CODEC_TYPE_NONE)
   1522         return;
   1523 
   1524     // Pause the channel untill OlcAck+MtAck is received
   1525     H223OutgoingChannelPtr outgoing_channel;
   1526     iH223->GetOutgoingChannel(OpenLcnF, outgoing_channel);
   1527     outgoing_channel->Pause();
   1528     // Notify outgoing channel
   1529     fsi_len = GetFormatSpecificInfo(&forRevParams->reverseLogicalChannelParameters.dataType, fsi);
   1530     iTSCObserver->OutgoingChannelEstablished(OpenLcnF,
   1531             GetCodecType(&forRevParams->reverseLogicalChannelParameters.dataType),
   1532             fsi, fsi_len);
   1533 }
   1534 
   1535 // =============================================================
   1536 // Status04Event11()                     E_PtvId_Lc_Rls_Idc
   1537 //
   1538 // This is LCSE RELEASE.indication.
   1539 // =============================================================
   1540 uint32 TSC_component::LcRlsIdc(PS_ControlMsgHeader  pReceiveInf)
   1541 {
   1542     TPVDirection dir = (pReceiveInf->Dir == S_ControlMsgHeader::INCOMING) ? INCOMING : OUTGOING;
   1543     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1544                     (0, "TSC_component::LcRlsIdc dir(%d), lcn(%d).",
   1545                      dir, pReceiveInf->InfSupplement1));
   1546     TPVChannelId lcn = (dir == INCOMING) ? (TPVChannelId)(pReceiveInf->InfSupplement1 +
   1547                        TSC_INCOMING_CHANNEL_MASK) : (TPVChannelId)pReceiveInf->InfSupplement1;
   1548     PS_SourceCause_LcBlc sourceCause = (PS_SourceCause_LcBlc)pReceiveInf->pParameter;
   1549     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1550                     (0, "TSC_component::LcRlsIdc sourceCause(%x), cause index(%d)",
   1551                      sourceCause, sourceCause->Cause.index));
   1552     PVMFStatus status = PVMFSuccess;
   1553 
   1554     OlcParam* olc_param = iOlcs.FindOlcGivenChannel(dir, lcn);
   1555     if (olc_param == NULL)
   1556     {
   1557         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1558                         (0, "TSC_component::LcRlsIdc ERROR Unable to lookup channel"));
   1559         return (PhaseE_Comm);
   1560     }
   1561 
   1562     if (dir == OUTGOING)
   1563     {
   1564         if (olc_param->GetState() == OLC_PENDING)
   1565         {
   1566             // only valid rejection code is m/s conflict
   1567             if (iTSCstatemanager.ReadState(TSC_MSD_DECISION) == SLAVE &&
   1568                     sourceCause->Cause.index == 10)
   1569             {
   1570                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1571                                 (0, "TSC_component::LcRlsIdc Reject due to M/S conflict"));
   1572             }
   1573             else
   1574             {
   1575                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1576                                 (0, "TSC_component::LcRlsIdc Olc failure"));
   1577                 status = PVMFFailure;
   1578             }
   1579         }
   1580     }
   1581     else if (dir == INCOMING)
   1582     {
   1583         RemoveMultiplex(olc_param);
   1584     }
   1585     ChannelReleased(dir, lcn, status);
   1586     return(PhaseE_Comm);
   1587 }
   1588 
   1589 // =============================================================
   1590 // Status04Event16()                   E_PtvId_Blc_Rls_Idc
   1591 //
   1592 // This is BLCSE RELEASE.indication.  It is called when
   1593 // a Bi-Dir OLCReject is received.  It could be from an incoming or outgoing SE
   1594 // =============================================================
   1595 uint32 TSC_component::BlcRlsIdc(PS_ControlMsgHeader  pReceiveInf)
   1596 {
   1597     PS_SourceCause_LcBlc sourceCause = (PS_SourceCause_LcBlc)pReceiveInf->pParameter;
   1598     int32 causeIndex = sourceCause->Cause.index;
   1599     TPVDirection dir = OUTGOING;
   1600     TPVChannelId lcn = (TPVChannelId)pReceiveInf->InfSupplement1;;
   1601     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1602                     (0, "TSC_component::BlcRlsIdc BLC rejected. dir(%d), forward lcn(%d), reverse lcn(%d), cause index(%d)",
   1603                      dir, pReceiveInf->InfSupplement1, pReceiveInf->InfSupplement2, causeIndex));
   1604 
   1605     if (pReceiveInf->Dir == S_ControlMsgHeader::INCOMING)
   1606     {
   1607         dir = INCOMING;
   1608         lcn += TSC_INCOMING_CHANNEL_MASK;
   1609     }
   1610 
   1611     PVMFStatus status = PVMFSuccess;
   1612     PVCodecType_t to_be_opened_codec = PV_CODEC_TYPE_NONE;
   1613     PV2WayMediaType media_type = PV_MEDIA_NONE;
   1614 
   1615     if (dir == OUTGOING)
   1616     {
   1617         OlcParam* olc_param = iOlcs.FindOlcGivenChannel(OUTGOING, lcn);
   1618         if (olc_param != NULL)
   1619         {
   1620             media_type = GetMediaType(olc_param->GetForwardParams()->GetDataType());
   1621             if (olc_param->GetState() == OLC_PENDING)
   1622             {
   1623                 if (causeIndex == 1)
   1624                 {
   1625                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1626                                     (0, "TSC_component::BlcRlsIdc UnsuitableReverseParams. Entering wait state ..."));
   1627                     /* Cause is unsuitableReverseParameters; Enter wait state */
   1628                     iWaitingForOblc = true;
   1629                     iWaitingForOblcCodec = GetCodecType(olc_param->GetForwardParams()->GetDataType());
   1630                     iWaitingForOblcTimer->Request(PV_TSC_WAITING_FOR_OBLC_TIMER_ID,
   1631                                                   PV_TSC_WAITING_FOR_OBLC_TIMER_ID , WAITING_FOR_OBLC_TIMEOUT_SECONDS, this);
   1632                 }
   1633                 else if (iTSCstatemanager.ReadState(TSC_MSD_DECISION) == SLAVE &&
   1634                          causeIndex == 10)
   1635                 {
   1636                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1637                                     (0, "TSC_component::BlcRlsIdc Master/Slave conflict"));
   1638                     // is there is a pending outgoing OLC for the same media type ?
   1639                     Oscl_Vector<OlcParam*, OsclMemAllocator> pending_olc_list;
   1640                     if (iOlcs.FindOlcs(OUTGOING, media_type, OLC_PENDING, pending_olc_list))
   1641                     {
   1642                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1643                                         (0, "TSC_component::BlcRlsIdc Pending outgoing OLCs(%d) found for incoming media type(%d).",
   1644                                          pending_olc_list.size(), media_type));
   1645                         OSCL_ASSERT(pending_olc_list.size() == 1);
   1646                         OlcParam* param = pending_olc_list[0];
   1647                         to_be_opened_codec = GetCodecType(param->GetForwardParams()->GetDataType());
   1648                     }
   1649                 }
   1650                 else
   1651                 {
   1652                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1653                                     (0, "TSC_component::BlcRlsIdc Olc failure"));
   1654                     status = PVMFFailure;
   1655                 }
   1656             }
   1657         }
   1658     }
   1659     else if (dir == INCOMING)
   1660     {
   1661         lcn += TSC_INCOMING_CHANNEL_MASK;
   1662     }
   1663     ChannelReleased(dir, lcn, status);
   1664 
   1665     if (to_be_opened_codec == PV_CODEC_TYPE_NONE)
   1666         return PhaseE_Comm;
   1667     FormatCapabilityInfo fci;
   1668     IsSupported(OUTGOING, to_be_opened_codec, fci);
   1669     PS_AdaptationLayerType al_type = GetOutgoingLayer(media_type, fci.max_sample_size);
   1670     if (al_type == NULL)
   1671     {
   1672         OSCL_LEAVE(PVMFErrNoMemory);
   1673     }
   1674     OpenOutgoingChannel(to_be_opened_codec, al_type);
   1675     Delete_AdaptationLayerType(al_type);
   1676     OSCL_DEFAULT_FREE(al_type);
   1677     iTSCmt.MtTrfReq(iOlcs);
   1678     return(PhaseE_Comm);
   1679 }
   1680 
   1681 OsclAny TSC_component::MuxTableSendComplete(uint32 sn, PVMFStatus status)
   1682 {
   1683     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1684                     (0, "TSC::MuxTableSendComplete sn(%d), status(%d)", sn, status));
   1685     if (!iTSCmt.MuxTableSendComplete(sn))
   1686     {
   1687         return;
   1688     }
   1689     Oscl_Vector<OlcParam*, OsclMemAllocator> olc_list;
   1690     unsigned num_pending = iOlcs.FindOutgoingOlcsByMtState(MT_PENDING, olc_list);
   1691     for (unsigned lcn = 0; lcn < num_pending; lcn++)
   1692     {
   1693         //OSCL_ASSERT(olc_list[lcn]->GetMtSn()==sn);
   1694         olc_list[lcn]->SetMtState(status == PVMFSuccess ? MT_COMPLETE : MT_RELEASED);
   1695         if (olc_list[lcn]->GetState() == OLC_ESTABLISHED)
   1696         {
   1697             CheckOutgoingChannel(olc_list[lcn], status);
   1698         }
   1699         else
   1700         {
   1701             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1702                             (0, "TSC_component::MuxTableSendComplete Mux table completed, but channel still pending. channel id=(%d)", olc_list[lcn]->GetChannelId()));
   1703         }
   1704     }
   1705     iTSCmt.ReleaseMuxTables();
   1706 }
   1707 
   1708 // ===============================================================
   1709 // StopData()
   1710 //
   1711 // Sets flags in the H324 system table which stop data transmission
   1712 // for each open, outgoing logical channel.
   1713 // ================================================================
   1714 OsclAny TSC_component::StopData()
   1715 {
   1716     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1717                     (0, "TSC_component::StopData"));
   1718     OlcList::iterator it = iOlcs.begin();
   1719     while (it != iOlcs.end())
   1720     {
   1721         OlcParam* olc = (*it++).second;
   1722         iH223->StopChannel(olc->GetDirection(), olc->GetChannelId());
   1723         if (olc->GetReverseParams())
   1724         {
   1725             iH223->StopChannel(olc->GetReverseParams()->GetDirection(),
   1726                                olc->GetReverseParams()->GetChannelId());
   1727         }
   1728     }
   1729 }
   1730 
   1731 // bool whether level is unknown
   1732 bool TSC_component::Connect1LevelKnown()
   1733 {
   1734     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iLogger, PVLOGMSG_NOTICE,
   1735                     (0, "TSC_component::Connect"));
   1736     bool levelknown = true;
   1737     iWaitingForOblc = false;
   1738     iWaitingForOblcCodec = PV_CODEC_TYPE_NONE;
   1739 
   1740 
   1741     if (iOutgoingChannelConfig == NULL)
   1742     {
   1743         OSCL_LEAVE(PVMFErrNoMemory);
   1744     }
   1745 
   1746     if (iIncomingChannelConfig == NULL)
   1747     {
   1748         OSCL_LEAVE(PVMFErrNoMemory);
   1749     }
   1750 
   1751     iWaitingForOblcTimer->Clear();
   1752     return levelknown;
   1753 }
   1754 
   1755 void TSC_component::Connect2()
   1756 {
   1757     H223PduParcomSharedPtr parcom;
   1758     iH223->Start(parcom);
   1759 }
   1760 
   1761 // =======================================================
   1762 // ClipCodecs()                                 (RAN-32K)
   1763 //
   1764 // This one reconciles the desired outgoing codecs with the
   1765 //   capabilities of the remote terminal.  The outgoing
   1766 //   codecs have been specified by the application via calls
   1767 //   to pH324.SetVideoType(), pH324.SetAudioType().  The
   1768 //   remote terminal capabilities from the received
   1769 //   TerminalCapabilitySet are passed in (pTcs).
   1770 // If insufficient capabilities are found, the routine will
   1771 //   modify the outgoing codecs stored in pH324.
   1772 // =======================================================
   1773 OsclAny TSC_component::ClipCodecs(PS_TerminalCapabilitySet pTcs)
   1774 {
   1775     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1776                     (0, "TSC_component::ClipCodecs(%d,%d)",
   1777                      pTcs->size_of_capabilityTable,
   1778                      pTcs->size_of_capabilityDescriptors));
   1779     if (!(pTcs->option_of_capabilityTable && pTcs->option_of_capabilityDescriptors))
   1780     {
   1781         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1782                         (0, "TSC_component::ClipCodecs - Remote terminal is incapable of decoding anything"));
   1783         return;
   1784     }
   1785     if (!iOutgoingChannelConfig || iOutgoingChannelConfig->size() == 0)
   1786     {
   1787         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1788                         (0, "TSC_component::ClipCodecs - We dont want to send anything.  Skip ClipCodecs."));
   1789         return;
   1790     }
   1791     PS_CapabilityDescriptor pCapDesc = NULL;
   1792     PS_AlternativeCapabilitySet pAltCapSet = NULL;
   1793     for (unsigned i = 0; i < pTcs->size_of_capabilityDescriptors; ++i)
   1794     {
   1795         pCapDesc = pTcs->capabilityDescriptors + i;
   1796         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1797                         (0, "TSC_component::ClipCodecs - descriptor(%d),size_of_simultaneousCapabilities(%d)",
   1798                          i, pCapDesc->size_of_simultaneousCapabilities));
   1799         /* Temporary list of selected codecs.  Retain the codecs for descriptor with most matching codecs */
   1800         Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator> codec_list;
   1801         /* A changing list of available media for outgoing channels.  Once a codec is selected,
   1802            the entry for that media is removed from this list */
   1803         Oscl_Vector<H324ChannelParameters, PVMFTscAlloc> outgoing_media(*iOutgoingChannelConfig);
   1804         if (pCapDesc->size_of_simultaneousCapabilities != iOutgoingChannelConfig->size())
   1805         {
   1806             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1807                             (0, "TSC_component::ClipCodecs - descriptor(%d),size_of_simultaneousCapabilities does not match num channels(%d)", i, iOutgoingChannelConfig->size()));
   1808         }
   1809 
   1810         for (unsigned j = 0; j < pCapDesc->size_of_simultaneousCapabilities; ++j)
   1811         {
   1812             bool txOnly = true;
   1813             pAltCapSet = pCapDesc->simultaneousCapabilities + j;
   1814             // Get the list of codecs in this ACS
   1815             Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator> codecs_acs;
   1816             uint16 num_media_types = GetCodecCapabilityInfo(pTcs, pAltCapSet, codecs_acs);
   1817             if (num_media_types != 1)
   1818             {
   1819                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1820                                 (0, "TSC_component::ClipCodecs - ERROR:  Badly formed AlternativeCapabilitySet j=%d, num media types=%d", j, num_media_types));
   1821                 Deallocate(codecs_acs);
   1822                 continue;
   1823             }
   1824 
   1825             //Check for tx only capabilities
   1826             for (unsigned k = 0; k < codecs_acs.size(); ++k)
   1827             {
   1828                 if (codecs_acs[k]->dir != OUTGOING)
   1829                 {
   1830                     txOnly = false;
   1831                     break;
   1832                 }
   1833             }
   1834             if (txOnly)
   1835             {
   1836                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1837                                 (0, "TSC_component::ClipCodecs: tx only codecs"));
   1838                 Deallocate(codecs_acs);
   1839                 continue;
   1840             }
   1841 
   1842             PV2WayMediaType mediaType = GetMediaType(codecs_acs[0]->codec);
   1843             if (mediaType != PV_AUDIO && mediaType != PV_VIDEO)
   1844             {
   1845                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1846                                 (0, "TSC_component::ClipCodecs:  Media type in AlternativeCapabilitySet j=%d is neither audio/video, media type=%d", j, mediaType));
   1847                 Deallocate(codecs_acs);
   1848                 continue;
   1849             }
   1850             // Get the list of our incoming codecs for this media type
   1851             Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator> in_codecs_for_media_type;
   1852             iTSCcapability.GetSupportedCodecCapabilityInfo(INCOMING, mediaType, in_codecs_for_media_type);
   1853 
   1854             // Do either side have symmetry constraints ?
   1855             bool local_has_symmetry_constraint = iTSCcapability.HasSymmetryConstraint(in_codecs_for_media_type);
   1856             bool remote_has_symmetry_constraint = iTSCcapability.HasSymmetryConstraint(codecs_acs);
   1857             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1858                             (0, "TSC_component::ClipCodecs mediaType=%d, local_has_symmetry_constraint=%d, remote_has_symmetry_constraint=%d", mediaType, local_has_symmetry_constraint, remote_has_symmetry_constraint));
   1859             CodecCapabilityInfo* selected_codec_info;
   1860             if (local_has_symmetry_constraint || remote_has_symmetry_constraint)
   1861             {
   1862                 selected_codec_info = iTSCcapability.SelectOutgoingCodec(&codecs_acs,
   1863                                       &in_codecs_for_media_type);
   1864             }
   1865             else
   1866             {
   1867                 selected_codec_info = iTSCcapability.SelectOutgoingCodec(&codecs_acs);
   1868             }
   1869             if (selected_codec_info)
   1870                 codec_list.push_back(selected_codec_info->Copy());
   1871             Deallocate(codecs_acs);
   1872             Deallocate(in_codecs_for_media_type);
   1873         }
   1874         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1875                         (0, "TSC_component::ClipCodecs codec_list size=%d, iOutCodecList size=%d",
   1876                          codec_list.size(), iOutCodecList.size()));
   1877         if (codec_list.size() > iOutCodecList.size())
   1878         {
   1879             /* found a match */
   1880             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1881                             (0, "TSC_component::ClipCodecs Match found for descriptor(%d), size(%d)",
   1882                              i, pCapDesc->size_of_simultaneousCapabilities));
   1883             Deallocate(iOutCodecList);
   1884             iOutCodecList = codec_list;
   1885             for (unsigned num = 0; num < iOutCodecList.size(); num++)
   1886             {
   1887                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1888                                 (0, "TSC_component::ClipCodecs Selected codec(%d)=%d",
   1889                                  num, codec_list[num]->codec));
   1890             }
   1891         }
   1892         else
   1893         {
   1894             Deallocate(codec_list);
   1895         }
   1896     }
   1897 }
   1898 
   1899 void TSC_component::Start()
   1900 {
   1901     if (iOutgoingChannelConfig == NULL || iIncomingChannelConfig == NULL)
   1902     {
   1903         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1904                         (0, "TSC_component::Start here"));
   1905     }
   1906 
   1907 }
   1908 
   1909 void TSC_component::StartDisconnect(bool terminate)
   1910 {
   1911     if (terminate)
   1912     {
   1913         StopData();
   1914         CloseChannels();
   1915         Deallocate(iOutCodecList);
   1916     }
   1917 }
   1918 
   1919 void TSC_component::TimeoutOccurred(int32 timerID, int32 timeoutInfo)
   1920 {
   1921     OSCL_UNUSED_ARG(timeoutInfo);
   1922     if (timerID == PV_TSC_WAITING_FOR_OBLC_TIMER_ID)
   1923     {
   1924         iWaitingForOblc = false;
   1925         iWaitingForOblcCodec = PV_CODEC_TYPE_NONE;
   1926     }
   1927 }
   1928 
   1929 /*****************************************************************************/
   1930 /*  function name        : Status08Event19          E_PtvId_Clc_Cls_Idc  */
   1931 /*  function outline     : Status08/Event19 procedure                        */
   1932 /*  function discription : Status08Event19( pReceiveInf )                */
   1933 /*  input data           : PS_ControlMsgHeader         Receive InfHeader Pointer    */
   1934 /*  output data          : uint32                 Terminal Status              */
   1935 /*  draw time            : '96.10.09                                         */
   1936 /*---------------------------------------------------------------------------*/
   1937 /*  amendment career(x)  :                                                   */
   1938 /*                                                                           */
   1939 /*              Copyright (C) 1996 NTT DoCoMo                                */
   1940 /*****************************************************************************/
   1941 uint32 TSC_component::Status08Event19(PS_ControlMsgHeader pReceiveInf)
   1942 {
   1943     TPVChannelId ClcLcn = CHANNEL_ID_UNKNOWN;
   1944     uint32 Directional = 0;          /* UNI=1, BI=2 */
   1945 
   1946     /* (RECEIVED AN INCOMING RequestChannelClose) */
   1947     /* Input parameters */
   1948     ClcLcn = (TPVChannelId)pReceiveInf->InfSupplement1;         /* Channel requested to be closed */
   1949     Directional = pReceiveInf->InfSupplement2;    /* Directionality */
   1950     if (Directional != 1 && Directional != 2)
   1951     {
   1952         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1953                         (0, "TSC_component::Status08Event19 Invalid directionality"));
   1954         iTSCclc.ClcRjtReq(ClcLcn);
   1955         return (PhaseE_Comm);
   1956     }
   1957 
   1958     if (!HasOlc(OUTGOING, ClcLcn))
   1959     {
   1960         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   1961                         (0, "TSC_component::Status08Event19 unable to lookup outgoing channel id(%d)",
   1962                          ClcLcn));
   1963         iTSCclc.ClcRjtReq(ClcLcn);
   1964         return (PhaseE_Comm);
   1965     }
   1966 
   1967     /* Primitive Send */
   1968     iTSCclc.ClcClsRps(ClcLcn);            /* Send RCCAck Message */
   1969 
   1970     ChannelReleased(OUTGOING, ClcLcn, PVMFSuccess);
   1971 
   1972     /* Send the H.245 CloseLogicalChannel message */
   1973     if (Directional == 1)          /* UniDirectional */
   1974     {
   1975         TPVDirection dir = iTSClc.LcRlsReq(RELEASE_CLOSE, ClcLcn, 0);
   1976         RemoveOlc(dir, ClcLcn);
   1977     }
   1978     else if (Directional == 2)     /* BiDirectional */
   1979     {
   1980         TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_CLOSE, ClcLcn, 0);
   1981         RemoveOlc(dir, ClcLcn);
   1982     }
   1983     return(PhaseE_Comm);
   1984 }
   1985 
   1986 /*****************************************************************************/
   1987 /*  function name        : Status04Event15          E_PtvId_Blc_Etb_Cfm  */
   1988 /*  function outline     : Status04/Event15 procedure                        */
   1989 /*  function discription : Status04Event15( pReceiveInf )                */
   1990 /*  input data           : PS_ControlMsgHeader         Receive InfHeader Pointer    */
   1991 /*  output data          : uint32                 Terminal Status              */
   1992 /*  draw time            : '96.10.09                                         */
   1993 /*---------------------------------------------------------------------------*/
   1994 /*  amendment career(x)  :                                                   */
   1995 /*                                                                           */
   1996 /*              Copyright (C) 1996 NTT DoCoMo                                */
   1997 /*****************************************************************************/
   1998 uint32 TSC_component::BlcEtbCfm(PS_ControlMsgHeader pReceiveInf)
   1999 {
   2000     TPVChannelId incoming_lcn = pReceiveInf->InfSupplement2 + TSC_INCOMING_CHANNEL_MASK;
   2001     OlcParam* olc_param = iOlcs.FindOlcGivenChannel(OUTGOING, pReceiveInf->InfSupplement1);
   2002     if (olc_param == NULL)
   2003     {
   2004         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2005                         (0, "TSC_component::BlcEtbCfm ERROR Unable to lookup channel"));
   2006         return PhaseE_Comm;
   2007     }
   2008     olc_param->SetState(OLC_ESTABLISHED);
   2009 
   2010     // Resume the channel if MT is also complete
   2011     CheckOutgoingChannel(olc_param, PVMFSuccess);
   2012 
   2013     if (olc_param->GetReverseParams())
   2014     {
   2015         // Set the incoming logical channel number
   2016         olc_param->GetReverseParams()->SetChannelId(incoming_lcn);
   2017         // Open the incoming channel in the mux
   2018         OpenPort(INCOMING,
   2019                  olc_param->GetReverseParams()->GetChannelId(),
   2020                  olc_param->GetReverseParams());
   2021 
   2022         uint8* fsi = NULL;
   2023         uint32 fsi_len = ::GetFormatSpecificInfo(olc_param->GetReverseParams()->GetDataType(), fsi);
   2024         iTSCObserver->IncomingChannel(incoming_lcn,
   2025                                       GetCodecType(olc_param->GetReverseParams()->GetDataType()),
   2026                                       fsi, fsi_len);
   2027     }
   2028     return PhaseE_Comm;
   2029 }
   2030 
   2031 
   2032 // =============================================================
   2033 // Status04Event50()                  E_PtvId_Blc_Etb_Cfm2
   2034 //
   2035 // This is "BLCSE ESTABLISH.confirm2"
   2036 // It is called when SE receives an OLCConfirm (Bi-Dir).
   2037 // =============================================================
   2038 uint32 TSC_component::BlcEtbCfm2(PS_ControlMsgHeader  pReceiveInf)
   2039 {
   2040     OSCL_UNUSED_ARG(pReceiveInf);
   2041     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2042                     (0, "TSC_component::BlcEtbCfm2 forward(%d), reverse(%d))\n",
   2043                      pReceiveInf->InfSupplement1, pReceiveInf->InfSupplement2));
   2044     OlcParam* olc_param = iOlcs.FindOlcGivenChannel(INCOMING,
   2045                           pReceiveInf->InfSupplement1 + TSC_INCOMING_CHANNEL_MASK);
   2046     if (olc_param == NULL)
   2047     {
   2048         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2049                         (0, "TSC_component::BlcEtbCfm ERROR Unable to lookup channel"));
   2050         return PhaseE_Comm;
   2051     }
   2052     olc_param->SetState(OLC_ESTABLISHED);
   2053     // Resume the channel if MT is also complete
   2054     CheckOutgoingChannel(olc_param, PVMFSuccess);
   2055     return PhaseE_Comm;
   2056 }
   2057 
   2058 
   2059 /*****************************************************************************/
   2060 /*  function name        : Status08Event12           E_PtvId_Lc_Rls_Cfm  */
   2061 /*  function outline     : Status08/Event12 procedure                        */
   2062 /*  function discription : Status08Event12( pReceiveInf )                */
   2063 /*  input data           : PS_ControlMsgHeader         Receive InfHeader Pointer    */
   2064 /*  output data          : uint32                 Terminal Status              */
   2065 /*  draw time            : '00.4.13                                          */
   2066 /*---------------------------------------------------------------------------*/
   2067 uint32 TSC_component::LcRlsCfm(PS_ControlMsgHeader  pReceiveInf)
   2068 {
   2069     TPVChannelId lcn = (TPVChannelId) pReceiveInf->InfSupplement1;
   2070     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2071                     (0, "TSC_component::LcRlsCfm - lcn(%d)\n", lcn));
   2072     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2073                     (0, "TSC_component::LcRlsCfm - lcn(%d)\n", lcn));
   2074     ChannelReleased(OUTGOING, lcn, PVMFSuccess);
   2075     return(PhaseE_Comm);
   2076 }
   2077 
   2078 /*****************************************************************************/
   2079 /*  function name        : Status08Event17          E_PtvId_Blc_Rls_Cfm  */
   2080 /*  function outline     : Status08/Event17 procedure                        */
   2081 /*  function discription : Status08Event17( pReceiveInf )                */
   2082 /*  input data           : PS_ControlMsgHeader         Receive InfHeader Pointer    */
   2083 /*  output data          : uint32                 Terminal Status              */
   2084 /*  draw time            : '00.4.13                                         */
   2085 /*---------------------------------------------------------------------------*/
   2086 /* RAN - Bi-Dir OLCAck */
   2087 uint32 TSC_component::BlcRlsCfm(PS_ControlMsgHeader  pReceiveInf)
   2088 {
   2089     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2090                     (0, "TSC_component::BlcRlsCfm - forward(%d), reverse(%d)",
   2091                      pReceiveInf->InfSupplement1, pReceiveInf->InfSupplement2));
   2092     ChannelReleased(OUTGOING,
   2093                     pReceiveInf->InfSupplement1, PVMFSuccess);
   2094     return PhaseE_Comm;
   2095 }
   2096 
   2097 LogicalChannelInfo* TSC_component::GetLogicalChannelInfo(PVMFPortInterface& port)
   2098 {
   2099     return iTSCchannelcontrol.GetLogicalChannelInfo(port);
   2100 }
   2101 
   2102 void TSC_component::ReceivedFormatSpecificInfo(TPVChannelId channel_id,
   2103         uint8* fsi,
   2104         uint32 fsi_len)
   2105 {
   2106     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2107                     (0, "TSC_component::ReceivedFormatSpecificInfo lcn=%d, len=%d",
   2108                      channel_id, fsi_len));
   2109     iTSCchannelcontrol.ReceivedFormatSpecificInfo(channel_id, fsi, fsi_len);
   2110 }
   2111 
   2112 bool TSC_component::IsEstablishedLogicalChannel(TPVDirection aDir,
   2113         TPVChannelId aChannelId)
   2114 {
   2115     return iTSCchannelcontrol.IsEstablishedLogicalChannel(aDir, aChannelId);
   2116 }
   2117 
   2118 
   2119 void TSC_component::RemoveOlc(TPVDirection dir, TPVChannelId lcn)
   2120 {
   2121     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2122                     (0, "TSC_component::RemoveOlc lcn(%d), dir(%d)", lcn, dir));
   2123     OlcKey key(dir, lcn);
   2124     OlcList::iterator iter = iOlcs.find(key);
   2125     if (iter == iOlcs.end())
   2126         return;
   2127     OlcParam* param = (*iter).second;
   2128 
   2129     if ((dir == OUTGOING || param->GetReverseParams()) &&
   2130             (param->GetMtNum() && (param->GetMtSn() >= 0)) &&
   2131             IsRemovable(lcn))
   2132     {
   2133         iTSCmt.DeleteMuxEntry(param->GetMtNum());
   2134     }
   2135 
   2136     iTSCmt.ReleaseMuxTables();
   2137 
   2138     if (iter != iOlcs.end())
   2139     {
   2140         delete(*iter).second;
   2141         iOlcs.erase(iter);
   2142     }
   2143 }
   2144 
   2145 void TSC_component::ReleaseOlc(OlcParam* olc, uint16 cause)
   2146 {
   2147     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2148                     (0, "TSC_channelcontrol::ReleaseOlc olc(%x), reason(%d))", olc, cause));
   2149     int release_type = (olc->GetDirection() == OUTGOING) ? RELEASE_CLOSE : RELEASE_REJECT;
   2150 
   2151     if (olc->GetDirectionality() == EPVT_UNI_DIRECTIONAL)
   2152     {
   2153         iTSClc.LcRlsReq(release_type, olc->GetChannelId(), cause);
   2154     }
   2155     else
   2156     {
   2157         iTSCblc.BlcRlsReq(release_type, olc->GetChannelId(), cause);
   2158     }
   2159 }
   2160 
   2161 /* This function just does the h.245 signalling for closing a logical channel - incoming/outgoing */
   2162 void TSC_component::SignalChannelClose(TPVDirection dir,
   2163                                        TPVChannelId lcn,
   2164                                        TPVDirectionality directionality)
   2165 {
   2166     /* Multiplex entries must have failed.  Close the channel */
   2167     if (dir == OUTGOING)
   2168     {
   2169         if (directionality == EPVT_BI_DIRECTIONAL)
   2170         {
   2171             TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_CLOSE, lcn, 0);
   2172             RemoveOlc(dir, lcn);
   2173         }
   2174         else
   2175         {
   2176             TPVDirection dir = iTSClc.LcRlsReq(RELEASE_CLOSE, lcn, 0);
   2177             RemoveOlc(dir, lcn);
   2178         }
   2179     }
   2180     else
   2181     {
   2182         iTSCclc.ClcClsReq(lcn);
   2183     }
   2184 }
   2185 
   2186 void TSC_component::CheckOutgoingChannel(OlcParam* olc_param, PVMFStatus status)
   2187 {
   2188     TPVChannelId id = (olc_param->GetDirection() == OUTGOING) ?
   2189                       olc_param->GetChannelId() : olc_param->GetReverseParams()->GetChannelId();
   2190     PVCodecType_t codec_type = olc_param->GetDirection() == OUTGOING ?
   2191                                GetCodecType(olc_param->GetForwardParams()->GetDataType()) :
   2192                                GetCodecType(olc_param->GetReverseParams()->GetDataType());
   2193     OSCL_UNUSED_ARG(codec_type);
   2194     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2195                     (0, "TSC_channelcontrol::CheckOutgoingChannel channel id=%d, codec type=%d, status=%d",
   2196                      olc_param->GetChannelId(), codec_type, status));
   2197     if (status != PVMFSuccess)
   2198     {
   2199         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2200                         (0, "TSC_component::CheckOutgoingChannel Channel open failed"));
   2201         ChannelReleased(OUTGOING, olc_param->GetChannelId(), status);
   2202         return;
   2203     }
   2204     if (olc_param->GetMtState() != MT_COMPLETE)
   2205     {
   2206         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2207                         (0, "TSC_component::CheckOutgoingChannel channel id=%d Mux table send not complete",
   2208                          olc_param->GetChannelId()));
   2209         return;
   2210     }
   2211     // OLC+MT is complete.  Resume the channel.
   2212     H223OutgoingChannelPtr outgoing_channel;
   2213     status = iH223->GetOutgoingChannel(id, outgoing_channel);
   2214     if (status != PVMFSuccess)
   2215     {
   2216         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2217                         (0, "TSC_component::CheckOutgoingChannel ERROR Failed to lookup channel."));
   2218         return;
   2219     }
   2220     outgoing_channel->Resume();
   2221     // Request fast update from the engine
   2222     iTSCObserver->RequestFrameUpdate(outgoing_channel);
   2223 }
   2224 
   2225 OsclAny TSC_component::ChannelReleased(TPVDirection dir, TPVChannelId lcn, PVMFStatus status)
   2226 {
   2227     OSCL_UNUSED_ARG(status);
   2228     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2229                     (0, "TSC_channelcontrol::ChannelReleased dir(%d), lcn(%d), status(%d)",
   2230                      dir, lcn, status));
   2231     OlcParam* olc_param = iOlcs.FindOlcGivenChannel(dir, lcn);
   2232     if (olc_param == NULL)
   2233     {
   2234         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2235                         (0, "TSC_channelcontrol::ChannelReleased Failed to lookup channel(%d), lcn(%d)\n",
   2236                          dir, lcn));
   2237         return;
   2238     }
   2239 
   2240     if (dir == OUTGOING || olc_param->GetState() == OLC_ESTABLISHED)
   2241     {
   2242         iTSCObserver->ChannelClosed(dir,
   2243                                     lcn,
   2244                                     ::GetCodecType(olc_param->GetForwardParams()->GetDataType()),
   2245                                     status);
   2246     }
   2247     if (olc_param->GetDirectionality() == EPVT_BI_DIRECTIONAL)
   2248     {
   2249         TPVChannelId rvs_lcn = olc_param->GetReverseParams()->GetChannelId();
   2250         if (rvs_lcn &&
   2251                 (rvs_lcn != CHANNEL_ID_UNKNOWN) &&
   2252                 (dir == INCOMING || olc_param->GetState() == OLC_ESTABLISHED))
   2253         {
   2254             iTSCObserver->ChannelClosed(REVERSE_DIR(dir),
   2255                                         rvs_lcn,
   2256                                         ::GetCodecType(olc_param->GetReverseParams()->GetDataType()),
   2257                                         status);
   2258         }
   2259     }
   2260 
   2261     RemoveOlc(dir, lcn);
   2262 }
   2263 
   2264 void TSC_component::CloseChannels()
   2265 {
   2266     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2267                     (0, "TSC_channelcontrol::CloseChannels "));
   2268     OlcList::iterator it = iOlcs.begin();
   2269     while (it != iOlcs.end())
   2270     {
   2271         OlcParam* olc = (*it++).second;
   2272         ChannelReleased(olc->GetDirection(), olc->GetChannelId(), PVMFSuccess);
   2273         it = iOlcs.begin();
   2274     }
   2275 }
   2276 
   2277 
   2278 OlcParam* TSC_component::OpenLogicalChannel(TPVDirection dir,
   2279         TPVChannelId lcn,
   2280         TPVChannelId lcnRvs,
   2281         PS_DataType dt,
   2282         PS_H223LogicalChannelParameters lcp,
   2283         PS_DataType dtRvs,
   2284         PS_H223LogicalChannelParameters lcpRvs)
   2285 {
   2286 
   2287     OSCL_UNUSED_ARG(lcpRvs);
   2288     OSCL_UNUSED_ARG(dtRvs);
   2289     OSCL_UNUSED_ARG(lcp);
   2290     OSCL_UNUSED_ARG(dt);
   2291 
   2292     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2293                     (0, "TSC_channelcontrol::OpenLogicalChannel dir(%d), lcn(%d), dt(%x), lcp(%x), lcnRvs(%d), dtRvs(%x), lcpRvs(%x)\n", dir, lcn, dt, lcp, lcnRvs, dtRvs, lcpRvs));
   2294     // add to list of channels
   2295     OlcParam* olc_param = iOlcs.FindOlcGivenChannel(dir, lcn);
   2296     if (olc_param == NULL)
   2297     {
   2298         SignalChannelClose(dir, lcn, lcnRvs == CHANNEL_ID_UNKNOWN ? EPVT_UNI_DIRECTIONAL : EPVT_BI_DIRECTIONAL);
   2299         return NULL;
   2300     }
   2301 
   2302     /* Is this a replacement channel outgoing channel ? */
   2303     if (dir == OUTGOING && olc_param->GetReplacementFor() != CHANNEL_ID_UNKNOWN)
   2304     {
   2305         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2306                         (0, "TSC_channelcontrol::OpenLogicalChannel Replacement for outgoing channel id=%d",
   2307                          olc_param->GetReplacementFor()));
   2308         ChannelReleased(OUTGOING, olc_param->GetReplacementFor(), PV2WayErrReplaced);
   2309         olc_param->SetReplacementFor(0);
   2310     }
   2311 
   2312     if (olc_param->GetReverseParams())
   2313         olc_param->GetReverseParams()->SetChannelId(lcnRvs);
   2314 
   2315     TPVDirection rvs_dir = REVERSE_DIR(dir);
   2316     OpenPort(dir, lcn, olc_param->GetForwardParams());
   2317     if (olc_param->GetReverseParams() &&
   2318             olc_param->GetReverseParams()->GetChannelId() != CHANNEL_ID_UNKNOWN)
   2319     {
   2320         OpenPort(rvs_dir, olc_param->GetReverseParams()->GetChannelId(),
   2321                  olc_param->GetReverseParams());
   2322     }
   2323     return olc_param;
   2324 }
   2325 void TSC_component::OpenPort(TPVDirection dir, TPVChannelId lcn, H223ChannelParam* param)
   2326 {
   2327     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2328                     (0, "TSC_channelcontrol::OpenPort dir(%d), lcn(%d), param(%x)\n",
   2329                      dir, lcn, param));
   2330     PVCodecType_t codec_type = ::GetCodecType(param->GetDataType());
   2331     if (codec_type == PV_CODEC_TYPE_NONE)
   2332     {
   2333         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2334                         (0, "TSC_channelcontrol::OpenPort codec_type==NONE", codec_type));
   2335         return;
   2336     }
   2337     iH223->OpenChannel(dir, lcn, param);
   2338 }
   2339 
   2340 
   2341 PS_DataType TSC_component::GetOutgoingDataType(PVCodecType_t codecType,
   2342         uint32 bitrate)
   2343 {
   2344     uint8* csi = NULL;
   2345     uint16 csi_len = 0;
   2346     return iTSCcapability.GetOutgoingDataType(codecType, bitrate, csi_len, csi);
   2347 }
   2348 
   2349 OlcParam* TSC_component::OpenOutgoingChannel(PVCodecType_t out_codec_type,
   2350         PS_AdaptationLayerType adaptation_layer,
   2351         PS_DataType pDataTypeRvs,
   2352         PS_H223LogicalChannelParameters pH223ParamsRvs)
   2353 {
   2354     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2355                     (0, "TSC_component::OpenOutgoingChannel codec(%d), layer(%x)",
   2356                      out_codec_type, adaptation_layer));
   2357     OlcParam* ret = NULL;
   2358     // allocate a channel id for this channel
   2359     TPVChannelId channel_id = iOlcs.GetNextAvailLcn();
   2360     uint32 bitrate = GetOutgoingBitrate(out_codec_type);
   2361 
   2362     /* Fill the data type for the outgoing codec */
   2363     PS_DataType pDataType = GetOutgoingDataType(out_codec_type, bitrate);
   2364 
   2365     /*  Fill the outgoing h223 logical channel parameters */
   2366     PS_H223LogicalChannelParameters pH223Params =
   2367         iTSCcapability.GetOutgoingLcnParams(GetMediaType(out_codec_type),
   2368                                             adaptation_layer);
   2369     if (adaptation_layer->index == 5)
   2370     { /* AL3 */
   2371         S_DataType nullDataType;
   2372         if (pDataTypeRvs == NULL)
   2373         {
   2374             nullDataType.index = 1;
   2375             pDataTypeRvs = &nullDataType;
   2376         }
   2377         if (pH223ParamsRvs == NULL)
   2378         {
   2379             pH223ParamsRvs = pH223Params;
   2380         }
   2381         PVCodecType_t in_codec_type = GetCodecType(pDataTypeRvs);
   2382         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2383                         (0, "TSC_component::OpenOutgoingChannel reverse codec(%d)", in_codec_type));
   2384         if (in_codec_type != out_codec_type)
   2385         {
   2386             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   2387                             (0, "TSC_component::OpenOutgoingChannel in codec type != out codec type"));
   2388         }
   2389         if (!CodecRequiresFsi(out_codec_type))
   2390         {
   2391             iTSCblc.BlcEtbReq(channel_id, pDataType, pH223Params,
   2392                               pDataTypeRvs, pH223ParamsRvs);
   2393         }
   2394         ret = iOlcs.AppendOlc(OUTGOING, channel_id, pDataType, pH223Params,
   2395                               CHANNEL_ID_UNKNOWN, pDataTypeRvs,
   2396                               pH223ParamsRvs);
   2397     }
   2398     else
   2399     {
   2400         if (!CodecRequiresFsi(out_codec_type))
   2401         {
   2402             iTSClc.LcEtbReq(channel_id, pDataType, pH223Params);
   2403         }
   2404 
   2405         ret = iOlcs.AppendOlc(OUTGOING, channel_id, pDataType, pH223Params);
   2406     }
   2407 
   2408     // Open the channel in the mux
   2409     OpenLogicalChannel(OUTGOING, ret->GetChannelId());
   2410     // Pause the channel untill OlcAck+MtAck is received
   2411     H223OutgoingChannelPtr outgoing_channel;
   2412     iH223->GetOutgoingChannel(ret->GetChannelId(), outgoing_channel);
   2413     if (Pausable())
   2414     {
   2415         outgoing_channel->Pause();
   2416     }
   2417     // Notify outgoing channel
   2418     iTSCObserver->OutgoingChannelEstablished(ret->GetChannelId(), out_codec_type,
   2419             NULL, 0); /* FSI will be generated by video source/encoder */
   2420 
   2421     Delete_DataType(pDataType);
   2422     OSCL_DEFAULT_FREE(pDataType);
   2423     Delete_H223LogicalChannelParameters(pH223Params);
   2424     OSCL_DEFAULT_FREE(pH223Params);
   2425     return ret;
   2426 }
   2427 
   2428 
   2429 bool TSC_component::queryInterface(const PVUuid& uuid, PVInterface*& iface)
   2430 {
   2431     // Only returns the component interface
   2432     if (uuid == PVUuidH324ComponentInterface)
   2433     {
   2434         PVMFComponentInterface* myInterface = OSCL_STATIC_CAST(PVMFComponentInterface*, this);
   2435         iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
   2436     }
   2437     else
   2438     {
   2439         return false;
   2440     }
   2441 
   2442     return true;
   2443 }
   2444 
   2445 #ifdef MEM_TRACK
   2446 void TSC_component::MemStats()
   2447 {
   2448 #if !(OSCL_BYPASS_MEMMGT)
   2449 
   2450     OsclAuditCB auditCB;
   2451     OsclMemInit(auditCB);
   2452     if (auditCB.pAudit)
   2453     {
   2454         MM_Stats_t* stats = auditCB.pAudit->MM_GetStats("");
   2455         if (stats)
   2456         {
   2457             printf("\n###################Memory Stats Start#################\n");
   2458             printf("  numBytes %d\n", stats->numBytes);
   2459             printf("  peakNumBytes %d\n", stats->peakNumBytes);
   2460             printf("  numAllocs %d\n", stats->numAllocs);
   2461             printf("  peakNumAllocs %d\n", stats->peakNumAllocs);
   2462             printf("  numAllocFails %d\n", stats->numAllocFails);
   2463             printf("  totalNumAllocs %d\n", stats->totalNumAllocs);
   2464             printf("  totalNumBytes %d\n", stats->totalNumBytes);
   2465             printf("\n###################Memory Stats End###################\n");
   2466         }
   2467 
   2468     }
   2469 #endif
   2470 }
   2471 #endif
   2472 
   2473