working with first descriptor

This commit is contained in:
hummypkg 2011-06-02 11:14:43 +00:00 committed by HummyPkg
parent d91dccdd7b
commit db87f8326e
9 changed files with 247 additions and 119 deletions

View File

@ -12,11 +12,17 @@ MAKE=gmake
DEFS=-D_REENTRANT -D_TS_ERRNO -DHMT_PROTECT
# -DWITH_MPATROL
SRCS= epg.c \
SRCS= descriptor.c \
epg.c \
file.c \
main.c \
util.c
HDRS= descriptor.h \
epg.h \
lint.h \
util.h
OBJS= $(SRCS:.c=.o)
CC=gcc
#CC=mipsel-linux-gcc
@ -61,5 +67,5 @@ tags:
@echo " $<"
@$(CC) $(CFLAGS) ${WARN} ${DEFS} ${INCS} -c $< -o $@
${OBJS}: lint.h
${OBJS}: ${HDRS}

119
descriptor.c Normal file
View File

@ -0,0 +1,119 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>
#include <strings.h>
#include "lint.h"
struct descriptor *
read_descriptor_header(struct epg *epg)
{
static struct descriptor d;
if (epg->binsize - epg->offset < 2)
return NULL;
memcpy(&d, epg->bin + epg->offset, 2);
epg->offset += 2;
return &d;
}
void
read_descriptor(struct epg *epg, struct descriptor *d)
{
switch (d->tag)
{
case 77:
memcpy(d->content.d77.language, epg->bin + epg->offset, 3);
epg->offset += 3;
d->content.d77.namelen = epg->bin[epg->offset++];
d->content.d77.name = read_string_len(epg->bin + epg->offset,
d->content.d77.namelen);
epg->offset += d->content.d77.namelen;
d->content.d77.textlen = epg->bin[epg->offset++];
d->content.d77.text = read_string_len(epg->bin + epg->offset,
d->content.d77.textlen);
epg->offset += d->content.d77.textlen;
break;
default:
epg->offset += d->len;
break;
}
}
inline void
skip_descriptor(struct epg *epg, struct descriptor *d)
{
epg->offset += d->len;
}
void
free_descriptor(struct descriptor *d)
{
switch (d->tag)
{
case DS_SHORT_EVENT:
free(d->content.d77.name);
free(d->content.d77.text);
break;
default:
break;
}
}
char *
descriptor_name(struct descriptor *d)
{
switch (d->tag)
{
case DS_LINKAGE: return "linkage";
case DS_SHORT_EVENT: return "short event";
case DS_COMPONENT: return "component";
case DS_CONTENT: return "content";
case DS_PRIVATE_DATA_SPECIFIER: return "private data spec.";
case DS_CONTENT_IDENTIFIER: return "content id";
case DS_FTA_CONTENT_MGMT: return "content mgmt";
case DS_USER_DEFINED: return "user defined";
default: return "Unknown";
}
return "Unknown";
}
void
dump_descriptor(struct descriptor *d, int content)
{
printf("Descriptor header:\n");
printf(" %30s: %#x [%d] (%s)\n", "descriptor", d->tag, d->tag,
descriptor_name(d));
DUMPINT(d, len);
if (!content)
return;
switch (d->tag)
{
case DS_SHORT_EVENT:
DUMPNSTR(d, content.d77.language, 3);
DUMPINT(d, content.d77.namelen);
//DUMPNSTR(d, content.d77.name, d->content.d77.namelen);
DUMPHEX(d, content.d77.name, d->content.d77.namelen);
DUMPINT(d, content.d77.textlen);
//DUMPNSTR(d, content.d77.text, d->content.d77.textlen);
DUMPHEX(d, content.d77.text, d->content.d77.textlen);
break;
default:
break;
}
}

23
descriptor.h Normal file
View File

@ -0,0 +1,23 @@
#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_CONTENT_IDENTIFIER 118
#define DS_FTA_CONTENT_MGMT 126
#define DS_USER_DEFINED 137
struct descriptor {
unsigned int tag:8;
unsigned int len:8;
union {
struct {
char language[3];
unsigned int namelen:8;
unsigned int textlen:8;
char *name;
char *text;
} d77;
} content;
};

110
epg.c
View File

