cat.c   cat.c 
/************************************************************************** *** /************************************************************************** ***
* cat.c: CAT decoder/generator * cat.c: CAT decoder/generator
*------------------------------------------------------------------------- --- *------------------------------------------------------------------------- ---
* Copyright (C) 2001-2010 VideoLAN * Copyright (C) 2001-2011 VideoLAN
* $Id$ * $Id$
* *
* Authors: Johann Hanne * Authors: Johann Hanne
* heavily based on pmt.c which was written by * heavily based on pmt.c which was written by
* Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr> * Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
* Jean-Paul Saman <jpsaman@videolan.org>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
skipping to change at line 33 skipping to change at line 34
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130 1 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130 1 USA
* *
*------------------------------------------------------------------------- --- *------------------------------------------------------------------------- ---
* *
************************************************************************** ***/ ************************************************************************** ***/
#include "config.h" #include "config.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include <string.h> #include <string.h>
#if defined(HAVE_INTTYPES_H) #if defined(HAVE_INTTYPES_H)
#include <inttypes.h> #include <inttypes.h>
#elif defined(HAVE_STDINT_H) #elif defined(HAVE_STDINT_H)
#include <stdint.h> #include <stdint.h>
#endif #endif
#include <assert.h>
#include "../dvbpsi.h" #include "../dvbpsi.h"
#include "../dvbpsi_private.h" #include "../dvbpsi_private.h"
#include "../psi.h" #include "../psi.h"
#include "../descriptor.h" #include "../descriptor.h"
#include "cat.h" #include "cat.h"
#include "cat_private.h" #include "cat_private.h"
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_AttachCAT * dvbpsi_cat_attach
************************************************************************** *** ************************************************************************** ***
* Initialize a CAT decoder and return a handle on it. * Initialize a CAT decoder and return a handle on it.
************************************************************************** ***/ ************************************************************************** ***/
dvbpsi_handle dvbpsi_AttachCAT(dvbpsi_cat_callback pf_callback, bool dvbpsi_cat_attach(dvbpsi_t *p_dvbpsi, dvbpsi_cat_callback pf_callback,
void* p_cb_data) void* p_cb_data)
{ {
dvbpsi_handle h_dvbpsi = (dvbpsi_decoder_t*)malloc(sizeof(dvbpsi_decoder_ assert(p_dvbpsi);
t)); assert(p_dvbpsi->p_decoder == NULL);
dvbpsi_cat_decoder_t* p_cat_decoder;
if(h_dvbpsi == NULL)
return NULL;
p_cat_decoder = (dvbpsi_cat_decoder_t*)malloc(sizeof(dvbpsi_cat_decoder_t dvbpsi_cat_decoder_t* p_cat_decoder;
)); p_cat_decoder = (dvbpsi_cat_decoder_t*) dvbpsi_decoder_new(&dvbpsi_cat_
sections_gather,
if(p_cat_decoder == NULL) 1024, true, sizeof(dvbpsi_c
{ at_decoder_t));
free(h_dvbpsi); if (p_cat_decoder == NULL)
return NULL; return false;
}
/* CAT decoder configuration */
/* PSI decoder configuration */ p_cat_decoder->pf_cat_callback = pf_callback;
h_dvbpsi->pf_callback = &dvbpsi_GatherCATSections; p_cat_decoder->p_cb_data = p_cb_data;
h_dvbpsi->p_private_decoder = p_cat_decoder; p_cat_decoder->p_building_cat = NULL;
h_dvbpsi->i_section_max_size = 1024;
/* PSI decoder initial state */
h_dvbpsi->i_continuity_counter = 31;
h_dvbpsi->b_discontinuity = 1;
h_dvbpsi->p_current_section = NULL;
/* CAT decoder configuration */
p_cat_decoder->pf_callback = pf_callback;
p_cat_decoder->p_cb_data = p_cb_data;
/* CAT decoder initial state */
p_cat_decoder->b_current_valid = 0;
p_cat_decoder->p_building_cat = NULL;
for(unsigned int i = 0; i <= 255; i++)
p_cat_decoder->ap_sections[i] = NULL;
return h_dvbpsi; p_dvbpsi->p_decoder = DVBPSI_DECODER(p_cat_decoder);
return true;
} }
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_DetachCAT * dvbpsi_cat_detach
************************************************************************** *** ************************************************************************** ***
* Close a CAT decoder. The handle isn't valid any more. * Close a CAT decoder. The handle isn't valid any more.
************************************************************************** ***/ ************************************************************************** ***/
void dvbpsi_DetachCAT(dvbpsi_handle h_dvbpsi) void dvbpsi_cat_detach(dvbpsi_t *p_dvbpsi)
{ {
dvbpsi_cat_decoder_t* p_cat_decoder assert(p_dvbpsi);
= (dvbpsi_cat_decoder_t*)h_dvbpsi->p_private_decode assert(p_dvbpsi->p_decoder);
r;
free(p_cat_decoder->p_building_cat);
for(unsigned int i = 0; i <= 255; i++) dvbpsi_cat_decoder_t* p_cat_decoder
{ = (dvbpsi_cat_decoder_t*)p_dvbpsi->p_decoder;
if(p_cat_decoder->ap_sections[i]) if (p_cat_decoder->p_building_cat)
free(p_cat_decoder->ap_sections[i]); dvbpsi_cat_delete(p_cat_decoder->p_building_cat);
} p_cat_decoder->p_building_cat = NULL;
free(h_dvbpsi->p_private_decoder); dvbpsi_decoder_delete(p_dvbpsi->p_decoder);
if(h_dvbpsi->p_current_section) p_dvbpsi->p_decoder = NULL;
dvbpsi_DeletePSISections(h_dvbpsi->p_current_section);
free(h_dvbpsi);
} }
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_InitCAT * dvbpsi_cat_init
************************************************************************** *** ************************************************************************** ***
* Initialize a pre-allocated dvbpsi_cat_t structure. * Initialize a pre-allocated dvbpsi_cat_t structure.
************************************************************************** ***/ ************************************************************************** ***/
void dvbpsi_InitCAT(dvbpsi_cat_t* p_cat, void dvbpsi_cat_init(dvbpsi_cat_t* p_cat, uint8_t i_version, bool b_current
uint8_t i_version, int b_current_next) _next)
{
assert(p_cat);
p_cat->i_version = i_version;
p_cat->b_current_next = b_current_next;
p_cat->p_first_descriptor = NULL;
}
/**************************************************************************
***
* dvbpsi_cat_new
**************************************************************************
***
* Allocate and Initialize a dvbpsi_cat_t structure.
**************************************************************************
***/
dvbpsi_cat_t *dvbpsi_cat_new(uint8_t i_version, bool b_current_next)
{ {
p_cat->i_version = i_version; dvbpsi_cat_t *p_cat = (dvbpsi_cat_t*)malloc(sizeof(dvbpsi_cat_t));
p_cat->b_current_next = b_current_next; if (p_cat != NULL)
p_cat->p_first_descriptor = NULL; dvbpsi_cat_init(p_cat, i_version, b_current_next);
return p_cat;
} }
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_EmptyCAT * dvbpsi_cat_empty
************************************************************************** *** ************************************************************************** ***
* Clean a dvbpsi_cat_t structure. * Clean a dvbpsi_cat_t structure.
************************************************************************** ***/ ************************************************************************** ***/
void dvbpsi_EmptyCAT(dvbpsi_cat_t* p_cat) void dvbpsi_cat_empty(dvbpsi_cat_t* p_cat)
{ {
dvbpsi_DeleteDescriptors(p_cat->p_first_descriptor); dvbpsi_DeleteDescriptors(p_cat->p_first_descriptor);
p_cat->p_first_descriptor = NULL;
}
p_cat->p_first_descriptor = NULL; /**************************************************************************
***
* dvbpsi_cat_delete
**************************************************************************
***
* Clean a dvbpsi_cat_t structure.
**************************************************************************
***/
void dvbpsi_cat_delete(dvbpsi_cat_t *p_cat)
{
if (p_cat)
dvbpsi_cat_empty(p_cat);
free(p_cat);
} }
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_CATAddDescriptor * dvbpsi_cat_descriptor_add
************************************************************************** *** ************************************************************************** ***
* Add a descriptor in the CAT. * Add a descriptor in the CAT.
************************************************************************** ***/ ************************************************************************** ***/
dvbpsi_descriptor_t* dvbpsi_CATAddDescriptor(dvbpsi_cat_t* p_cat, dvbpsi_descriptor_t* dvbpsi_cat_descriptor_add(dvbpsi_cat_t* p_cat,
uint8_t i_tag, uint8_t i_lengt h, uint8_t i_tag, uint8_t i_lengt h,
uint8_t* p_data) uint8_t* p_data)
{ {
dvbpsi_descriptor_t* p_descriptor dvbpsi_descriptor_t* p_descriptor
= dvbpsi_NewDescriptor(i_tag, i_length, p_data); = dvbpsi_NewDescriptor(i_tag, i_length, p_data);
if (p_descriptor == NULL)
return NULL;
p_cat->p_first_descriptor = dvbpsi_AddDescriptor(p_cat->p_first_descrip
tor,
p_descriptor);
assert(p_cat->p_first_descriptor);
if (p_cat->p_first_descriptor == NULL)
return NULL;
return p_descriptor;
}
/* */
static void dvbpsi_ReInitCAT(dvbpsi_cat_decoder_t* p_decoder, const bool b_
force)
{
assert(p_decoder);
if(p_descriptor) dvbpsi_decoder_reset(DVBPSI_DECODER(p_decoder), b_force);
{
if(p_cat->p_first_descriptor == NULL) /* Force redecoding */
if (b_force)
{ {
p_cat->p_first_descriptor = p_descriptor; /* Free structures */
if (p_decoder->p_building_cat)
dvbpsi_cat_delete(p_decoder->p_building_cat);
}
p_decoder->p_building_cat = NULL;
}
static bool dvbpsi_CheckCAT(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t *p_sec
tion)
{
bool b_reinit = false;
assert(p_dvbpsi->p_decoder);
dvbpsi_cat_decoder_t* p_cat_decoder;
p_cat_decoder = (dvbpsi_cat_decoder_t *)p_dvbpsi->p_decoder;
/* Perform a few sanity checks */
#if 0
if (p_pat_decoder->p_building_pat->i_ts_id != p_section->i_extension)
{
/* transport_stream_id */
dvbpsi_error(p_dvbpsi, "PAT decoder",
"'transport_stream_id' differs"
" whereas no TS discontinuity has occured");
b_reinit = true;
} }
else else
#endif
if (p_cat_decoder->p_building_cat->i_version != p_section->i_version)
{
/* version_number */
dvbpsi_error(p_dvbpsi, "CAT decoder",
"'version_number' differs"
" whereas no discontinuity has occured");
b_reinit = true;
}
else if (p_cat_decoder->i_last_section_number != p_section->i_last_numb
er)
{
/* last_section_number */
dvbpsi_error(p_dvbpsi, "CAT decoder",
"'last_section_number' differs"
" whereas no discontinuity has occured");
b_reinit = true;
}
return b_reinit;
}
static bool dvbpsi_AddSectionCAT(dvbpsi_t *p_dvbpsi, dvbpsi_cat_decoder_t *
p_decoder,
dvbpsi_psi_section_t* p_section)
{
assert(p_dvbpsi);
assert(p_decoder);
assert(p_section);
/* Initialize the structures if it's the first section received */
if (p_decoder->p_building_cat == NULL)
{ {
dvbpsi_descriptor_t* p_last_descriptor = p_cat->p_first_descriptor; p_decoder->p_building_cat = dvbpsi_cat_new(p_section->i_version,
while(p_last_descriptor->p_next != NULL) p_section->b_current_nex
p_last_descriptor = p_last_descriptor->p_next; t);
p_last_descriptor->p_next = p_descriptor; if (p_decoder->p_building_cat == NULL)
return false;
p_decoder->i_last_section_number = p_section->i_last_number;
} }
}
return p_descriptor; /* Add to linked list of sections */
if (dvbpsi_decoder_psi_section_add(DVBPSI_DECODER(p_decoder), p_section
))
dvbpsi_debug(p_dvbpsi, "CAT decoder", "overwrite section number %d"
,
p_section->i_number);
return true;
} }
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_GatherCATSections * dvbpsi_cat_sections_gather
************************************************************************** *** ************************************************************************** ***
* Callback for the PSI decoder. * Callback for the PSI decoder.
************************************************************************** ***/ ************************************************************************** ***/
void dvbpsi_GatherCATSections(dvbpsi_decoder_t* p_decoder, void dvbpsi_cat_sections_gather(dvbpsi_t *p_dvbpsi,
dvbpsi_psi_section_t* p_section) dvbpsi_psi_section_t* p_section)
{ {
dvbpsi_cat_decoder_t* p_cat_decoder assert(p_dvbpsi);
= (dvbpsi_cat_decoder_t*)p_decoder->p_private_decod assert(p_dvbpsi->p_decoder);
er;
int b_append = 1; if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0x01, "CAT decoder"))
int b_reinit = 0; {
dvbpsi_DeletePSISections(p_section);
DVBPSI_DEBUG_ARG("CAT decoder", return;
"Table version %2d, " "i_extension %5d, " }
"section %3d up to %3d, " "current %1d",
p_section->i_version, p_section->i_extension, /* */
p_section->i_number, p_section->i_last_number, dvbpsi_cat_decoder_t* p_cat_decoder
p_section->b_current_next); = (dvbpsi_cat_decoder_t*)p_dvbpsi->p_decoder;
if(p_section->i_table_id != 0x01)
{
/* Invalid table_id value */
DVBPSI_ERROR_ARG("CAT decoder",
"invalid section (table_id == 0x%02x)",
p_section->i_table_id);
b_append = 0;
}
if(b_append && !p_section->b_syntax_indicator)
{
/* Invalid section_syntax_indicator */
DVBPSI_ERROR("CAT decoder",
"invalid section (section_syntax_indicator == 0)");
b_append = 0;
}
if(b_append)
{
/* TS discontinuity check */ /* TS discontinuity check */
if(p_decoder->b_discontinuity) if (p_cat_decoder->b_discontinuity)
{ {
b_reinit = 1; dvbpsi_ReInitCAT(p_cat_decoder, true);
p_decoder->b_discontinuity = 0; p_cat_decoder->b_discontinuity = false;
} }
else else
{ {
/* Perform some few sanity checks */ /* Perform some few sanity checks */
if(p_cat_decoder->p_building_cat) if (p_cat_decoder->p_building_cat)
{
if(p_cat_decoder->p_building_cat->i_version != p_section->i_version
)
{
/* version_number */
DVBPSI_ERROR("CAT decoder",
"'version_number' differs"
" whereas no discontinuity has occured");
b_reinit = 1;
}
else if(p_cat_decoder->i_last_section_number
!= p_section->i_last_number
)
{ {
/* last_section_number */ if (dvbpsi_CheckCAT(p_dvbpsi, p_section))
DVBPSI_ERROR("CAT decoder", dvbpsi_ReInitCAT(p_cat_decoder, true);
"'last_section_number' differs"
" whereas no discontinuity has occured");
b_reinit = 1;
} }
} else
else
{
if( (p_cat_decoder->b_current_valid)
&& (p_cat_decoder->current_cat.i_version == p_section->i_versio
n)
&& (p_cat_decoder->current_cat.b_current_next ==
p_section->b_current_next))
{ {
/* Don't decode since this version is already decoded */ if ( (p_cat_decoder->b_current_valid)
b_append = 0; && (p_cat_decoder->current_cat.i_version == p_section->i_v
ersion)
&& (p_cat_decoder->current_cat.b_current_next ==
p_section->b_current_nex
t))
{
/* Don't decode since this version is already decoded */
dvbpsi_debug(p_dvbpsi, "CAT decoder",
"ignoring already decoded section %d",
p_section->i_number);
dvbpsi_DeletePSISections(p_section);
return;
}
} }
}
}
}
/* Reinit the decoder if wanted */
if(b_reinit)
{
/* Force redecoding */
p_cat_decoder->b_current_valid = 0;
/* Free structures */
if(p_cat_decoder->p_building_cat)
{
free(p_cat_decoder->p_building_cat);
p_cat_decoder->p_building_cat = NULL;
}
/* Clear the section array */
for(unsigned int i = 0; i <= 255; i++)
{
if(p_cat_decoder->ap_sections[i] != NULL)
{
dvbpsi_DeletePSISections(p_cat_decoder->ap_sections[i]);
p_cat_decoder->ap_sections[i] = NULL;
}
}
}
/* Append the section to the list if wanted */
if(b_append)
{
int b_complete;
/* Initialize the structures if it's the first section received */
if(!p_cat_decoder->p_building_cat)
{
p_cat_decoder->p_building_cat =
(dvbpsi_cat_t*)malloc(sizeof(dvbpsi_cat_t))
;
dvbpsi_InitCAT(p_cat_decoder->p_building_cat,
p_section->i_version,
p_section->b_current_next);
p_cat_decoder->i_last_section_number = p_section->i_last_number;
} }
/* Fill the section array */ /* Add section to CAT */
if(p_cat_decoder->ap_sections[p_section->i_number] != NULL) if (!dvbpsi_AddSectionCAT(p_dvbpsi, p_cat_decoder, p_section))
{ {
DVBPSI_DEBUG_ARG("CAT decoder", "overwrite section number %d", dvbpsi_error(p_dvbpsi, "CAT decoder", "failed decoding section %d",
p_section->i_number); p_section->i_number);
dvbpsi_DeletePSISections(p_cat_decoder->ap_sections[p_section->i_numb dvbpsi_DeletePSISections(p_section);
er]); return;
} }
p_cat_decoder->ap_sections[p_section->i_number] = p_section;
/* Check if we have all the sections */ /* Check if we have all the sections */
b_complete = 0; if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_cat_decoder)
for(unsigned int i = 0; i <= p_cat_decoder->i_last_section_number; i++) ))
{ {
if(!p_cat_decoder->ap_sections[i]) assert(p_cat_decoder->pf_cat_callback);
break;
if(i == p_cat_decoder->i_last_section_number) /* Save the current information */
b_complete = 1; p_cat_decoder->current_cat = *p_cat_decoder->p_building_cat;
p_cat_decoder->b_current_valid = true;
/* Decode the sections */
dvbpsi_cat_sections_decode(p_cat_decoder->p_building_cat,
p_cat_decoder->p_sections);
/* Delete the sections */
dvbpsi_DeletePSISections(p_cat_decoder->p_sections);
p_cat_decoder->p_sections = NULL;
/* signal the new CAT */
p_cat_decoder->pf_cat_callback(p_cat_decoder->p_cb_data,
p_cat_decoder->p_building_cat);
/* Reinitialize the structures */
dvbpsi_ReInitCAT(p_cat_decoder, false);
} }
if(b_complete)
{
/* Save the current information */
p_cat_decoder->current_cat = *p_cat_decoder->p_building_cat;
p_cat_decoder->b_current_valid = 1;
/* Chain the sections */
if(p_cat_decoder->i_last_section_number)
{
for(unsigned int i = 0; (int)i <= p_cat_decoder->i_last_section_num
ber - 1; i++)
p_cat_decoder->ap_sections[i]->p_next =
p_cat_decoder->ap_sections[i + 1];
}
/* Decode the sections */
dvbpsi_DecodeCATSections(p_cat_decoder->p_building_cat,
p_cat_decoder->ap_sections[0]);
/* Delete the sections */
dvbpsi_DeletePSISections(p_cat_decoder->ap_sections[0]);
/* signal the new CAT */
p_cat_decoder->pf_callback(p_cat_decoder->p_cb_data,
p_cat_decoder->p_building_cat);
/* Reinitialize the structures */
p_cat_decoder->p_building_cat = NULL;
for(unsigned int i = 0; i <= p_cat_decoder->i_last_section_number; i+
+)
p_cat_decoder->ap_sections[i] = NULL;
}
}
else
{
dvbpsi_DeletePSISections(p_section);
}
} }
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_DecodeCATSections * dvbpsi_cat_sections_decode
************************************************************************** *** ************************************************************************** ***
* CAT decoder. * CAT decoder.
************************************************************************** ***/ ************************************************************************** ***/
void dvbpsi_DecodeCATSections(dvbpsi_cat_t* p_cat, void dvbpsi_cat_sections_decode(dvbpsi_cat_t* p_cat, dvbpsi_psi_section_t*
dvbpsi_psi_section_t* p_section) p_section)
{ {
uint8_t* p_byte; uint8_t* p_byte;
while(p_section) while (p_section)
{
/* CAT descriptors */
p_byte = p_section->p_payload_start;
while(p_byte + 5 <= p_section->p_payload_end)
{ {
uint8_t i_tag = p_byte[0]; /* CAT descriptors */
uint8_t i_length = p_byte[1]; p_byte = p_section->p_payload_start;
if(i_length + 2 <= p_section->p_payload_end - p_byte) while (p_byte + 5 <= p_section->p_payload_end)
dvbpsi_CATAddDescriptor(p_cat, i_tag, i_length, p_byte + 2); {
p_byte += 2 + i_length; uint8_t i_tag = p_byte[0];
uint8_t i_length = p_byte[1];
if (i_length + 2 <= p_section->p_payload_end - p_byte)
dvbpsi_cat_descriptor_add(p_cat, i_tag, i_length, p_byte +
2);
p_byte += 2 + i_length;
}
p_section = p_section->p_next;
} }
p_section = p_section->p_next;
}
} }
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_GenCATSections * dvbpsi_cat_sections_generate
************************************************************************** *** ************************************************************************** ***
* Generate CAT sections based on the dvbpsi_cat_t structure. * Generate CAT sections based on the dvbpsi_cat_t structure.
************************************************************************** ***/ ************************************************************************** ***/
dvbpsi_psi_section_t* dvbpsi_GenCATSections(dvbpsi_cat_t* p_cat) dvbpsi_psi_section_t* dvbpsi_cat_sections_generate(dvbpsi_t* p_dvbpsi, dvbp si_cat_t* p_cat)
{ {
dvbpsi_psi_section_t* p_result = dvbpsi_NewPSISection(1024); dvbpsi_psi_section_t* p_result = dvbpsi_NewPSISection(1024);
dvbpsi_psi_section_t* p_current = p_result; dvbpsi_psi_section_t* p_current = p_result;
dvbpsi_psi_section_t* p_prev; dvbpsi_psi_section_t* p_prev;
dvbpsi_descriptor_t* p_descriptor = p_cat->p_first_descriptor; dvbpsi_descriptor_t* p_descriptor = p_cat->p_first_descriptor;
p_current->i_table_id = 0x01; p_current->i_table_id = 0x01;
p_current->b_syntax_indicator = 1; p_current->b_syntax_indicator = true;
p_current->b_private_indicator = 0; p_current->b_private_indicator = false;
p_current->i_length = 9; /* header + CRC_32 */ p_current->i_length = 9; /* header + CRC_32 */
p_current->i_extension = 0; /* Not used in the CAT */ p_current->i_extension = 0; /* Not used in the CAT */
p_current->i_version = p_cat->i_version; p_current->i_version = p_cat->i_version;
p_current->b_current_next = p_cat->b_current_next; p_current->b_current_next = p_cat->b_current_next;
p_current->i_number = 0; p_current->i_number = 0;
p_current->p_payload_end += 8; /* just after the header */ p_current->p_payload_end += 8; /* just after the header
p_current->p_payload_start = p_current->p_data + 8; */
p_current->p_payload_start = p_current->p_data + 8;
/* CAT descriptors */
while(p_descriptor != NULL) /* CAT descriptors */
{ while (p_descriptor != NULL)
/* New section if needed */
/* written_data_length + descriptor_length + 2 > 1024 - CRC_32_length *
/
if( (p_current->p_payload_end - p_current->p_data)
+ p_descriptor->i_length > 1018)
{ {
p_prev = p_current; /* New section if needed */
p_current = dvbpsi_NewPSISection(1024); /* written_data_length + descriptor_length + 2 > 1024 - CRC_32_leng
p_prev->p_next = p_current; th */
if( (p_current->p_payload_end - p_current->p_data)
p_current->i_table_id = 0x01; + p_descriptor->i_length > 1018)
p_current->b_syntax_indicator = 1; {
p_current->b_private_indicator = 0; p_prev = p_current;
p_current->i_length = 9; /* header + CRC_32 */ p_current = dvbpsi_NewPSISection(1024);
p_current->i_extension = 0; /* Not used in the CAT */ p_prev->p_next = p_current;
p_current->i_version = p_cat->i_version;
p_current->b_current_next = p_cat->b_current_next; p_current->i_table_id = 0x01;
p_current->i_number = p_prev->i_number + 1; p_current->b_syntax_indicator = true;
p_current->p_payload_end += 8; /* just after the header */ p_current->b_private_indicator = false;
p_current->p_payload_start = p_current->p_data + 8; p_current->i_length = 9; /* header + CRC_32 */
} p_current->i_extension = 0; /* Not used in the CA
T */
/* p_payload_end is where the descriptor begins */ p_current->i_version = p_cat->i_version;
p_current->p_payload_end[0] = p_descriptor->i_tag; p_current->b_current_next = p_cat->b_current_next;
p_current->p_payload_end[1] = p_descriptor->i_length; p_current->i_number = p_prev->i_number + 1;
memcpy(p_current->p_payload_end + 2, p_current->p_payload_end += 8; /* just after the hea
p_descriptor->p_data, der */
p_descriptor->i_length); p_current->p_payload_start = p_current->p_data + 8;
}
/* Increase length by descriptor_length + 2 */
p_current->p_payload_end += p_descriptor->i_length + 2; /* p_payload_end is where the descriptor begins */
p_current->i_length += p_descriptor->i_length + 2; p_current->p_payload_end[0] = p_descriptor->i_tag;
p_current->p_payload_end[1] = p_descriptor->i_length;
p_descriptor = p_descriptor->p_next; memcpy(p_current->p_payload_end + 2,
} p_descriptor->p_data, p_descriptor->i_length);
/* Finalization */ /* Increase length by descriptor_length + 2 */
p_prev = p_result; p_current->p_payload_end += p_descriptor->i_length + 2;
while(p_prev != NULL) p_current->i_length += p_descriptor->i_length + 2;
{
p_prev->i_last_number = p_current->i_number;
dvbpsi_BuildPSISection(p_prev);
p_prev = p_prev->p_next;
}
return p_result; p_descriptor = p_descriptor->p_next;
}
/* Finalization */
p_prev = p_result;
while (p_prev != NULL)
{
p_prev->i_last_number = p_current->i_number;
dvbpsi_BuildPSISection(p_dvbpsi, p_prev);
p_prev = p_prev->p_next;
}
return p_result;
} }
 End of changes. 60 change blocks. 
311 lines changed or deleted 316 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/