1 /*****************************************************************************
2  * nit.c: NIT decoder/generator
3  *----------------------------------------------------------------------------
4  * Copyright (C) 2001-2012 VideoLAN
5  * $Id$
6  *
7  * Authors: Johann Hanne
8  *          heavily based on pmt.c which was written by
9  *          Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
10  *          Jean-Paul Saman <jpsaman@videolan.org>
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with this library; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
25  *
26  *----------------------------------------------------------------------------
27  *
28  *****************************************************************************/
29 
30 #include "config.h"
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <stdbool.h>
35 #include <string.h>
36 
37 #if defined(HAVE_INTTYPES_H)
38 #include <inttypes.h>
39 #elif defined(HAVE_STDINT_H)
40 #include <stdint.h>
41 #endif
42 
43 #include <assert.h>
44 
45 #include "../dvbpsi.h"
46 #include "../dvbpsi_private.h"
47 #include "../psi.h"
48 #include "../descriptor.h"
49 #include "../demux.h"
50 #include "nit.h"
51 #include "nit_private.h"
52 
53 /*****************************************************************************
54  * dvbpsi_nit_attach
55  *****************************************************************************
56  * Initialize a NIT subtable decoder.
57  *****************************************************************************/
dvbpsi_nit_attach(dvbpsi_t * p_dvbpsi,uint8_t i_table_id,uint16_t i_extension,dvbpsi_nit_callback pf_callback,void * p_cb_data)58 bool dvbpsi_nit_attach(dvbpsi_t* p_dvbpsi, uint8_t i_table_id,
59                       uint16_t i_extension, dvbpsi_nit_callback pf_callback,
60                       void* p_cb_data)
61 {
62     assert(p_dvbpsi);
63     assert(p_dvbpsi->p_decoder);
64 
65     dvbpsi_demux_t* p_demux = (dvbpsi_demux_t*)p_dvbpsi->p_decoder;
66 
67     if (dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension))
68     {
69         dvbpsi_error(p_dvbpsi, "NIT decoder",
70                      "Already a decoder for (table_id == 0x%02x,"
71                      "extension == 0x%02x)",
72                      i_table_id, i_extension);
73         return false;
74     }
75 
76     dvbpsi_nit_decoder_t*  p_nit_decoder;
77     p_nit_decoder = (dvbpsi_nit_decoder_t*) dvbpsi_decoder_new(NULL,
78                                              0, true, sizeof(dvbpsi_nit_decoder_t));
79     if (p_nit_decoder == NULL)
80         return false;
81 
82     /* subtable decoder configuration */
83     dvbpsi_demux_subdec_t* p_subdec;
84     p_subdec = dvbpsi_NewDemuxSubDecoder(i_table_id, i_extension, dvbpsi_nit_detach,
85                                          dvbpsi_nit_sections_gather, DVBPSI_DECODER(p_nit_decoder));
86     if (p_subdec == NULL)
87     {
88         dvbpsi_decoder_delete(DVBPSI_DECODER(p_nit_decoder));
89         return false;
90     }
91 
92     /* Attach the subtable decoder to the demux */
93     dvbpsi_AttachDemuxSubDecoder(p_demux, p_subdec);
94 
95     /* NIT decoder information */
96     p_nit_decoder->i_network_id = i_extension;
97     p_nit_decoder->pf_nit_callback = pf_callback;
98     p_nit_decoder->p_cb_data = p_cb_data;
99     p_nit_decoder->p_building_nit = NULL;
100 
101     return true;
102 }
103 
104 /*****************************************************************************
105  * dvbpsi_nit_detach
106  *****************************************************************************
107  * Close a NIT decoder.
108  *****************************************************************************/
dvbpsi_nit_detach(dvbpsi_t * p_dvbpsi,uint8_t i_table_id,uint16_t i_extension)109 void dvbpsi_nit_detach(dvbpsi_t * p_dvbpsi, uint8_t i_table_id, uint16_t i_extension)
110 {
111     dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_decoder;
112 
113     dvbpsi_demux_subdec_t* p_subdec;
114     p_subdec = dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension);
115     if (p_subdec == NULL)
116     {
117         dvbpsi_error(p_dvbpsi, "NIT Decoder",
118                      "No such NIT decoder (table_id == 0x%02x,"
119                      "extension == 0x%02x)",
120                      i_table_id, i_extension);
121         return;
122     }
123 
124     dvbpsi_nit_decoder_t* p_nit_decoder;
125     p_nit_decoder = (dvbpsi_nit_decoder_t*)p_subdec->p_decoder;
126     if (p_nit_decoder->p_building_nit)
127         dvbpsi_nit_delete(p_nit_decoder->p_building_nit);
128     p_nit_decoder->p_building_nit = NULL;
129 
130     /* Free demux sub table decoder */
131     dvbpsi_DetachDemuxSubDecoder(p_demux, p_subdec);
132     dvbpsi_DeleteDemuxSubDecoder(p_subdec);
133 }
134 
135 /****************************************************************************
136  * dvbpsi_nit_init
137  *****************************************************************************
138  * Initialize a pre-allocated dvbpsi_nit_t structure.
139  *****************************************************************************/
dvbpsi_nit_init(dvbpsi_nit_t * p_nit,uint8_t i_table_id,uint16_t i_extension,uint16_t i_network_id,uint8_t i_version,bool b_current_next)140 void dvbpsi_nit_init(dvbpsi_nit_t* p_nit, uint8_t i_table_id, uint16_t i_extension,
141                      uint16_t i_network_id, uint8_t i_version, bool b_current_next)
142 {
143     p_nit->i_table_id = i_table_id;
144     p_nit->i_extension = i_extension;
145 
146     p_nit->i_network_id = i_network_id;
147     p_nit->i_version = i_version;
148     p_nit->b_current_next = b_current_next;
149     p_nit->p_first_descriptor = NULL;
150     p_nit->p_first_ts = NULL;
151 }
152 
153 /****************************************************************************
154  * dvbpsi_nit_new
155  *****************************************************************************
156  * Allocate and initialize a dvbpsi_nit_t structure.
157  *****************************************************************************/
dvbpsi_nit_new(uint8_t i_table_id,uint16_t i_extension,uint16_t i_network_id,uint8_t i_version,bool b_current_next)158 dvbpsi_nit_t *dvbpsi_nit_new(uint8_t i_table_id, uint16_t i_extension,
159                              uint16_t i_network_id, uint8_t i_version,
160                              bool b_current_next)
161 {
162     dvbpsi_nit_t*p_nit = (dvbpsi_nit_t*)malloc(sizeof(dvbpsi_nit_t));
163     if (p_nit != NULL)
164        dvbpsi_nit_init(p_nit, i_table_id, i_extension, i_network_id,
165                        i_version, b_current_next);
166     return p_nit;
167 }
168 
169 /*****************************************************************************
170  * dvbpsi_nit_empty
171  *****************************************************************************
172  * Clean a dvbpsi_nit_t structure.
173  *****************************************************************************/
dvbpsi_nit_empty(dvbpsi_nit_t * p_nit)174 void dvbpsi_nit_empty(dvbpsi_nit_t* p_nit)
175 {
176     dvbpsi_nit_ts_t* p_ts = p_nit->p_first_ts;
177 
178     dvbpsi_DeleteDescriptors(p_nit->p_first_descriptor);
179 
180     while (p_ts != NULL)
181     {
182         dvbpsi_nit_ts_t* p_tmp = p_ts->p_next;
183         dvbpsi_DeleteDescriptors(p_ts->p_first_descriptor);
184         free(p_ts);
185         p_ts = p_tmp;
186     }
187 
188     p_nit->p_first_descriptor = NULL;
189     p_nit->p_first_ts = NULL;
190 }
191 
192 /****************************************************************************
193  * dvbpsi_nit_delete
194  *****************************************************************************
195  * Clean and delete a dvbpsi_nit_t structure.
196  *****************************************************************************/
dvbpsi_nit_delete(dvbpsi_nit_t * p_nit)197 void dvbpsi_nit_delete(dvbpsi_nit_t *p_nit)
198 {
199     if (p_nit)
200         dvbpsi_nit_empty(p_nit);
201     free(p_nit);
202 }
203 
204 /*****************************************************************************
205  * dvbpsi_nit_descriptor_add
206  *****************************************************************************
207  * Add a descriptor in the NIT.
208  *****************************************************************************/
dvbpsi_nit_descriptor_add(dvbpsi_nit_t * p_nit,uint8_t i_tag,uint8_t i_length,uint8_t * p_data)209 dvbpsi_descriptor_t* dvbpsi_nit_descriptor_add(dvbpsi_nit_t* p_nit,
210                                                uint8_t i_tag, uint8_t i_length,
211                                                uint8_t* p_data)
212 {
213     dvbpsi_descriptor_t* p_descriptor
214                         = dvbpsi_NewDescriptor(i_tag, i_length, p_data);
215     if (p_descriptor == NULL)
216         return NULL;
217 
218     if (p_nit->p_first_descriptor == NULL)
219         p_nit->p_first_descriptor = p_descriptor;
220     else
221     {
222         dvbpsi_descriptor_t* p_last_descriptor = p_nit->p_first_descriptor;
223         while(p_last_descriptor->p_next != NULL)
224             p_last_descriptor = p_last_descriptor->p_next;
225         p_last_descriptor->p_next = p_descriptor;
226     }
227     return p_descriptor;
228 }
229 
230 /*****************************************************************************
231  * dvbpsi_nit_ts_add
232  *****************************************************************************
233  * Add an TS in the NIT.
234  *****************************************************************************/
dvbpsi_nit_ts_add(dvbpsi_nit_t * p_nit,uint16_t i_ts_id,uint16_t i_orig_network_id)235 dvbpsi_nit_ts_t* dvbpsi_nit_ts_add(dvbpsi_nit_t* p_nit,
236                                    uint16_t i_ts_id, uint16_t i_orig_network_id)
237 {
238     dvbpsi_nit_ts_t* p_ts = (dvbpsi_nit_ts_t*)malloc(sizeof(dvbpsi_nit_ts_t));
239     if (p_ts == NULL)
240         return NULL;
241 
242     p_ts->i_ts_id = i_ts_id;
243     p_ts->i_orig_network_id = i_orig_network_id;
244     p_ts->p_first_descriptor = NULL;
245     p_ts->p_next = NULL;
246 
247     if (p_nit->p_first_ts == NULL)
248         p_nit->p_first_ts = p_ts;
249     else
250     {
251         dvbpsi_nit_ts_t* p_last_ts = p_nit->p_first_ts;
252         while(p_last_ts->p_next != NULL)
253             p_last_ts = p_last_ts->p_next;
254         p_last_ts->p_next = p_ts;
255     }
256     return p_ts;
257 }
258 
259 /*****************************************************************************
260  * dvbpsi_nit_ts_descriptor_add
261  *****************************************************************************
262  * Add a descriptor in the NIT TS.
263  *****************************************************************************/
dvbpsi_nit_ts_descriptor_add(dvbpsi_nit_ts_t * p_ts,uint8_t i_tag,uint8_t i_length,uint8_t * p_data)264 dvbpsi_descriptor_t* dvbpsi_nit_ts_descriptor_add(dvbpsi_nit_ts_t* p_ts,
265                                                   uint8_t i_tag, uint8_t i_length,
266                                                   uint8_t* p_data)
267 {
268     dvbpsi_descriptor_t* p_descriptor
269                         = dvbpsi_NewDescriptor(i_tag, i_length, p_data);
270     if (p_descriptor == NULL)
271         return NULL;
272 
273     p_ts->p_first_descriptor = dvbpsi_AddDescriptor(p_ts->p_first_descriptor,
274                                                     p_descriptor);
275     assert(p_ts->p_first_descriptor);
276     if (p_ts->p_first_descriptor == NULL)
277         return NULL;
278 
279     return p_descriptor;
280 }
281 
282 /* */
dvbpsi_ReInitNIT(dvbpsi_nit_decoder_t * p_decoder,const bool b_force)283 static void dvbpsi_ReInitNIT(dvbpsi_nit_decoder_t* p_decoder, const bool b_force)
284 {
285     assert(p_decoder);
286 
287     dvbpsi_decoder_reset(DVBPSI_DECODER(p_decoder), b_force);
288 
289     /* Force redecoding */
290     if (b_force)
291     {
292         /* Free structures */
293         if (p_decoder->p_building_nit)
294             dvbpsi_nit_delete(p_decoder->p_building_nit);
295     }
296     p_decoder->p_building_nit = NULL;
297 }
298 
dvbpsi_CheckNIT(dvbpsi_t * p_dvbpsi,dvbpsi_nit_decoder_t * p_nit_decoder,dvbpsi_psi_section_t * p_section)299 static bool dvbpsi_CheckNIT(dvbpsi_t *p_dvbpsi, dvbpsi_nit_decoder_t *p_nit_decoder,
300                             dvbpsi_psi_section_t *p_section)
301 {
302     assert(p_dvbpsi);
303     assert(p_nit_decoder);
304 
305     bool b_reinit = false;
306 
307     if (p_nit_decoder->p_building_nit->i_version != p_section->i_version)
308     {
309         /* version_number */
310         dvbpsi_error(p_dvbpsi, "NIT decoder",
311                 "'version_number' differs"
312                 " whereas no discontinuity has occured");
313         b_reinit = true;
314     }
315     else if (p_nit_decoder->i_last_section_number
316                                     != p_section->i_last_number)
317     {
318         /* last_section_number */
319         dvbpsi_error(p_dvbpsi, "NIT decoder",
320                 "'last_section_number' differs"
321                 " whereas no discontinuity has occured");
322         b_reinit = true;
323     }
324 
325     return b_reinit;
326 }
327 
dvbpsi_AddSectionNIT(dvbpsi_t * p_dvbpsi,dvbpsi_nit_decoder_t * p_nit_decoder,dvbpsi_psi_section_t * p_section)328 static bool dvbpsi_AddSectionNIT(dvbpsi_t *p_dvbpsi, dvbpsi_nit_decoder_t *p_nit_decoder,
329                                  dvbpsi_psi_section_t* p_section)
330 {
331     assert(p_dvbpsi);
332     assert(p_nit_decoder);
333     assert(p_section);
334 
335     /* Initialize the structures if it's the first section received */
336     if (p_nit_decoder->p_building_nit == NULL)
337     {
338         p_nit_decoder->p_building_nit = dvbpsi_nit_new(p_section->i_table_id,
339                 p_section->i_extension, p_nit_decoder->i_network_id,
340                 p_section->i_version, p_section->b_current_next);
341         if (p_nit_decoder->p_building_nit == NULL)
342             return false;
343         p_nit_decoder->i_last_section_number = p_section->i_last_number;
344     }
345 
346     /* Add to linked list of sections */
347     if (dvbpsi_decoder_psi_section_add(DVBPSI_DECODER(p_nit_decoder), p_section))
348         dvbpsi_debug(p_dvbpsi, "NIT decoder", "overwrite section number %d",
349                                p_section->i_number);
350 
351     return true;
352 }
353 
354 /*****************************************************************************
355  * dvbpsi_nit_sections_gather
356  *****************************************************************************
357  * Callback for the PSI decoder.
358  *****************************************************************************/
dvbpsi_nit_sections_gather(dvbpsi_t * p_dvbpsi,dvbpsi_decoder_t * p_private_decoder,dvbpsi_psi_section_t * p_section)359 void dvbpsi_nit_sections_gather(dvbpsi_t *p_dvbpsi,
360                                 dvbpsi_decoder_t *p_private_decoder,
361                                 dvbpsi_psi_section_t *p_section)
362 {
363     assert(p_dvbpsi);
364 
365     const uint8_t i_table_id = ((p_section->i_table_id == 0x40) ||
366                                 (p_section->i_table_id == 0x41)) ?
367                                     p_section->i_table_id : 0x40;
368 
369     if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, i_table_id, "NIT decoder"))
370     {
371         dvbpsi_DeletePSISections(p_section);
372         return;
373     }
374 
375     /* */
376     dvbpsi_nit_decoder_t* p_nit_decoder
377                         = (dvbpsi_nit_decoder_t*)p_private_decoder;
378 
379     /* We have a valid NIT section */
380     if (p_nit_decoder->i_network_id != p_section->i_extension)
381     {
382         /* Invalid program_number */
383         dvbpsi_error(p_dvbpsi, "NIT decoder", "'network_id' don't match");
384         dvbpsi_DeletePSISections(p_section);
385         return;
386     }
387 
388     /* TS discontinuity check */
389     if (p_nit_decoder->b_discontinuity)
390     {
391         dvbpsi_ReInitNIT(p_nit_decoder, true);
392         p_nit_decoder->b_discontinuity = false;
393     }
394     else
395     {
396         /* Perform some few sanity checks */
397         if (p_nit_decoder->p_building_nit)
398         {
399             if (dvbpsi_CheckNIT(p_dvbpsi, p_nit_decoder, p_section))
400                 dvbpsi_ReInitNIT(p_nit_decoder, true);
401         }
402         else
403         {
404             if (   (p_nit_decoder->b_current_valid)
405                 && (p_nit_decoder->current_nit.i_version == p_section->i_version)
406                 && (p_nit_decoder->current_nit.b_current_next == p_section->b_current_next))
407             {
408                 /* Don't decode since this version is already decoded */
409                 dvbpsi_debug(p_dvbpsi, "NIT decoder",
410                              "ignoring already decoded section %d",
411                              p_section->i_number);
412                 dvbpsi_DeletePSISections(p_section);
413                 return;;
414             }
415         }
416     }
417 
418     /* Add section to NIT */
419     if (!dvbpsi_AddSectionNIT(p_dvbpsi, p_nit_decoder, p_section))
420     {
421         dvbpsi_error(p_dvbpsi, "NIT decoder", "failed decoding section %d",
422                      p_section->i_number);
423         dvbpsi_DeletePSISections(p_section);
424         return;
425     }
426 
427     /* Check if we have all the sections */
428     if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_nit_decoder)))
429     {
430         assert(p_nit_decoder->pf_nit_callback);
431 
432         /* Save the current information */
433         p_nit_decoder->current_nit = *p_nit_decoder->p_building_nit;
434         p_nit_decoder->b_current_valid = true;
435 
436         /* Decode the sections */
437         dvbpsi_nit_sections_decode(p_nit_decoder->p_building_nit,
438                                    p_nit_decoder->p_sections);
439         /* signal the new NIT */
440         p_nit_decoder->pf_nit_callback(p_nit_decoder->p_cb_data,
441                                        p_nit_decoder->p_building_nit);
442         /* Delete sections and Reinitialize the structures */
443         dvbpsi_ReInitNIT(p_nit_decoder, false);
444         assert(p_nit_decoder->p_sections == NULL);
445     }
446 }
447 
448 /*****************************************************************************
449  * dvbpsi_nit_sections_decode
450  *****************************************************************************
451  * NIT decoder.
452  *****************************************************************************/
dvbpsi_nit_sections_decode(dvbpsi_nit_t * p_nit,dvbpsi_psi_section_t * p_section)453 void dvbpsi_nit_sections_decode(dvbpsi_nit_t* p_nit,
454                                 dvbpsi_psi_section_t* p_section)
455 {
456     uint8_t* p_byte, * p_end;
457 
458     while (p_section)
459     {
460         /* - NIT descriptors */
461         p_byte = p_section->p_payload_start + 2;
462         p_end = p_byte + (((uint16_t)(p_section->p_payload_start[0] & 0x0f) << 8)
463                           | p_section->p_payload_start[1]);
464 
465         while (p_byte + 2 <= p_end)
466         {
467             uint8_t i_tag = p_byte[0];
468             uint8_t i_length = p_byte[1];
469             if (i_length + 2 <= p_end - p_byte)
470                 dvbpsi_nit_descriptor_add(p_nit, i_tag, i_length, p_byte + 2);
471             p_byte += 2 + i_length;
472         }
473 
474         /* Transport stream loop length */
475         p_end = 2 + p_byte + (((uint16_t)(p_byte[0] & 0x0f) << 8) | p_byte[1]);
476         if (p_end > p_section->p_payload_end)
477             p_end = p_section->p_payload_end;
478 
479         p_byte += 2;
480 
481         /* - TSs */
482         while(p_byte + 6 <= p_end)
483         {
484             uint8_t *p_end2; /* descriptor loop end */
485 
486             uint16_t i_ts_id = ((uint16_t)p_byte[0] << 8) | p_byte[1];
487             uint16_t i_orig_network_id = ((uint16_t)p_byte[2] << 8) | p_byte[3];
488             uint16_t i_ts_length = ((uint16_t)(p_byte[4] & 0x0f) << 8) | p_byte[5];
489 
490             dvbpsi_nit_ts_t* p_ts = dvbpsi_nit_ts_add(p_nit, i_ts_id, i_orig_network_id);
491             if (!p_ts)
492                 break;
493 
494             /* - TS descriptors */
495             p_byte += 6;
496             p_end2 = p_byte + i_ts_length;
497             if (p_end2 > p_section->p_payload_end)
498                 p_end2 = p_section->p_payload_end;
499 
500             while (p_byte + 2 <= p_end2)
501             {
502                 uint8_t i_tag = p_byte[0];
503                 uint8_t i_length = p_byte[1];
504                 if (i_length + 2 <= p_end2 - p_byte)
505                     dvbpsi_nit_ts_descriptor_add(p_ts, i_tag, i_length, p_byte + 2);
506                 p_byte += 2 + i_length;
507             }
508         }
509         p_section = p_section->p_next;
510     }
511 }
512 
513 /*****************************************************************************
514  * dvbpsi_nit_sections_generate
515  *****************************************************************************
516  * Generate NIT sections based on the dvbpsi_nit_t structure.
517  *****************************************************************************/
dvbpsi_nit_sections_generate(dvbpsi_t * p_dvbpsi,dvbpsi_nit_t * p_nit,uint8_t i_table_id)518 dvbpsi_psi_section_t* dvbpsi_nit_sections_generate(dvbpsi_t *p_dvbpsi,
519                                             dvbpsi_nit_t* p_nit, uint8_t i_table_id)
520 {
521     dvbpsi_psi_section_t* p_result = dvbpsi_NewPSISection(1024);
522     dvbpsi_psi_section_t* p_current = p_result;
523     dvbpsi_psi_section_t* p_prev;
524     dvbpsi_descriptor_t* p_descriptor = p_nit->p_first_descriptor;
525     dvbpsi_nit_ts_t* p_ts = p_nit->p_first_ts;
526     uint16_t i_network_descriptors_length, i_transport_stream_loop_length;
527     uint8_t * p_transport_stream_loop_length;
528 
529     p_current->i_table_id = i_table_id;
530     p_current->b_syntax_indicator = true;
531     p_current->b_private_indicator = false;
532     p_current->i_length = 13;                     /* including CRC_32 */
533     p_current->i_extension = p_nit->i_network_id;
534     p_current->i_version = p_nit->i_version;
535     p_current->b_current_next = p_nit->b_current_next;
536     p_current->i_number = 0;
537     p_current->p_payload_end += 10;
538     p_current->p_payload_start = p_current->p_data + 8;
539 
540     /* NIT descriptors */
541     while (p_descriptor != NULL)
542     {
543         /* New section if needed */
544         /* written_data_length + descriptor_length + 2 > 1024 - CRC_32_length */
545         if ((p_current->p_payload_end - p_current->p_data)
546                                 + p_descriptor->i_length > 1018)
547         {
548             /* network_descriptors_length */
549             i_network_descriptors_length = (p_current->p_payload_end - p_current->p_payload_start) - 2;
550             p_current->p_data[8] = (i_network_descriptors_length >> 8) | 0xf0;
551             p_current->p_data[9] = i_network_descriptors_length;
552 
553             /* transport_stream_loop_length */
554             p_current->p_payload_end[0] = 0;
555             p_current->p_payload_end[1] = 0;
556             p_current->p_payload_end += 2;
557 
558             p_prev = p_current;
559             p_current = dvbpsi_NewPSISection(1024);
560             p_prev->p_next = p_current;
561 
562             p_current->i_table_id = i_table_id;
563             p_current->b_syntax_indicator = true;
564             p_current->b_private_indicator = false;
565             p_current->i_length = 13;                 /* including CRC_32 */
566             p_current->i_extension = p_nit->i_network_id;
567             p_current->i_version = p_nit->i_version;
568             p_current->b_current_next = p_nit->b_current_next;
569             p_current->i_number = p_prev->i_number + 1;
570             p_current->p_payload_end += 10;
571             p_current->p_payload_start = p_current->p_data + 8;
572         }
573 
574         /* p_payload_end is where the descriptor begins */
575         p_current->p_payload_end[0] = p_descriptor->i_tag;
576         p_current->p_payload_end[1] = p_descriptor->i_length;
577         memcpy(p_current->p_payload_end + 2,
578                p_descriptor->p_data,
579                p_descriptor->i_length);
580 
581         /* Increase length by descriptor_length + 2 */
582         p_current->p_payload_end += p_descriptor->i_length + 2;
583         p_current->i_length += p_descriptor->i_length + 2;
584 
585         p_descriptor = p_descriptor->p_next;
586     }
587 
588     /* network_descriptors_length */
589     i_network_descriptors_length = (p_current->p_payload_end - p_current->p_payload_start) - 2;
590     p_current->p_data[8] = (i_network_descriptors_length >> 8) | 0xf0;
591     p_current->p_data[9] = i_network_descriptors_length;
592 
593     /* Store the position of the transport_stream_loop_length field
594        and reserve two bytes for it */
595     p_transport_stream_loop_length = p_current->p_payload_end;
596     p_current->p_payload_end += 2;
597 
598     /* NIT TSs */
599     while (p_ts != NULL)
600     {
601         uint8_t* p_ts_start = p_current->p_payload_end;
602         uint16_t i_ts_length = 5;
603 
604         /* Can the current section carry all the descriptors ? */
605         p_descriptor = p_ts->p_first_descriptor;
606         while(    (p_descriptor != NULL)
607                && ((p_ts_start - p_current->p_data) + i_ts_length <= 1020))
608         {
609             i_ts_length += p_descriptor->i_length + 2;
610             p_descriptor = p_descriptor->p_next;
611         }
612 
613         /* If _no_ and the current section isn't empty and an empty section
614            may carry one more descriptor
615            then create a new section */
616         if(    (p_descriptor != NULL)
617             && (p_ts_start - p_current->p_data != 12)
618             && (i_ts_length <= 1008))
619         {
620             /* transport_stream_loop_length */
621             i_transport_stream_loop_length = (p_current->p_payload_end - p_transport_stream_loop_length) - 2;
622             p_transport_stream_loop_length[0] = (i_transport_stream_loop_length >> 8) | 0xf0;
623             p_transport_stream_loop_length[1] = i_transport_stream_loop_length;
624 
625             /* will put more descriptors in an empty section */
626             dvbpsi_debug(p_dvbpsi, "NIT generator",
627                                    "create a new section to carry more TS descriptors");
628 
629             p_prev = p_current;
630             p_current = dvbpsi_NewPSISection(1024);
631             p_prev->p_next = p_current;
632 
633             p_current->i_table_id = i_table_id;
634             p_current->b_syntax_indicator = true;
635             p_current->b_private_indicator = false;
636             p_current->i_length = 13;                 /* including CRC_32 */
637             p_current->i_extension = p_nit->i_network_id;
638             p_current->i_version = p_nit->i_version;
639             p_current->b_current_next = p_nit->b_current_next;
640             p_current->i_number = p_prev->i_number + 1;
641             p_current->p_payload_end += 10;
642             p_current->p_payload_start = p_current->p_data + 8;
643 
644             /* network_descriptors_length = 0 */
645             p_current->p_data[8] = 0xf0;
646             p_current->p_data[9] = 0x00;
647 
648             /* Store the position of the transport_stream_loop_length field
649                and reserve two bytes for it */
650             p_transport_stream_loop_length = p_current->p_payload_end;
651             p_current->p_payload_end += 2;
652 
653             p_ts_start = p_current->p_payload_end;
654         }
655 
656         /* p_ts_start is where the TS begins */
657         p_ts_start[0] = p_ts->i_ts_id >> 8;
658         p_ts_start[1] = p_ts->i_ts_id & 0xff;
659         p_ts_start[2] = p_ts->i_orig_network_id >> 8;
660         p_ts_start[3] = p_ts->i_orig_network_id & 0xff;
661 
662         /* Increase the length by 6 */
663         p_current->p_payload_end += 6;
664         p_current->i_length += 6;
665 
666         /* TS descriptors */
667         p_descriptor = p_ts->p_first_descriptor;
668         while (   (p_descriptor != NULL)
669            && (   (p_current->p_payload_end - p_current->p_data)
670                 + p_descriptor->i_length <= 1018))
671         {
672             /* p_payload_end is where the descriptor begins */
673             p_current->p_payload_end[0] = p_descriptor->i_tag;
674             p_current->p_payload_end[1] = p_descriptor->i_length;
675             memcpy(p_current->p_payload_end + 2,
676                     p_descriptor->p_data,
677                     p_descriptor->i_length);
678 
679             /* Increase length by descriptor_length + 2 */
680             p_current->p_payload_end += p_descriptor->i_length + 2;
681             p_current->i_length += p_descriptor->i_length + 2;
682 
683             p_descriptor = p_descriptor->p_next;
684         }
685 
686         if (p_descriptor != NULL)
687             dvbpsi_error(p_dvbpsi, "NIT generator", "unable to carry all the TS descriptors");
688 
689         /* TS_info_length */
690         i_ts_length = p_current->p_payload_end - p_ts_start - 6;
691         p_ts_start[4] = (i_ts_length >> 8) | 0xf0;
692         p_ts_start[5] = i_ts_length;
693 
694         p_ts = p_ts->p_next;
695     }
696 
697     /* transport_stream_loop_length */
698     i_transport_stream_loop_length = (p_current->p_payload_end - p_transport_stream_loop_length) - 2;
699     p_transport_stream_loop_length[0] = (i_transport_stream_loop_length >> 8) | 0xf0;
700     p_transport_stream_loop_length[1] = i_transport_stream_loop_length;
701 
702     /* Finalization */
703     p_prev = p_result;
704     while (p_prev != NULL)
705     {
706         p_prev->i_last_number = p_current->i_number;
707         dvbpsi_BuildPSISection(p_dvbpsi, p_prev);
708         p_prev = p_prev->p_next;
709     }
710 
711     return p_result;
712 }
713