@@ -26,7 +26,6 @@
#include <time.h>
#include <libdvbv5/atsc_header.h>
-#include <libdvbv5/descriptors.h>
#define ATSC_TABLE_EIT 0xCB
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2011-2012 - Mauro Carvalho Chehab
+ * Copyright (c) 2012-2014 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -27,7 +27,6 @@
#include <time.h>
#include <libdvbv5/header.h>
-#include <libdvbv5/descriptors.h>
#define DVB_TABLE_EIT 0x4E
#define DVB_TABLE_EIT_OTHER 0x4F
@@ -47,7 +46,7 @@ struct dvb_table_eit_event {
union {
uint16_t bitfield2;
struct {
- uint16_t section_length:12;
+ uint16_t desc_length:12;
uint16_t free_CA_mode:1;
uint16_t running_status:3;
} __attribute__((packed));
@@ -25,7 +25,6 @@
#include <unistd.h> /* ssize_t */
#include <libdvbv5/atsc_header.h>
-#include <libdvbv5/descriptors.h>
#define ATSC_TABLE_MGT 0xC7
@@ -46,7 +46,7 @@ struct dvb_table_nit_transport {
union {
uint16_t bitfield;
struct {
- uint16_t section_length:12;
+ uint16_t desc_length:12;
uint16_t reserved:4;
} __attribute__((packed));
} __attribute__((packed));
@@ -27,8 +27,8 @@
#include <libdvbv5/header.h>
-#define DVB_TABLE_PAT 0
-#define DVB_TABLE_PAT_PID 0
+#define DVB_TABLE_PAT 0x00
+#define DVB_TABLE_PAT_PID 0x0000
struct dvb_table_pat_program {
uint16_t service_id;
@@ -26,11 +26,10 @@
#include <unistd.h> /* ssize_t */
#include <libdvbv5/header.h>
-#include <libdvbv5/descriptors.h>
#define DVB_TABLE_SDT 0x42
#define DVB_TABLE_SDT2 0x46
-#define DVB_TABLE_SDT_PID 0x11
+#define DVB_TABLE_SDT_PID 0x0011
struct dvb_table_sdt_service {
uint16_t service_id;
@@ -40,7 +39,7 @@ struct dvb_table_sdt_service {
union {
uint16_t bitfield;
struct {
- uint16_t section_length:12;
+ uint16_t desc_length:12;
uint16_t free_CA_mode:1;
uint16_t running_status:3;
} __attribute__((packed));
@@ -26,7 +26,6 @@
#include <unistd.h> /* ssize_t */
#include <libdvbv5/atsc_header.h>
-#include <libdvbv5/descriptors.h>
#define ATSC_TABLE_TVCT 0xc8
#define ATSC_TABLE_CVCT 0xc9
@@ -112,11 +112,16 @@ int dvb_parse_descriptors(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
uint8_t desc_len = ptr[1];
size_t size;
+ if (desc_type == 0xff ) {
+ dvb_logwarn("%s: stopping at invalid descriptor 0xff", __func__);
+ return 0;
+ }
+
ptr += 2; /* skip type and length */
if (ptr + desc_len > endbuf) {
- dvb_logerr("short read of %zd/%d bytes parsing descriptor %#02x",
- endbuf - ptr, desc_len, desc_type);
+ dvb_logerr("%s: short read of %zd/%d bytes parsing descriptor %#02x",
+ __func__, endbuf - ptr, desc_len, desc_type);
return -1;
}
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 - Andre Roth <neolynx@gmail.com>
+ * Copyright (c) 2013-2014 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -19,6 +19,7 @@
*/
#include <libdvbv5/atsc_eit.h>
+#include <libdvbv5/descriptors.h>
#include <libdvbv5/dvb-fe.h>
ssize_t atsc_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
@@ -26,16 +27,22 @@ ssize_t atsc_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
{
const uint8_t *p = buf, *endbuf = buf + buflen - 4; /* minus CRC */;
struct atsc_table_eit_event **head;
+ size_t size;
int i = 0;
- struct atsc_table_eit_event *last = NULL;
- size_t size = offsetof(struct atsc_table_eit, event);
+ size = offsetof(struct atsc_table_eit, event);
if (p + size > endbuf) {
dvb_logerr("%s: short read %zd/%zd bytes", __func__,
- size, endbuf - p);
+ endbuf - p, size);
return -1;
}
+ if (buf[0] != ATSC_TABLE_EIT) {
+ dvb_logerr("%s: invalid marker 0x%02x, sould be 0x%02x",
+ __func__, buf[0], ATSC_TABLE_EIT);
+ return -2;
+ }
+
if (*table_length > 0) {
memcpy(eit, p, size);
@@ -45,7 +52,6 @@ ssize_t atsc_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
head = &(*head)->next;
} else {
memcpy(eit, p, size);
- *table_length = sizeof(struct atsc_table_eit);
eit->event = NULL;
head = &eit->event;
@@ -59,10 +65,14 @@ ssize_t atsc_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
size = offsetof(struct atsc_table_eit_event, descriptor);
if (p + size > endbuf) {
dvb_logerr("%s: short read %zd/%zd bytes", __func__,
- size, endbuf - p);
+ endbuf - p, size);
return -2;
}
event = (struct atsc_table_eit_event *) malloc(sizeof(struct atsc_table_eit_event));
+ if (!event) {
+ dvb_logerr("%s: out of memory", __func__);
+ return -3;
+ }
memcpy(event, p, size);
p += size;
@@ -74,15 +84,13 @@ ssize_t atsc_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
atsc_time(event->start_time, &event->start);
event->source_id = eit->header.id;
- if(!*head)
- *head = event;
- if(last)
- last->next = event;
+ *head = event;
+ head = &(*head)->next;
size = event->title_length - 1;
if (p + size > endbuf) {
dvb_logerr("%s: short read %zd/%zd bytes", __func__,
- size, endbuf - p);
+ endbuf - p, size);
return -3;
}
/* TODO: parse title */
@@ -92,7 +100,7 @@ ssize_t atsc_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
size = sizeof(union atsc_table_eit_desc_length);
if (p + size > endbuf) {
dvb_logerr("%s: short read %zd/%zd bytes", __func__,
- size, endbuf - p);
+ endbuf - p, size);
return -4;
}
memcpy(&dl, p, size);
@@ -102,13 +110,12 @@ ssize_t atsc_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
size = dl.desc_length;
if (p + size > endbuf) {
dvb_logerr("%s: short read %zd/%zd bytes", __func__,
- size, endbuf - p);
+ endbuf - p, size);
return -5;
}
dvb_parse_descriptors(parms, p, size, &event->descriptor);
p += size;
- last = event;
}
*table_length = p - buf;
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 - Andre Roth <neolynx@gmail.com>
+ * Copyright (c) 2013-2014 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,37 +23,58 @@
#include <libdvbv5/dvb-fe.h>
ssize_t dvb_table_cat_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
- ssize_t buflen, struct dvb_table_cat *cat, ssize_t *table_length)
+ ssize_t buflen, struct dvb_table_cat *cat, ssize_t *table_length)
{
- struct dvb_desc **head_desc = &cat->descriptor;
const uint8_t *p = buf, *endbuf = buf + buflen - 4;
+ struct dvb_desc **head_desc;
size_t size;
- if (buf[0] != DVB_TABLE_CAT) {
- dvb_logerr("%s: invalid marker 0x%02x, sould be 0x%02x", __func__, buf[0], DVB_TABLE_CAT);
- *table_length = 0;
+ size = offsetof(struct dvb_table_cat, descriptor);
+ if (p + size > endbuf) {
+ dvb_logerr("%s: short read %zd/%zd bytes", __func__,
+ endbuf - p, size);
return -1;
}
+ if (buf[0] != DVB_TABLE_CAT) {
+ dvb_logerr("%s: invalid marker 0x%02x, sould be 0x%02x",
+ __func__, buf[0], DVB_TABLE_CAT);
+ return -2;
+ }
+
if (*table_length > 0) {
/* find end of current lists */
+ head_desc = &cat->descriptor;
while (*head_desc != NULL)
head_desc = &(*head_desc)->next;
- }
-
- size = offsetof(struct dvb_table_cat, descriptor);
- if (p + size > endbuf) {
- dvb_logerr("CAT table was truncated while filling dvb_table_cat. Need %zu bytes, but has only %zu.",
- size, buflen);
- return -2;
+ } else {
+ head_desc = &cat->descriptor;
}
memcpy(cat, p, size);
p += size;
- *table_length = sizeof(struct dvb_table_cat);
- size = endbuf - p;
- dvb_parse_descriptors(parms, p, size, head_desc);
+ size = cat->header.section_length + 3 - 4; /* plus header, minus CRC */
+ if (buf + size > endbuf) {
+ dvb_logerr("%s: short read %zd/%zd bytes", __func__,
+ endbuf - buf, size);
+ return -3;
+ }
+ endbuf = buf + size;
+
+ /* parse the descriptors */
+ if (endbuf > p) {
+ uint16_t desc_length = endbuf - p;
+ if (dvb_parse_descriptors(parms, p, desc_length,
+ head_desc) != 0) {
+ return -4;
+ }
+ p += desc_length;
+ }
+
+ if (endbuf - p)
+ dvb_logwarn("%s: %zu spurious bytes at the end",
+ __func__, endbuf - p);
*table_length = p - buf;
return p - buf;
@@ -1,6 +1,5 @@
/*
- * Copyright (c) 2011-2012 - Mauro Carvalho Chehab
- * Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
+ * Copyright (c) 2012-2014 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -20,12 +19,32 @@
*/
#include <libdvbv5/eit.h>
+#include <libdvbv5/descriptors.h>
#include <libdvbv5/dvb-fe.h>
-ssize_t dvb_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize_t buflen, struct dvb_table_eit *eit, ssize_t *table_length)
+ssize_t dvb_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
+ ssize_t buflen, struct dvb_table_eit *eit, ssize_t *table_length)
{
- const uint8_t *p = buf;
+ const uint8_t *p = buf, *endbuf = buf + buflen - 4; /* minus CRC */
struct dvb_table_eit_event **head;
+ size_t size;
+
+ size = offsetof(struct dvb_table_eit, event);
+ if (p + size > endbuf) {
+ dvb_logerr("%s: short read %zd/%zd bytes", __func__,
+ endbuf - p, size);
+ return -1;
+ }
+
+ if ((buf[0] != DVB_TABLE_EIT && buf[0] != DVB_TABLE_EIT_OTHER) &&
+ !(buf[0] >= DVB_TABLE_EIT_SCHEDULE && buf[0] <= DVB_TABLE_EIT_SCHEDULE + 0xF) &&
+ !(buf[0] >= DVB_TABLE_EIT_SCHEDULE_OTHER && buf[0] <= DVB_TABLE_EIT_SCHEDULE_OTHER + 0xF)) {
+ dvb_logerr("%s: invalid marker 0x%02x, sould be 0x%02x, 0x%02x or between 0x%02x and 0x%02x or 0x%02x and 0x%02x",
+ __func__, buf[0], DVB_TABLE_EIT, DVB_TABLE_EIT_OTHER,
+ DVB_TABLE_EIT_SCHEDULE, DVB_TABLE_EIT_SCHEDULE + 0xF,
+ DVB_TABLE_EIT_SCHEDULE_OTHER, DVB_TABLE_EIT_SCHEDULE_OTHER + 0xF);
+ return -2;
+ }
if (*table_length > 0) {
memcpy(eit, p, sizeof(struct dvb_table_eit) - sizeof(eit->event));
@@ -39,7 +58,6 @@ ssize_t dvb_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ss
head = &(*head)->next;
} else {
memcpy(eit, p, sizeof(struct dvb_table_eit) - sizeof(eit->event));
- *table_length = sizeof(struct dvb_table_eit);
bswap16(eit->transport_id);
bswap16(eit->network_id);
@@ -47,23 +65,20 @@ ssize_t dvb_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ss
eit->event = NULL;
head = &eit->event;
}
- p += sizeof(struct dvb_table_eit) - sizeof(eit->event);
-
- struct dvb_table_eit_event *last = NULL;
- while ((uint8_t *) p < buf + buflen - 4) {
- struct dvb_table_eit_event *event = (struct dvb_table_eit_event *) malloc(sizeof(struct dvb_table_eit_event));
- memcpy(event, p, sizeof(struct dvb_table_eit_event) -
- sizeof(event->descriptor) -
- sizeof(event->next) -
- sizeof(event->start) -
- sizeof(event->duration) -
- sizeof(event->service_id));
- p += sizeof(struct dvb_table_eit_event) -
- sizeof(event->descriptor) -
- sizeof(event->next) -
- sizeof(event->start) -
- sizeof(event->duration) -
- sizeof(event->service_id);
+ p += size;
+
+ /* get the event entries */
+ size = offsetof(struct dvb_table_eit_event, descriptor);
+ while (p + size <= endbuf) {
+ struct dvb_table_eit_event *event;
+
+ event = malloc(sizeof(struct dvb_table_eit_event));
+ if (!event) {
+ dvb_logerr("%s: out of memory", __func__);
+ return -3;
+ }
+ memcpy(event, p, size);
+ p += size;
bswap16(event->event_id);
bswap16(event->bitfield1);
@@ -77,18 +92,27 @@ ssize_t dvb_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ss
event->service_id = eit->header.id;
- if(!*head)
- *head = event;
- if(last)
- last->next = event;
-
- /* get the descriptors for each program */
- struct dvb_desc **head_desc = &event->descriptor;
- dvb_parse_descriptors(parms, p, event->section_length, head_desc);
-
- p += event->section_length;
- last = event;
+ *head = event;
+ head = &(*head)->next;
+
+ /* parse the descriptors */
+ if (event->desc_length > 0) {
+ uint16_t desc_length = event->desc_length;
+ if (p + desc_length > endbuf) {
+ dvb_logwarn("%s: decsriptors short read %zd/%d bytes", __func__,
+ endbuf - p, desc_length);
+ desc_length = endbuf - p;
+ }
+ if (dvb_parse_descriptors(parms, p, desc_length,
+ &event->descriptor) != 0) {
+ return -4;
+ }
+ p += desc_length;
+ }
}
+ if (p < endbuf)
+ dvb_logwarn("%s: %zu spurious bytes at the end",
+ __func__, endbuf - p);
*table_length = p - buf;
return p - buf;
}
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 - Andre Roth <neolynx@gmail.com>
+ * Copyright (c) 2013-2014 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -19,25 +19,36 @@
*/
#include <libdvbv5/mgt.h>
+#include <libdvbv5/descriptors.h>
#include <libdvbv5/dvb-fe.h>
ssize_t atsc_table_mgt_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
ssize_t buflen, struct atsc_table_mgt *mgt, ssize_t *table_length)
{
const uint8_t *p = buf, *endbuf = buf + buflen - 4; /* minus CRC */
- struct dvb_desc **head_desc;
struct atsc_table_mgt_table **head;
+ struct dvb_desc **head_desc;
+ size_t size;
int i = 0;
- struct atsc_table_mgt_table *last = NULL;
- size_t size = offsetof(struct atsc_table_mgt, table);
+ size = offsetof(struct atsc_table_mgt, table);
if (p + size > endbuf) {
dvb_logerr("%s: short read %zd/%zd bytes", __func__,
- size, endbuf - p);
+ endbuf - p, size);
return -1;
}
+ if (buf[0] != ATSC_TABLE_MGT) {
+ dvb_logerr("%s: invalid marker 0x%02x, sould be 0x%02x",
+ __func__, buf[0], ATSC_TABLE_MGT);
+ return -2;
+ }
+
if (*table_length > 0) {
+ memcpy(mgt, p, size);
+
+ bswap16(mgt->tables);
+
/* find end of curent lists */
head_desc = &mgt->descriptor;
while (*head_desc != NULL)
@@ -45,11 +56,8 @@ ssize_t atsc_table_mgt_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
head = &mgt->table;
while (*head != NULL)
head = &(*head)->next;
-
- /* FIXME: read current mgt->tables for loop below */
} else {
memcpy(mgt, p, size);
- *table_length = sizeof(struct atsc_table_mgt);
bswap16(mgt->tables);
@@ -66,10 +74,14 @@ ssize_t atsc_table_mgt_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
size = offsetof(struct atsc_table_mgt_table, descriptor);
if (p + size > endbuf) {
dvb_logerr("%s: short read %zd/%zd bytes", __func__,
- size, endbuf - p);
+ endbuf - p, size);
return -2;
}
table = (struct atsc_table_mgt_table *) malloc(sizeof(struct atsc_table_mgt_table));
+ if (!table) {
+ dvb_logerr("%s: out of memory", __func__);
+ return -3;
+ }
memcpy(table, p, size);
p += size;
@@ -80,22 +92,19 @@ ssize_t atsc_table_mgt_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
table->descriptor = NULL;
table->next = NULL;
- if(!*head)
- *head = table;
- if(last)
- last->next = table;
+ *head = table;
+ head = &(*head)->next;
/* get the descriptors for each table */
size = table->desc_length;
if (p + size > endbuf) {
dvb_logerr("%s: short read %zd/%zd bytes", __func__,
- size, endbuf - p);
+ endbuf - p, size);
return -3;
}
dvb_parse_descriptors(parms, p, size, &table->descriptor);
p += size;
- last = table;
}
/* TODO: parse MGT descriptors here into head_desc */
@@ -109,7 +118,7 @@ void atsc_table_mgt_free(struct atsc_table_mgt *mgt)
struct atsc_table_mgt_table *table = mgt->table;
dvb_free_descriptors((struct dvb_desc **) &mgt->descriptor);
- while(table) {
+ while (table) {
struct atsc_table_mgt_table *tmp = table;
dvb_free_descriptors((struct dvb_desc **) &table->descriptor);
@@ -127,7 +136,7 @@ void atsc_table_mgt_print(struct dvb_v5_fe_parms *parms, struct atsc_table_mgt *
dvb_log("MGT");
ATSC_TABLE_HEADER_PRINT(parms, mgt);
dvb_log("| tables %d", mgt->tables);
- while(table) {
+ while (table) {
dvb_log("|- type %04x %d", table->type, table->pid);
dvb_log("| one %d", table->one);
dvb_log("| one2 %d", table->one2);
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2011-2012 - Mauro Carvalho Chehab
- * Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
+ * Copyright (c) 2012-2014 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -26,50 +26,55 @@ ssize_t dvb_table_nit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
ssize_t buflen, struct dvb_table_nit *nit, ssize_t *table_length)
{
const uint8_t *p = buf, *endbuf = buf + buflen - 4;
- struct dvb_desc **head_desc = &nit->descriptor;
- struct dvb_table_nit_transport **head = &nit->transport;
+ struct dvb_table_nit_transport **head;
+ struct dvb_desc **head_desc;
size_t size;
+ size = offsetof(struct dvb_table_nit, descriptor);
+ if (p + size > endbuf) {
+ dvb_logerr("%s: short read %zd/%zd bytes", __func__,
+ endbuf - p, size);
+ return -1;
+ }
+
+ if (buf[0] != DVB_TABLE_NIT) {
+ dvb_logerr("%s: invalid marker 0x%02x, sould be 0x%02x",
+ __func__, buf[0], DVB_TABLE_NIT);
+ return -2;
+ }
+
if (*table_length > 0) {
struct dvb_table_nit *t;
/* find end of current lists */
+ head_desc = &nit->descriptor;
while (*head_desc != NULL)
head_desc = &(*head_desc)->next;
+ head = &nit->transport;
while (*head != NULL)
head = &(*head)->next;
- size = offsetof(struct dvb_table_nit, descriptor);
- if (p + size > endbuf) {
- dvb_logerr("NIT table (cont) was truncated");
- return -1;
- }
p += size;
t = (struct dvb_table_nit *)buf;
bswap16(t->bitfield);
size = t->desc_length;
} else {
- size = offsetof(struct dvb_table_nit, descriptor);
- if (p + size > endbuf) {
- dvb_logerr("NIT table was truncated while filling dvb_table_nit. Need %zu bytes, but has only %zu.",
- size, buflen);
- return -2;
- }
memcpy(nit, p, size);
p += size;
- *table_length = sizeof(struct dvb_table_nit);
+ head = &nit->transport;
nit->descriptor = NULL;
nit->transport = NULL;
bswap16(nit->bitfield);
size = nit->desc_length;
+ head_desc = &nit->descriptor;
}
if (p + size > endbuf) {
- dvb_logerr("NIT table was truncated while getting NIT descriptors. Need %zu bytes, but has only %zu.",
- size, endbuf - p);
+ dvb_logerr("%s: short read %zd/%zd bytes", __func__,
+ endbuf - p, size);
return -3;
}
dvb_parse_descriptors(parms, p, size, head_desc);
@@ -77,8 +82,8 @@ ssize_t dvb_table_nit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
size = sizeof(union dvb_table_nit_transport_header);
if (p + size > endbuf) {
- dvb_logerr("NIT table was truncated while getting NIT transports. Need %zu bytes, but has only %zu.",
- size, endbuf - p);
+ dvb_logerr("%s: short read %zd/%zd bytes", __func__,
+ endbuf - p, size);
return -4;
}
p += size;
@@ -89,7 +94,7 @@ ssize_t dvb_table_nit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
transport = malloc(sizeof(struct dvb_table_nit_transport));
if (!transport) {
- dvb_perror(__func__);
+ dvb_logerr("%s: out of memory", __func__);
return -5;
}
memcpy(transport, p, size);
@@ -104,20 +109,24 @@ ssize_t dvb_table_nit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
*head = transport;
head = &(*head)->next;
- /* get the descriptors for each transport */
- head_desc = &transport->descriptor;
-
- if (p + transport->section_length > endbuf) {
- dvb_logerr("NIT table was truncated while getting NIT transport descriptors. Need %u bytes, but has only %zu.",
- transport->section_length, endbuf - p);
- return -6;
+ /* parse the descriptors */
+ if (transport->desc_length > 0) {
+ uint16_t desc_length = transport->desc_length;
+ if (p + desc_length > endbuf) {
+ dvb_logwarn("%s: decsriptors short read %zd/%d bytes", __func__,
+ endbuf - p, desc_length);
+ desc_length = endbuf - p;
+ }
+ if (dvb_parse_descriptors(parms, p, desc_length,
+ &transport->descriptor) != 0) {
+ return -6;
+ }
+ p += desc_length;
}
- dvb_parse_descriptors(parms, p, transport->section_length, head_desc);
- p += transport->section_length;
}
if (endbuf - p)
- dvb_logerr("NIT table has %zu spurious bytes at the end.",
- endbuf - p);
+ dvb_logwarn("%s: %zu spurious bytes at the end",
+ __func__, endbuf - p);
*table_length = p - buf;
return p - buf;
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2011-2012 - Mauro Carvalho Chehab
- * Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
+ * Copyright (c) 2012-2014 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -26,64 +26,77 @@
ssize_t dvb_table_pat_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
ssize_t buflen, struct dvb_table_pat *pat, ssize_t *table_length)
{
- struct dvb_table_pat_program **head = &pat->program;
const uint8_t *p = buf, *endbuf = buf + buflen - 4;
+ struct dvb_table_pat_program **head;
size_t size;
+ size = offsetof(struct dvb_table_pat, programs);
+ if (p + size > endbuf) {
+ dvb_logerr("%s: short read %zd/%zd bytes", __func__,
+ endbuf - p, size);
+ return -1;
+ }
+
+ if (buf[0] != DVB_TABLE_PAT) {
+ dvb_logerr("%s: invalid marker 0x%02x, sould be 0x%02x",
+ __func__, buf[0], DVB_TABLE_PAT);
+ return -2;
+ }
+
if (*table_length > 0) {
/* find end of current list */
+ head = &pat->program;
while (*head != NULL)
head = &(*head)->next;
} else {
- size = offsetof(struct dvb_table_pat, programs);
- if (p + size > endbuf) {
- dvb_logerr("PAT table was truncated. Need %zu bytes, but has only %zu.",
- size, buflen);
- return -1;
- }
memcpy(pat, buf, size);
p += size;
pat->programs = 0;
pat->program = NULL;
+ head = &pat->program;
}
- *table_length = sizeof(struct dvb_table_pat_program);
size = offsetof(struct dvb_table_pat_program, next);
while (p + size <= endbuf) {
- struct dvb_table_pat_program *pgm;
+ struct dvb_table_pat_program *prog;
- pgm = malloc(sizeof(struct dvb_table_pat_program));
- if (!pgm) {
+ prog = malloc(sizeof(struct dvb_table_pat_program));
+ if (!prog) {
dvb_perror("Out of memory");
- return -2;
+ return -3;
}
- memcpy(pgm, p, size);
+ memcpy(prog, p, size);
p += size;
- bswap16(pgm->service_id);
- bswap16(pgm->bitfield);
+ bswap16(prog->service_id);
+
+ if (prog->pid == 0x1fff) { /* ignore null packets */
+ free(prog);
+ break;
+ }
+ bswap16(prog->bitfield);
pat->programs++;
- pgm->next = NULL;
+ prog->next = NULL;
- *head = pgm;
+ *head = prog;
head = &(*head)->next;
}
if (endbuf - p)
- dvb_logerr("PAT table has %zu spurious bytes at the end.",
- endbuf - p);
+ dvb_logwarn("%s: %zu spurious bytes at the end",
+ __func__, endbuf - p);
*table_length = p - buf;
return p - buf;
}
void dvb_table_pat_free(struct dvb_table_pat *pat)
{
- struct dvb_table_pat_program *pgm = pat->program;
+ struct dvb_table_pat_program *prog = pat->program;
- while (pgm) {
- struct dvb_table_pat_program *tmp = pgm;
- pgm = pgm->next;
+ while (prog) {
+ struct dvb_table_pat_program *tmp = prog;
+ prog = prog->next;
free(tmp);
}
free(pat);
@@ -91,15 +104,15 @@ void dvb_table_pat_free(struct dvb_table_pat *pat)
void dvb_table_pat_print(struct dvb_v5_fe_parms *parms, struct dvb_table_pat *pat)
{
- struct dvb_table_pat_program *pgm = pat->program;
+ struct dvb_table_pat_program *prog = pat->program;
- dvb_log("PAT");
+ dvb_loginfo("PAT");
dvb_table_header_print(parms, &pat->header);
- dvb_log("|\\ %d program%s", pat->programs, pat->programs != 1 ? "s" : "");
+ dvb_loginfo("|\\ %d program pid%s", pat->programs, pat->programs != 1 ? "s" : "");
- while (pgm) {
- dvb_log("|- program 0x%04x -> service 0x%04x", pgm->pid, pgm->service_id);
- pgm = pgm->next;
+ while (prog) {
+ dvb_loginfo("| pid 0x%04x: service 0x%04x", prog->pid, prog->service_id);
+ prog = prog->next;
}
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2011-2012 - Mauro Carvalho Chehab
- * Copyright (c) 2012-2013 - Andre Roth <neolynx@gmail.com>
+ * Copyright (c) 2012-2014 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -29,46 +29,69 @@ ssize_t dvb_table_pmt_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
ssize_t buflen, struct dvb_table_pmt *pmt, ssize_t *table_length)
{
const uint8_t *p = buf, *endbuf = buf + buflen - 4;
- struct dvb_table_pmt_stream **head = &pmt->stream;
+ struct dvb_table_pmt_stream **head;
+ struct dvb_desc **head_desc;
size_t size;
- if (buf[0] != DVB_TABLE_PMT) {
- dvb_logerr("%s: invalid marker 0x%02x, sould be 0x%02x", __func__, buf[0], DVB_TABLE_PMT);
- *table_length = 0;
+ size = offsetof(struct dvb_table_pmt, dvb_pmt_field_last);
+ if (p + size > endbuf) {
+ dvb_logerr("%s: short read %zd/%zd bytes", __func__,
+ endbuf - p, size);
return -1;
}
+ if (buf[0] != DVB_TABLE_PMT) {
+ dvb_logerr("%s: invalid marker 0x%02x, sould be 0x%02x",
+ __func__, buf[0], DVB_TABLE_PMT);
+ return -2;
+ }
+
if (*table_length > 0) {
+ memcpy(pmt, p, size);
+ bswap16(pmt->bitfield);
+ bswap16(pmt->bitfield2);
+
/* find end of current list */
+ head = &pmt->stream;
while (*head != NULL)
head = &(*head)->next;
+ head_desc = &pmt->descriptor;
+ while (*head_desc != NULL)
+ head_desc = &(*head_desc)->next;
} else {
- size = offsetof(struct dvb_table_pmt, dvb_pmt_field_last);
- if (p + size > endbuf) {
- dvb_logerr("%s: short read %zd/%zd bytes", __func__,
- size, endbuf - p);
- return -2;
- }
memcpy(pmt, p, size);
- p += size;
-
bswap16(pmt->bitfield);
bswap16(pmt->bitfield2);
+
pmt->descriptor = NULL;
pmt->stream = NULL;
- /* parse the descriptors */
- if (pmt->desc_length > 0 ) {
- size = pmt->desc_length;
- if (p + size > endbuf) {
- dvb_logwarn("%s: decsriptors short read %zd/%zd bytes", __func__,
- size, endbuf - p);
- size = endbuf - p;
- }
- dvb_parse_descriptors(parms, p, size,
- &pmt->descriptor);
- p += size;
+ head = &pmt->stream;
+ head_desc = &pmt->descriptor;
+ }
+ p += size;
+
+ size = pmt->header.section_length + 3 - 4; /* plus header, minus CRC */
+ if (buf + size > endbuf) {
+ dvb_logerr("%s: short read %zd/%zd bytes", __func__,
+ endbuf - buf, size);
+ return -3;
+ }
+ endbuf = buf + size;
+
+ /* parse the descriptors */
+ if (pmt->desc_length > 0 ) {
+ uint16_t desc_length = pmt->desc_length;
+ if (p + desc_length > endbuf) {
+ dvb_logwarn("%s: decsriptors short read %d/%zd bytes", __func__,
+ desc_length, endbuf - p);
+ desc_length = endbuf - p;
}
+ if (dvb_parse_descriptors(parms, p, desc_length,
+ head_desc) != 0) {
+ return -3;
+ }
+ p += desc_length;
}
/* get the stream entries */
@@ -77,7 +100,10 @@ ssize_t dvb_table_pmt_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
struct dvb_table_pmt_stream *stream;
stream = malloc(sizeof(struct dvb_table_pmt_stream));
-
+ if (!stream) {
+ dvb_logerr("%s: out of memory", __func__);
+ return -3;
+ }
memcpy(stream, p, size);
p += size;
@@ -91,16 +117,17 @@ ssize_t dvb_table_pmt_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
/* parse the descriptors */
if (stream->desc_length > 0) {
- size = stream->desc_length;
- if (p + size > endbuf) {
- dvb_logwarn("%s: decsriptors short read %zd/%zd bytes", __func__,
- size, endbuf - p);
- size = endbuf - p;
+ uint16_t desc_length = stream->desc_length;
+ if (p + desc_length > endbuf) {
+ dvb_logwarn("%s: decsriptors short read %zd/%d bytes", __func__,
+ endbuf - p, desc_length);
+ desc_length = endbuf - p;
}
- dvb_parse_descriptors(parms, p, size,
- &stream->descriptor);
-
- p += size;
+ if (dvb_parse_descriptors(parms, p, desc_length,
+ &stream->descriptor) != 0) {
+ return -4;
+ }
+ p += desc_length;
}
}
if (p < endbuf)
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2011-2012 - Mauro Carvalho Chehab
- * Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
+ * Copyright (c) 2012-2014 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -20,40 +20,64 @@
*/
#include <libdvbv5/sdt.h>
+#include <libdvbv5/descriptors.h>
#include <libdvbv5/dvb-fe.h>
ssize_t dvb_table_sdt_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
ssize_t buflen, struct dvb_table_sdt *sdt, ssize_t *table_length)
{
const uint8_t *p = buf, *endbuf = buf + buflen - 4;
- struct dvb_table_sdt_service **head = &sdt->service;
- size_t size = offsetof(struct dvb_table_sdt, service);
+ struct dvb_table_sdt_service **head;
+ size_t size;
+
+ size = offsetof(struct dvb_table_sdt, service);
+ if (p + size > endbuf) {
+ dvb_logerr("%s: short read %zd/%zd bytes", __func__,
+ endbuf - p, size);
+ return -1;
+ }
+
+ if (buf[0] != DVB_TABLE_SDT && buf[0] != DVB_TABLE_SDT2) {
+ dvb_logerr("%s: invalid marker 0x%02x, sould be 0x%02x or 0x%02x",
+ __func__, buf[0], DVB_TABLE_SDT, DVB_TABLE_SDT2);
+ return -2;
+ }
if (*table_length > 0) {
+ memcpy(sdt, p, size);
+ bswap16(sdt->network_id);
+
/* find end of curent list */
+ head = &sdt->service;
while (*head != NULL)
head = &(*head)->next;
} else {
- if (p + size > endbuf) {
- dvb_logerr("SDT table was truncated. Need %zu bytes, but has only %zu.",
- size, buflen);
- return -1;
- }
memcpy(sdt, p, size);
- *table_length = sizeof(struct dvb_table_sdt);
-
bswap16(sdt->network_id);
sdt->service = NULL;
+ head = &sdt->service;
}
p += size;
+ size = sdt->header.section_length + 3 - 4; /* plus header, minus CRC */
+ if (buf + size > endbuf) {
+ dvb_logerr("%s: short read %zd/%zd bytes", __func__,
+ endbuf - buf, size);
+ return -3;
+ }
+ endbuf = buf + size;
+
+ /* get the event entries */
size = offsetof(struct dvb_table_sdt_service, descriptor);
while (p + size <= endbuf) {
struct dvb_table_sdt_service *service;
service = malloc(sizeof(struct dvb_table_sdt_service));
-
+ if (!service) {
+ dvb_logerr("%s: out of memory", __func__);
+ return -5;
+ }
memcpy(service, p, size);
p += size;
@@ -65,15 +89,25 @@ ssize_t dvb_table_sdt_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
*head = service;
head = &(*head)->next;
- /* get the descriptors for each program */
- dvb_parse_descriptors(parms, p, service->section_length,
- &service->descriptor);
+ /* parse the descriptors */
+ if (service->desc_length > 0) {
+ uint16_t desc_length = service->desc_length;
+ if (p + desc_length > endbuf) {
+ dvb_logwarn("%s: decsriptors short read %zd/%d bytes", __func__,
+ endbuf - p, desc_length);
+ desc_length = endbuf - p;
+ }
+ if (dvb_parse_descriptors(parms, p, desc_length,
+ &service->descriptor) != 0) {
+ return -4;
+ }
+ p += desc_length;
+ }
- p += service->section_length;
}
if (endbuf - p)
- dvb_logerr("SDT table has %zu spurious bytes at the end.",
- endbuf - p);
+ dvb_logwarn("%s: %zu spurious bytes at the end",
+ __func__, endbuf - p);
*table_length = p - buf;
return p - buf;
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2013 - Mauro Carvalho Chehab <m.chehab@samsung.com>
- * Copyright (c) 2013 - Andre Roth <neolynx@gmail.com>
+ * Copyright (c) 2013-2014 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -20,6 +20,7 @@
*/
#include <libdvbv5/vct.h>
+#include <libdvbv5/descriptors.h>
#include <libdvbv5/dvb-fe.h>
#include <parse_string.h>
@@ -27,27 +28,35 @@ ssize_t atsc_table_vct_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
ssize_t buflen, struct atsc_table_vct *vct, ssize_t *table_length)
{
const uint8_t *p = buf, *endbuf = buf + buflen - 4;
- struct atsc_table_vct_channel **head = &vct->channel;
+ struct atsc_table_vct_channel **head;
+ size_t size;
int i, n;
- size_t size = offsetof(struct atsc_table_vct, channel);
+ size = offsetof(struct atsc_table_vct, channel);
if (p + size > endbuf) {
- dvb_logerr("VCT table was truncated. Need %zu bytes, but has only %zu.",
- size, buflen);
+ dvb_logerr("%s: short read %zd/%zd bytes", __func__,
+ endbuf - p, size);
return -1;
}
+ if (buf[0] != ATSC_TABLE_TVCT && buf[0] != ATSC_TABLE_CVCT) {
+ dvb_logerr("%s: invalid marker 0x%02x, sould be 0x%02x or 0x%02x",
+ __func__, buf[0], ATSC_TABLE_TVCT, ATSC_TABLE_CVCT);
+ return -2;
+ }
+
if (*table_length > 0) {
/* find end of curent list */
+ head = &vct->channel;
while (*head != NULL)
head = &(*head)->next;
} else {
memcpy(vct, p, size);
- *table_length = sizeof(struct atsc_table_vct);
-
vct->channel = NULL;
vct->descriptor = NULL;
+
+ head = &vct->channel;
}
p += size;
@@ -56,13 +65,17 @@ ssize_t atsc_table_vct_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
struct atsc_table_vct_channel *channel;
if (p + size > endbuf) {
- dvb_logerr("VCT channel table is missing %d elements",
- vct->num_channels_in_section - n + 1);
+ dvb_logerr("%s: channel table is missing %d elements",
+ __func__, vct->num_channels_in_section - n + 1);
vct->num_channels_in_section = n;
break;
}
channel = malloc(sizeof(struct atsc_table_vct_channel));
+ if (!channel) {
+ dvb_logerr("%s: out of memory", __func__);
+ return -3;
+ }
memcpy(channel, p, size);
p += size;
@@ -123,8 +136,8 @@ ssize_t atsc_table_vct_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
&vct->descriptor);
}
if (endbuf - p)
- dvb_logerr("VCT table has %zu spurious bytes at the end.",
- endbuf - p);
+ dvb_logwarn("%s: %zu spurious bytes at the end",
+ __func__, endbuf - p);
*table_length = p - buf;
return p - buf;
}
- make the code look similar - check for correct table ID - ignore null packets with ID 0x1fff - return table length, or: - return error code on error - update / fix Copyrights Signed-off-by: André Roth <neolynx@gmail.com> --- lib/include/libdvbv5/atsc_eit.h | 1 - lib/include/libdvbv5/descriptors.h | 1 + lib/include/libdvbv5/eit.h | 3 +- lib/include/libdvbv5/mgt.h | 1 - lib/include/libdvbv5/nit.h | 2 +- lib/include/libdvbv5/pat.h | 4 +- lib/include/libdvbv5/sdt.h | 5 +- lib/include/libdvbv5/vct.h | 1 - lib/libdvbv5/descriptors.c | 9 +++- lib/libdvbv5/descriptors/atsc_eit.c | 35 +++++++------ lib/libdvbv5/descriptors/cat.c | 53 +++++++++++++------ lib/libdvbv5/descriptors/eit.c | 90 +++++++++++++++++++++------------ lib/libdvbv5/descriptors/mgt.c | 43 +++++++++------- lib/libdvbv5/descriptors/nit.c | 71 ++++++++++++++------------ lib/libdvbv5/descriptors/pat.c | 73 ++++++++++++++++----------- lib/libdvbv5/descriptors/pmt.c | 95 ++++++++++++++++++++++------------- lib/libdvbv5/descriptors/sdt.c | 68 ++++++++++++++++++------- lib/libdvbv5/descriptors/vct.c | 35 +++++++++---- 18 files changed, 374 insertions(+), 216 deletions(-)