@ -9,18 +9,16 @@
#include "lint.h"
#define _swap16(v) ((((v) >> 8) & 0xff) | (((v) & 0xff) << 8))
struct section_header *
read_section_header(struct epg *epg)
struct section *
read_section(struct epg *epg)
{
static struct section_header h;
static struct section h;
if (epg->binsize - epg->offset < sizeof(h))
return NULL;
memcpy(&h, epg->bin + epg->offset, sizeof(h));
if (memcmp(h.magic, SECTION_HEADER_MAGIC, sizeof(h.magic)))
if (memcmp(h.magic, SECTION_MAGIC, sizeof(h.magic)))
{
printf("Section header magic mismatch.\n");
return NULL;
@ -38,6 +36,27 @@ read_section_header(struct epg *epg)
return &h;
}
void
dump_section(struct section *h)
{
printf("Section header:\n");
DUMPINT(h, total_length);
DUMPINT(h, table_id);
DUMPINT(h, u1.u.syntax_indicator);
DUMPINT(h, u1.u.reserved);
DUMPINT(h, u1.u.length);
DUMPINT(h, service_id);
DUMPINT(h, reserved2);
DUMPINT(h, version_number);
DUMPINT(h, current_next_indicator);
DUMPINT(h, section_number);
DUMPINT(h, last_section_number);
DUMPINT(h, transport_stream_id);
DUMPINT(h, original_network_id);
DUMPINT(h, segment_last_section_number);
DUMPINT(h, last_table_id);
}
struct data *
read_data(struct epg *epg)
{
@ -57,58 +76,6 @@ read_data(struct epg *epg)
return &d;
}
struct descriptor_header *
read_descriptor_header(struct epg *epg)
{
static struct descriptor_header d;
if (epg->binsize - epg->offset < sizeof(d))
return NULL;
memcpy(&d, epg->bin + epg->offset, sizeof(d));
epg->offset += sizeof(d);
return &d;
}
#define DUMPINT(ss,xx) printf(" %30s: %d\n", #xx, ss->xx)
#define DUMPSTR(ss,xx) printf(" %30s: %s\n", #xx, ss->xx)
#define DUMPHEX(ss,xx) printf(" %30s: %s\n", #xx, \
hexstr(ss->xx, sizeof(ss->xx)))
char *
ctime_nl(time_t *tm)
{
static char buf[26];
strcpy(buf, ctime(tm));
*strchr(buf, '\n') = '\0';
return buf;
}
void
dump_section_header(struct section_header *h)
{
printf("Section header:\n");
DUMPINT(h, total_length);
DUMPINT(h, table_id);
DUMPINT(h, u1.u.syntax_indicator);
DUMPINT(h, u1.u.reserved);
DUMPINT(h, u1.u.length);
DUMPINT(h, service_id);
DUMPINT(h, reserved2);
DUMPINT(h, version_number);
DUMPINT(h, current_next_indicator);
DUMPINT(h, section_number);
DUMPINT(h, last_section_number);
DUMPINT(h, transport_stream_id);
DUMPINT(h, original_network_id);
DUMPINT(h, segment_last_section_number);
DUMPINT(h, last_table_id);
}
void
dump_data(struct data *d)
{
@ -131,30 +98,3 @@ dump_data(struct data *d)
DUMPINT(d, u1.u.descriptors_loop_length);
}
char *
descriptor_name(struct descriptor_header *d)
{
switch (d->tag)
{
case 77: return "short event";
case 80: return "component";
case 137: return "user defined";
case 118: return "content identifier";
case 74: return "linkage";
case 84: return "content";
case 95: return "private data specifier";
case 126: return "FTA content management";
default: return "Unknown";
}
return "Unknown";
}
void
dump_descriptor_header(struct descriptor_header *d)
{
printf("Descriptor header:\n");
printf(" %30s: %#x [%d] (%s)\n", "descriptor", d->tag, d->tag,
descriptor_name(d));
DUMPINT(d, len);
}

10
epg.h
View File

