diff --git a/descriptor.c b/descriptor.c index 535e34c..66d82b7 100644 --- a/descriptor.c +++ b/descriptor.c @@ -86,6 +86,31 @@ read_descriptor(struct epg *epg, struct descriptor *d) break; + case DS_EXTENDED_EVENT: + { + unsigned int i; + + epg->offset++; /* Skip descriptor number and last descriptor */ + memcpy(d->content.d78.lang, epg->bin + epg->offset, 3); + epg->offset += 3; + + d->content.d78.items = epg->bin[epg->offset++]; + if (debug > 1 && d->content.d78.items > 0) + printf("Extended event items: %d\n", + d->content.d78.items); + /* Skip items. */ + for (i = 0; i < d->content.d78.items; i++) + { + int l = epg->bin[epg->offset++]; + epg->offset += l; + } + + d->content.d78.text = + read_lstring(epg, &d->content.d78.textlen); + + break; + } + case DS_COMPONENT: memcpy(&d->content.d80, epg->bin + epg->offset, 6); epg->offset += 6; @@ -216,6 +241,11 @@ free_descriptor(struct descriptor *d) free(d->content.d77.text); break; + case DS_EXTENDED_EVENT: + if (d->content.d78.text) + free(d->content.d78.text); + break; + case DS_COMPONENT: if (d->content.d80.text) free(d->content.d80.text); @@ -325,6 +355,13 @@ dump_descriptor(struct descriptor *d, int content) DUMPHEX(d, content.d77.text, d->content.d77.textlen); break; + case DS_EXTENDED_EVENT: + DUMPNSTR(d, content.d78.lang, 3); + DUMPINT(d, content.d78.items); + DUMPINT(d, content.d78.textlen); + DUMPHEX(d, content.d78.text, d->content.d78.textlen); + break; + case DS_COMPONENT: DUMPINT(d, content.d80.stream_content); DUMPINT(d, content.d80.reserved); diff --git a/descriptor.h b/descriptor.h index f1d274b..c5ddb96 100644 --- a/descriptor.h +++ b/descriptor.h @@ -3,11 +3,12 @@ * by af123, 2011 */ -#define DS_LINKAGE 74 -#define DS_SHORT_EVENT 77 -#define DS_COMPONENT 80 -#define DS_CONTENT 84 -#define DS_PRIVATE_DATA_SPECIFIER 95 +#define DS_LINKAGE 74 /* 0x4a */ +#define DS_SHORT_EVENT 77 /* 0x4d */ +#define DS_EXTENDED_EVENT 78 /* 0x4e */ +#define DS_COMPONENT 80 /* 0x50 */ +#define DS_CONTENT 84 /* 0x54 */ +#define DS_PRIVATE_DATA_SPECIFIER 95 /* 0x5f */ #define DS_CONTENT_IDENTIFIER 118 #define DS_FTA_CONTENT_MGMT 126 #define DS_USER_DEFINED 137 @@ -18,7 +19,8 @@ #define PARSER_CRID_EVENT 3 #define PARSER_CRID_SERIES 4 #define PARSER_CRID_REC 5 -#define PARSER_MAX 6 +#define PARSER_EXTENDED_EVENT 6 +#define PARSER_MAX 7 #define CRIDT_EVENT '1' #define CRIDT_SERIES '2' @@ -44,6 +46,12 @@ struct descriptor { char *name; char *text; } d77; /* SHORT_EVENT */ + struct { + char lang[3]; + unsigned int items; + unsigned int textlen; + char *text; + } d78; /* EXTENDED_EVENT */ struct { unsigned int stream_content:4; unsigned int reserved:4; diff --git a/epg.c b/epg.c index 30d1960..01fc19a 100644 --- a/epg.c +++ b/epg.c @@ -288,8 +288,12 @@ parse(char *epgpath, } if (debug) - printf("Checking descriptor: %d (%d)\n", - dstag, dslen); + printf("Checking descriptor: " + "%d/%#x (%d)\n", + dstag, dstag, dslen); + if (debug > 3) + hexdump(epg->bin + epg->offset, + dslen + 2, 0); switch (dstag) { @@ -300,6 +304,13 @@ parse(char *epgpath, dslist[PARSER_SHORT_EVENT] = ds; break; + case DS_EXTENDED_EVENT: + if (!(ds = read_descriptor_header(epg))) + break; + read_descriptor(epg, ds); + dslist[PARSER_EXTENDED_EVENT] = ds; + break; + case DS_CONTENT_IDENTIFIER: if (!(ds = read_descriptor_header(epg))) break; @@ -347,17 +358,39 @@ parse(char *epgpath, */ default: - if (debug > 3) - { - printf("Unhandled.\n"); - hexdump(epg->bin + epg->offset, - dslen + 2, 0); - } + if (debug > 2) + printf("! Unhandled.\n"); epg->offset += dslen + 2; break; } } + /* Move synopsis from extended event descriptor into + * short description if appropriate. */ + if (dslist[PARSER_SHORT_EVENT] && + dslist[PARSER_EXTENDED_EVENT] && + dslist[PARSER_EXTENDED_EVENT]->content.d78.textlen + > 0 && + dslist[PARSER_SHORT_EVENT]->content.d77.textlen + == 2 && + dslist[PARSER_SHORT_EVENT]->content.d77.text[1] + == '\0') + { + if (debug > 3) + printf("Moving event text from " + "extended to short event.\n"); + free(dslist[PARSER_SHORT_EVENT] + ->content.d77.text); + dslist[PARSER_SHORT_EVENT]->content.d77.text + = dslist[PARSER_EXTENDED_EVENT]-> + content.d78.text; + dslist[PARSER_SHORT_EVENT]->content.d77.textlen + = dslist[PARSER_EXTENDED_EVENT]-> + content.d78.textlen; + dslist[PARSER_EXTENDED_EVENT]->content.d78.text + = (char *)NULL; + } + if ( ( !(filterflags & FILTER_CRID) || diff --git a/main.c b/main.c index 0e24a30..30bd6ae 100644 --- a/main.c +++ b/main.c @@ -75,6 +75,7 @@ syntax() " now Show what is currently on.\n" " first Show the time of the earliest record.\n" " last Show the time of the latest record.\n" + " d78 Check for records with d78.\n" " parse Parse the EPG, no output.\n" " search Search programme names for text.\n" " searchall " @@ -127,6 +128,20 @@ earliest(struct epg *epg __attribute__((unused)), latest_stamp = tm; } +void +d78check(struct epg *epg __attribute__((unused)), + struct section *s __attribute__((unused)), + struct data *d __attribute__((unused)), + struct descriptor **ds __attribute__((unused)), + void *var __attribute__((unused))) +{ + if (ds[PARSER_EXTENDED_EVENT]) + { + printf("Found descriptor 78 in event.\n"); + exit(1); + } +} + void dumpraw(struct epg *epg __attribute__((unused)), struct section *s, struct data *d, struct descriptor **ds, @@ -832,6 +847,8 @@ nextopt: parse(epgpath, latest, NULL, filter); printf("%ld\n", latest_stamp); } + else if (!strcmp(argv[0], "d78")) + parse(epgpath, d78check, NULL, filter); else if (!strcmp(argv[0], "first")) { parse(epgpath, earliest, NULL, filter);