blob: 4e2e41706a6c899f1cd9edfa5c84030336c035fd [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
// ----------------------------------------------------------------------
//
// This Software is an original work of authorship of PacketVideo Corporation.
// Portions of the Software were developed in collaboration with NTT DoCoMo,
// Inc. or were derived from the public domain or materials licensed from
// third parties. Title and ownership, including all intellectual property
// rights in and to the Software shall remain with PacketVideo Corporation
// and NTT DoCoMo, Inc.
//
// -----------------------------------------------------------------------
/*****************************************************************************/
/* file name : tsc_mt.cpp */
/* file contents : Terminal State Control routine */
/* draw : '96.10.04 */
/*---------------------------------------------------------------------------*/
/* amendment */
/* Copyright (C) 1996 NTT DoCoMo */
/*****************************************************************************/
#include "tsc_mt.h"
#include "tsc_sub.h" /* Sub Routine Information Header */
#include "cpvh223multiplex.h"
#include "tsc_component.h"
#define TSC_FM_H263_MTE 5
#define TSC_FM_MAX_MTE TSC_FM_H263_MTE
#define FIRST_MUX_ENTRY_NUMBER TSC_FM_MAX_MTE + 1
#define LAST_MUX_ENTRY_NUMBER 14
void TSC_mt::ClearVars()
{
iToBeDeletedMuxEntryNumbers.clear();
iOutMtSn = 0;
iPendingMtSn = 0;
}
void TSC_mt::DeleteMuxEntry(uint32 aNum)
{
iToBeDeletedMuxEntryNumbers.push_back(aNum);
}
void TSC_mt::InitVarsSession()
{
// Initialize available multiplex entry numbers
iAvailableMuxEntryNumbers.clear();
for (int ii = TSC_FM_MAX_MTE + 1; ii <= LAST_MUX_ENTRY_NUMBER; ii++)
{
iAvailableMuxEntryNumbers.push_back(ii);
}
iOutMtSn = 0;
iPendingMtSn = 0;
}
bool TSC_mt::MuxTableSendComplete(uint32 sn)
{
if ((uint32)iPendingMtSn != sn)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0,
"TSC_mt::MuxTableSendComplete Outdated multipex entry send sn(%d), last sn(%d)",
sn, iPendingMtSn));
return false;
}
iPendingMtSn = -1;
return true;
}
bool TSC_mt::CheckMtTrf(Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator> aOutCodecList,
Oscl_Vector<H324ChannelParameters, PVMFTscAlloc>* aOutgoingChannelConfig)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "TSC_mt::CheckMtTrf"));
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0,
"TSC_mt::CheckMtTrf codec list size(%d), num h223 channels(%d)",
aOutCodecList.size(), iH223->GetNumChannels(OUTGOING)));
unsigned num_channels = (aOutgoingChannelConfig) ?
aOutgoingChannelConfig->size() : 0;
num_channels = aOutCodecList.size() < num_channels ?
aOutCodecList.size() : num_channels;
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "TSC_mt::CheckMtTrf num opened h223 channels(%d)", num_channels));
return (iH223->GetNumChannels(OUTGOING) >= num_channels) ? true : false;
}
/*****************************************************************************/
/* function name : Tsc_MtTrfRps */
/* function outline : Tsc_MtTrfRps procedure */
/* function discription : Tsc_MtTrfRps( void ) */
/* input data : None */
/* output data : None */
/* draw time : '96.10.09 */
/*---------------------------------------------------------------------------*/
/* amendent career (x) : */
/* */
/* Copyright (C) 1996 NTT DoCoMo */
/*****************************************************************************/
void TSC_mt::MtTrfRps(uint32 sequenceNumber, PS_MuxDescriptor pMux)
{
S_ControlMsgHeader infHeader;
Tsc_SendDataSet(&infHeader,
H245_PRIMITIVE,
E_PtvId_Mt_Trf_Rps,
sequenceNumber,
0,
(uint8*)pMux,
sizeof(S_MuxDescriptor));
// Primitive Send
iH245->DispatchControlMessage(&infHeader);
return;
}
/*****************************************************************************/
/* function name : Tsc_MtRjtReq */
/* function outline : Tsc_MtRjtReq procedure */
/* function discription : Tsc_MtRjtReq( pReceiveInf ) */
/* input data : PS_ControlMsgHeader */
/* output data : None */
/* draw time : '96.10.09 */
/*---------------------------------------------------------------------------*/
/* amendent career (x) : */
/* */
/* Copyright (C) 1996 NTT DoCoMo */
/*****************************************************************************/
void TSC_mt::MtRjtReq()
{
S_ControlMsgHeader infHeader;
S_MeRejectCause parameter;
// REJECT.request primitive - Parameter[CAUSE]
parameter.index = 1;
Tsc_SendDataSet(&infHeader,
H245_PRIMITIVE,
E_PtvId_Mt_Rjt_Req,
0,
0,
(uint8*)&parameter,
sizeof(S_MeRejectCause));
// Primitive Send
iH245->DispatchControlMessage(&infHeader);
}
CPVMultiplexEntryDescriptor* TSC_mt::GenerateCombinedDescriptor(uint8 entry_num,
TPVChannelId lcn1,
unsigned lcn1_size,
TPVChannelId lcn2)
{
PS_MultiplexEntryDescriptor h245_desc =
(PS_MultiplexEntryDescriptor)OSCL_DEFAULT_MALLOC(sizeof(S_MultiplexEntryDescriptor));
h245_desc->multiplexTableEntryNumber = entry_num;
h245_desc->option_of_elementList = true;
h245_desc->size_of_elementList = 2;
h245_desc->elementList =
(PS_MultiplexElement)OSCL_DEFAULT_MALLOC(2 * sizeof(S_MultiplexElement));
oscl_memset(h245_desc->elementList, 0, 2 * sizeof(S_MultiplexElement));
PS_MultiplexElement elem = h245_desc->elementList;
elem->muxType.index = 0;
elem->muxType.logicalChannelNumber = (uint16)lcn1;
elem->muxType.size = 1;
elem->repeatCount.index = 0;
elem->repeatCount.finite = (uint16)lcn1_size;
elem++;
elem->muxType.index = 0;
elem->muxType.logicalChannelNumber = (uint16)lcn2;
elem->muxType.size = 1;
elem->repeatCount.index = 1;
CPVMultiplexEntryDescriptor* ret = CPVMultiplexEntryDescriptor::NewL(h245_desc, 128);
Delete_MultiplexEntryDescriptor(h245_desc);
OSCL_DEFAULT_FREE(h245_desc);
return ret;
}
uint32 TSC_mt::SendMuxTableForLcn(TPVChannelId lcn)
{
S_ControlMsgHeader infHeader;
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "TSC_mt::SendMuxTableForLcn lcn(%d)", lcn));
CPVMultiplexEntryDescriptorVector descriptors;
if (iAvailableMuxEntryNumbers.size() == 0)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
(0, "TSC_mt::SendMuxTableForLcn Ran out of mux table entries"));
OSCL_LEAVE(PVMFErrNoResources);
}
int entry_num = iAvailableMuxEntryNumbers[0];
iAvailableMuxEntryNumbers.erase(iAvailableMuxEntryNumbers.begin());
CPVMultiplexEntryDescriptor* desc =
iTSCcomponent->GenerateSingleDescriptor((uint8)entry_num, lcn);
descriptors.push_back(desc);
iH223->SetOutgoingMuxDescriptors(descriptors);
PS_MuxDescriptor mux_descriptor =
(PS_MuxDescriptor)OSCL_DEFAULT_MALLOC(sizeof(S_MuxDescriptor));
oscl_memset(mux_descriptor, 0, sizeof(S_MuxDescriptor));
mux_descriptor->size_of_multiplexEntryDescriptors = 1;
mux_descriptor->multiplexEntryDescriptors = desc->GetH245descriptor();
Tsc_SendDataSet(&infHeader,
H245_PRIMITIVE,
E_PtvId_Mt_Trf_Req,
0,
0,
(uint8*)mux_descriptor,
sizeof(S_MuxDescriptor));
// Primitive Send
iH245->DispatchControlMessage(&infHeader);
OSCL_DEFAULT_FREE(mux_descriptor);
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0,
"TSC_mt::SendMuxTableForLcn lcn(%d), mt sn(%d), mt num(%d)",
lcn, iOutMtSn, entry_num));
return entry_num;
}
void TSC_mt::ReleaseMuxTables()
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "TSC_mt::ReleaseMuxTable "));
S_ControlMsgHeader infHeader;
if (iToBeDeletedMuxEntryNumbers.size() == 0)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "TSC_mt::ReleaseMuxTable No MT entries to be released"));
return;
}
unsigned mem_size = sizeof(S_MuxDescriptor) +
iToBeDeletedMuxEntryNumbers.size() * sizeof(S_MultiplexEntryDescriptor);
uint8* mem_ptr = (uint8*)OSCL_DEFAULT_MALLOC(mem_size);
if (mem_ptr == NULL)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "TSC_mt::ReleaseMuxTable ERROR: Memory allocation failed."));
return;
}
oscl_memset(mem_ptr, 0, mem_size);
PS_MuxDescriptor mux_descriptor = (PS_MuxDescriptor)mem_ptr;
mux_descriptor->size_of_multiplexEntryDescriptors =
iToBeDeletedMuxEntryNumbers.size();
mux_descriptor->multiplexEntryDescriptors =
(PS_MultiplexEntryDescriptor)(mem_ptr + sizeof(S_MuxDescriptor));
for (unsigned ii = 0; ii < iToBeDeletedMuxEntryNumbers.size(); ++ii)
{
uint8 mt_num = (uint8)iToBeDeletedMuxEntryNumbers[ii];
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0,
"TSC_mt::ReleaseMuxTable Deleting Entry number=%d, sn=%d",
mt_num, iOutMtSn));
iH223->RemoveOutgoingMuxDescriptor(mt_num);
mux_descriptor->multiplexEntryDescriptors[ii].option_of_elementList =
false;
mux_descriptor->multiplexEntryDescriptors[ii].multiplexTableEntryNumber =
(int8)mt_num;
iAvailableMuxEntryNumbers.push_back(mt_num);
}
Tsc_SendDataSet(&infHeader,
H245_PRIMITIVE,
E_PtvId_Mt_Trf_Req,
0,
0,
(uint8*)mux_descriptor,
sizeof(S_MuxDescriptor));
// Primitive Send
iH245->DispatchControlMessage(&infHeader);
OSCL_DEFAULT_FREE(mem_ptr);
iPendingMtSn = iOutMtSn++;
iToBeDeletedMuxEntryNumbers.clear();
}
/**
* Generates and send multiplex table entries for all logical channels for which MT state is idle/pending
**/
void TSC_mt::MtTrfReq(OlcList& aOlcs)
{
S_ControlMsgHeader infHeader;
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "TSC_mt::MtTrfReq"));
CPVMultiplexEntryDescriptorVector descriptors;
CPVMultiplexEntryDescriptor* desc = NULL;
Oscl_Vector<OlcParam*, OsclMemAllocator> olc_list;
unsigned num_pending = aOlcs.FindOutgoingOlcsByMtState(MT_IDLE | MT_PENDING,
olc_list);
if (num_pending == 0)
{
// No mux entries to send
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "TSC_mt::MtTrfReq No mux entries to send"));
return;
}
if (iAvailableMuxEntryNumbers.size() < num_pending)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
(0,
"TSC_mt::MtTrfReq Ran out of mux table entries - needed(%d), have(%d)",
num_pending, iAvailableMuxEntryNumbers.size()));
OSCL_LEAVE(PVMFErrNoResources);
}
for (unsigned lcn = 0; lcn < num_pending; ++lcn)
{
int entry_num = iAvailableMuxEntryNumbers[0];
iAvailableMuxEntryNumbers.erase(iAvailableMuxEntryNumbers.begin());
TPVChannelId channel_id = (olc_list[lcn]->GetDirection() == OUTGOING) ?
olc_list[lcn]->GetChannelId() :
olc_list[lcn]->GetReverseParams()->GetChannelId();
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "TSC_mt::MtTrfReq Descriptor for lcn(%d)=%d", channel_id, entry_num));
desc = iTSCcomponent->GenerateSingleDescriptor((uint8)entry_num, channel_id);
descriptors.push_back(desc);
olc_list[lcn]->SetMtState(MT_PENDING);
olc_list[lcn]->SetMtSn(iOutMtSn);
olc_list[lcn]->SetMtNum(entry_num);
}
iH223->SetOutgoingMuxDescriptors(descriptors);
PS_MultiplexEntryDescriptor temp = NULL;
PS_MuxDescriptor mux_descriptor =
(PS_MuxDescriptor)OSCL_DEFAULT_MALLOC(sizeof(S_MuxDescriptor));
oscl_memset(mux_descriptor, 0, sizeof(S_MuxDescriptor));
mux_descriptor->size_of_multiplexEntryDescriptors = descriptors.size();
mux_descriptor->multiplexEntryDescriptors =
(PS_MultiplexEntryDescriptor)OSCL_DEFAULT_MALLOC(
sizeof(S_MultiplexEntryDescriptor) *
mux_descriptor->size_of_multiplexEntryDescriptors);
oscl_memset(mux_descriptor->multiplexEntryDescriptors,
0,
sizeof(S_MultiplexEntryDescriptor) *
mux_descriptor->size_of_multiplexEntryDescriptors);
PS_MultiplexEntryDescriptor cur_desc =
mux_descriptor->multiplexEntryDescriptors;
Oscl_Vector<PS_MultiplexEntryDescriptor, PVMFTscAlloc> to_be_deleted;
for (unsigned num = 0; num < descriptors.size(); ++num)
{
temp = Copy_MultiplexEntryDescriptor(
descriptors[num]->GetH245descriptor());
oscl_memcpy(cur_desc, temp, sizeof(S_MultiplexEntryDescriptor));
cur_desc++;
to_be_deleted.push_back(temp);
}
Tsc_SendDataSet(&infHeader,
H245_PRIMITIVE,
E_PtvId_Mt_Trf_Req,
0,
0,
(uint8*)mux_descriptor,
sizeof(S_MuxDescriptor));
// Primitive Send
iH245->DispatchControlMessage(&infHeader);
while (to_be_deleted.size())
{
PS_MultiplexEntryDescriptor desc = to_be_deleted.back();
Delete_MultiplexEntryDescriptor(desc);
OSCL_DEFAULT_FREE(desc);
to_be_deleted.pop_back();
}
OSCL_DEFAULT_FREE(mux_descriptor->multiplexEntryDescriptors);
OSCL_DEFAULT_FREE(mux_descriptor);
iPendingMtSn = iOutMtSn++;
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "TSC_mt::MtTrfReq iOutMtSn(%d)", iOutMtSn));
}