@ -9,10 +9,10 @@ struct epg {
uint32_t binsize;
};
#define SECTION_HEADER_MAGIC "(Gq\x87\x00\x00\x00\x00\x02\x00\x00\x00\x00\x01"
#define SECTION_MAGIC "(Gq\x87\x00\x00\x00\x00\x02\x00\x00\x00\x00\x01"
#pragma pack(1)
struct section_header {
struct section {
char magic[14];
unsigned int total_length:16;
unsigned int magic2:32;
@ -37,6 +37,7 @@ struct section_header {
unsigned int last_table_id:8;
};
#pragma pack(1)
struct data {
unsigned int event_id:16;
unsigned int start_date:16;
@ -56,8 +57,3 @@ struct data {
} u1;
};
struct descriptor_header {
unsigned int tag:8;
unsigned int len:8;
};

19
lint.h
View File

@ -1,8 +1,7 @@
#include "epg.h"
/* Works for modern dates, 1970 - 2038 */
#define MJD_TO_UNIX(xx) (((xx) - 40587) * 86400)
#include "descriptor.h"
#include "util.h"
extern int debug;
extern const char *version;
@ -11,17 +10,21 @@ extern unsigned long sysopts;
inline uint16_t read_uint16(uint8_t *, int);
inline uint32_t read_uint32(uint8_t *, int);
void hexdump(uint8_t *, uint32_t, uint32_t);
void hexstr(uint8_t *, uint32_t);
char *hexstr(uint8_t *, uint32_t);
char *ctime_nl(time_t *);
char *read_string_len(uint8_t *, uint32_t);
struct epg *open_file(char *);
void close_file(struct epg *);
struct section_header *read_section_header(struct epg *);
void dump_section_header(struct section_header *);
struct section *read_section(struct epg *);
void dump_section(struct section *);
struct data *read_data(struct epg *);
void dump_data(struct data *);
struct descriptor_header *read_descriptor_header(struct epg *);
void dump_descriptor_header(struct descriptor_header *);
struct descriptor *read_descriptor_header(struct epg *);
void read_descriptor(struct epg *, struct descriptor *);
void skip_descriptor(struct epg *, struct descriptor *);
void dump_descriptor(struct descriptor *, int);

37
main.c
View File

@ -36,8 +36,7 @@ syntax()
int
main(int argc, char **argv)
{
struct section_header *h;
struct data *d;
struct section *h;
struct epg *epg;
if (!(epg = open_file("../epg.dat")))
@ -45,36 +44,44 @@ main(int argc, char **argv)
while (epg->offset < epg->binsize)
{
uint32_t end;
uint32_t send;
if (!(h = read_section_header(epg)))
if (!(h = read_section(epg)))
break;
dump_section_header(h);
//dump_section(h);
end = epg->offset - 11 + h->u1.u.length - 4;
send = epg->offset - 11 + h->u1.u.length - 4;
while (epg->offset < end)
while (epg->offset < send)
{
struct data *d;
uint32_t dend;
if (!(d = read_data(epg)))
break;
dump_data(d);
//dump_data(d);
dend = epg->offset + d->u1.u.descriptors_loop_length;
while (epg->offset < dend)
{
struct descriptor_header *dh;
struct descriptor *ds;
dh = read_descriptor_header(epg);
dump_descriptor_header(dh);
epg->offset += dh->len;
ds = read_descriptor_header(epg);
if (ds->tag == DS_SHORT_EVENT)
{
read_descriptor(epg, ds);
dump_descriptor(ds, 1);
}
else
{
dump_descriptor(ds, 0);
skip_descriptor(epg, ds);
}
printf("Offset: %d / %d\n", epg->offset, dend);
}
//goto stop;
}
/* Section CRC */
/* Skip CRC */
epg->offset += 4;
/* Skip padding bytes... */

27
util.c
View File

@ -12,6 +12,26 @@
#include "lint.h"
char *
ctime_nl(time_t *tm)
{
static char buf[26];
strcpy(buf, ctime(tm));
*strchr(buf, '\n') = '\0';
return buf;
}
inline char *
read_string_len(uint8_t *src, uint32_t len)
{
char *s = malloc(len + 1);
memcpy(s, src, len);
s[len] = '\0';
return s;
}
inline uint32_t
read_uint32(uint8_t *p, int le)
{
@ -77,9 +97,10 @@ hexdump(uint8_t *s, uint32_t len, uint32_t o)
}
}
void
char *
hexstr(uint8_t *s, uint32_t len)
{
static char buf[0x1000];
uint16_t off;
if (!s)
@ -88,6 +109,7 @@ hexstr(uint8_t *s, uint32_t len)
if (!len)
len = strlen((char *)s);
memset(buf, '\0', sizeof(buf));
for (off = 0; off < len; off += 16)
{
uint32_t i;
@ -95,9 +117,10 @@ hexstr(uint8_t *s, uint32_t len)
for (i = off; i - off < 16; i++)
{
if (i < len)
printf("%02x", s[i] & 0xff);
sprintf(buf + i * 3, "%02x ", s[i] & 0xff);
}
}
return buf;
}
void

11
util.h Normal file
View File

@ -0,0 +1,11 @@
/* Works for modern dates, 1970 - 2038 */
#define MJD_TO_UNIX(xx) (((xx) - 40587) * 86400)
#define _swap16(v) ((((v) >> 8) & 0xff) | (((v) & 0xff) << 8))
#define DUMPINT(ss,xx) printf(" %30s: %d\n", #xx, ss->xx)
#define DUMPSTR(ss,xx) printf(" %30s: %s\n", #xx, ss->xx)
#define DUMPNSTR(ss,xx,nn) printf(" %30s: %.*s\n", #xx, nn, ss->xx)
#define DUMPHEX(ss,xx,nn) printf(" %30s: %s\n", #xx, hexstr(ss->xx, nn))