libdvbv5: fix VCT parsing
authorMauro Carvalho Chehab <m.chehab@samsung.com>
Wed, 13 Nov 2013 20:42:22 +0000 (18:42 -0200)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Wed, 13 Nov 2013 20:44:33 +0000 (18:44 -0200)
While converting dvb-scan to use the new descriptors approach, I
was able to test the VCT table parsing. So, fix them. It should now
parse properly the ATSC CVCT/TVCT tables:

INFO     TVCT
INFO     | table_id       200
INFO     | section_length 154
INFO     | zero           0
INFO     | one            3
INFO     | zero2          1
INFO     | syntax         1
INFO     | id             1399
INFO     | current_next   1
INFO     | version        4
INFO     | one2           3
INFO     | section_id     0
INFO     | last_section   0
INFO     |- Protocol version 0
INFO     |- #channels        3
INFO     |\  channel_id
INFO     |- Channel                256.496: WMAR HD
INFO     |   modulation mode       8
INFO     |   carrier frequency     698000000
INFO     |   TS ID                 1399
INFO     |   program number        2
INFO     |   ETM location          0
INFO     |   access controlled     0
INFO     |   hidden                0
INFO     |   hide guide            1
INFO     |   service type          2
INFO     |   source id            33
INFO     |                   Unknown descriptor (161)
INFO     |                       e0 21 02 02 e0 21 65 6e  67 81 e0 24 65 6e 67      .!...!eng..$eng
INFO     |- Channel                256.752: WMAR SD
INFO     |   modulation mode       8
INFO     |   carrier frequency     698000000
INFO     |   TS ID                 1399
INFO     |   program number        3
INFO     |   ETM location          0
INFO     |   access controlled     0
INFO     |   hidden                0
INFO     |   hide guide            1
INFO     |   service type          2
INFO     |   source id            49
INFO     |                   Unknown descriptor (161)
INFO     |                       e0 31 02 02 e0 31 65 6e  67 81 e0 34 65 6e 67      .1...1eng..4eng
INFO     |- Channel                256.1008: WMAR SD
INFO     |   modulation mode       8
INFO     |   carrier frequency     698000000
INFO     |   TS ID                 1399
INFO     |   program number        4
INFO     |   ETM location          0
INFO     |   access controlled     0
INFO     |   hidden                0
INFO     |   hide guide            1
INFO     |   service type          2
INFO     |   source id            65
INFO     |                   Unknown descriptor (161)
INFO     |                       e0 41 01 02 e0 41 65 6e  67                        .A...Aeng
INFO     |_  3 channels

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
lib/include/descriptors/vct.h
lib/libdvbv5/descriptors/vct.c

index a32088b..94d783c 100644 (file)
@@ -85,27 +85,6 @@ struct dvb_table_vct_channel {
 struct dvb_table_vct {
        struct dvb_table_header header;
 
-       union {
-               uint16_t bitfield;
-               struct {
-                       uint16_t section_length:12;
-                       uint16_t reserved1:2;
-                       uint16_t private_indicator:1;
-                       uint16_t section_syntax_indicator:1;
-               } __attribute__((packed));
-       };
-
-       union {
-               uint16_t transport_stream_id;   /* TVCT */
-               uint16_t table_id_extension;    /* CVCT */
-       } __attribute__((packed));
-
-       uint8_t reserved2:2;
-       uint8_t version_number:5;
-       uint8_t current_next_indicator:1;
-
-       uint8_t section_number;
-       uint8_t last_section_number;
        uint8_t ATSC_protocol_version;
        uint8_t num_channels_in_section;
 
index 5197469..70ccd7e 100644 (file)
@@ -27,19 +27,16 @@ void dvb_table_vct_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize
        const uint8_t *p = buf;
        struct dvb_table_vct *vct = (struct dvb_table_vct *) table;
        struct dvb_table_vct_channel **head;
-       int i;
+       int i, n;
 
-       bswap16(vct->bitfield);
-       bswap16(vct->transport_stream_id);
-
-       if (*table_length > 0) {
+       if (*table_length >= offsetof(struct dvb_table_vct, channel)) {
                /* find end of curent list */
                head = &vct->channel;
                while (*head != NULL)
                        head = &(*head)->next;
        } else {
-               memcpy(vct, p, sizeof(struct dvb_table_vct) - sizeof(vct->channel));
-               *table_length = sizeof(struct dvb_table_vct);
+               memcpy(vct, p, offsetof(struct dvb_table_vct, channel));
+               *table_length = offsetof(struct dvb_table_vct, channel);
 
                vct->channel = NULL;
                head = &vct->channel;
@@ -47,7 +44,7 @@ void dvb_table_vct_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize
        p += sizeof(struct dvb_table_vct) - sizeof(vct->channel);
 
        struct dvb_table_vct_channel *last = NULL;
-       while ((uint8_t *) p < buf + buflen - 4) {
+       for (n = 0; n < vct->num_channels_in_section; n++) {
                struct dvb_table_vct_channel *channel = (struct dvb_table_vct_channel *) malloc(sizeof(struct dvb_table_vct_channel));
 
                memcpy(channel, p, offsetof(struct dvb_table_vct_channel, descriptor));
@@ -76,6 +73,7 @@ void dvb_table_vct_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize
                /* Fill descriptors */
 
                channel->descriptor = NULL;
+               channel->next = NULL;
 
                if (!*head)
                        *head = channel;
@@ -112,12 +110,9 @@ void dvb_table_vct_print(struct dvb_v5_fe_parms *parms, struct dvb_table_vct *vc
                dvb_log("TVCT");
 
        dvb_table_header_print(parms, &vct->header);
-       dvb_log("|- ts_id                  %d", vct->transport_stream_id);
-       dvb_log("|- version_number         %d", vct->version_number);
-       dvb_log("|- current_next_indicator %d", vct->current_next_indicator);
-       dvb_log("|- section_number         %d", vct->section_number);
-       dvb_log("|- last_section_number    %d", vct->last_section_number);
-       dvb_log("|- ATSC_protocol_version  %d", vct->ATSC_protocol_version);
+
+       dvb_log("|- Protocol version %d", vct->ATSC_protocol_version);
+       dvb_log("|- #channels        %d", vct->num_channels_in_section);
        dvb_log("|\\  channel_id");
        const struct dvb_table_vct_channel *channel = vct->channel;
        uint16_t channels = 0;