summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2003-04-12 11:32:31 +0200
committerKlaus Schmidinger <vdr@tvdr.de>2003-04-12 11:32:31 +0200
commitf8a7e51d00d66f2fd71c9f5966a893c59485584b (patch)
tree65faf3f26927df1f1aed3fef5d6626a35cb5e907
parent7c84508417b9831b364947b4d7882209db50d4e8 (diff)
downloadvdr-f8a7e51d00d66f2fd71c9f5966a893c59485584b.tar.gz
vdr-f8a7e51d00d66f2fd71c9f5966a893c59485584b.tar.bz2
Now using 'libdtv' version 0.0.5
-rw-r--r--CONTRIBUTORS1
-rw-r--r--HISTORY2
-rw-r--r--eit.c51
-rw-r--r--eit.h3
-rw-r--r--libdtv/libsi/include/libsi.h248
-rw-r--r--libdtv/libsi/include/si_tables.h156
-rw-r--r--libdtv/libsi/si_debug_services.c130
-rw-r--r--libdtv/libsi/si_debug_services.h34
-rw-r--r--libdtv/libsi/si_parser.c430
9 files changed, 928 insertions, 127 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index f2c3a7ed..7a872990 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -166,6 +166,7 @@ Stefan Huelswitt <huels@iname.com>
for reporting a problem with timers when channel IDs have a 'source' that is 0
for reporting a new/delete malloc/free mismatch in ringbuffer.c
for reporting a crash in case the index file can't be accessed any more during replay
+ for adapting VDR to 'libdtv' version 0.0.5
Ulrich Röder <roeder@efr-net.de>
for pointing out that there are channels that have a symbol rate higher than
diff --git a/HISTORY b/HISTORY
index 0071d33f..f8b63a68 100644
--- a/HISTORY
+++ b/HISTORY
@@ -2020,3 +2020,5 @@ Video Disk Recorder Revision History
- Implemented a "resume ID" which allows several users to each have their own
resume.vdr files (thanks to Martin Hammerschmid). This parameter can be set in
the "Setup/Replay" menu (see MANUAL for details).
+- Now using 'libdtv' version 0.0.5 (thanks to Rolf Hakenes for the new version
+ and Stefan Huelswitt for adapting VDR to it).
diff --git a/eit.c b/eit.c
index 42740852..ff5dd42f 100644
--- a/eit.c
+++ b/eit.c
@@ -16,7 +16,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: eit.c 1.67 2003/03/16 11:20:05 kls Exp $
+ * $Id: eit.c 1.68 2003/04/12 11:27:31 kls Exp $
***************************************************************************/
#include "eit.h"
@@ -1011,29 +1011,37 @@ private:
int length;
uchar *data;
public:
- cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, int Length, uchar *Data);
+ cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, int CaPid, int Length, uchar *Data);
virtual ~cCaDescriptor();
int Length(void) const { return length; }
const uchar *Data(void) const { return data; }
};
-cCaDescriptor::cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, int Length, uchar *Data)
+cCaDescriptor::cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, int CaPid, int Length, uchar *Data)
{
source = Source;
transponder = Transponder;
serviceId = ServiceId;
caSystem = CaSystem;
- length = Length;
+ length = Length + 6;
data = MALLOC(uchar, length);
- memcpy(data, Data, length);
- /*//XXX just while debugging...
+ data[0] = DESCR_CA;
+ data[1] = length - 2;
+ data[2] = (caSystem >> 8) & 0xFF;
+ data[3] = caSystem & 0xFF;
+ data[4] = ((CaPid >> 8) & 0xFF) | 0xE0;
+ data[5] = CaPid & 0xFF;
+ if (Length)
+ memcpy(&data[6], Data, Length);
+//#define DEBUG_CA_DESCRIPTORS 1
+#ifdef DEBUG_CA_DESCRIPTORS
char buffer[1024];
char *q = buffer;
q += sprintf(q, "CAM: %04X %5d %4d", source, transponder, serviceId);
for (int i = 0; i < length; i++)
q += sprintf(q, " %02X", data[i]);
dsyslog(buffer);
- *///XXX
+#endif
}
cCaDescriptor::~cCaDescriptor()
@@ -1312,16 +1320,13 @@ void cSIProcessor::Action()
if (pid == pmtPid && buf[0] == 0x02 && currentSource && currentTransponder) {
struct Pid *pi = siParsePMT(buf);
if (pi) {
- for (struct LIST *d = (struct LIST *)pi->Descriptors; d; d = (struct LIST *)xSucc(d)) {
- if (DescriptorTag(d) == DESCR_CA) {
- uchar *Data = ((ConditionalAccessDescriptor *)d)->Data;
- int CaSystem = (Data[2] << 8) | Data[3];
- if (!caDescriptors->Get(currentSource, currentTransponder, pi->ProgramID, CaSystem)) {
- cMutexLock MutexLock(&caDescriptorsMutex);
- caDescriptors->Add(new cCaDescriptor(currentSource, currentTransponder, pi->ProgramID, CaSystem, ((ConditionalAccessDescriptor *)d)->Amount, Data));
- }
- //XXX update???
- }
+ struct Descriptor *d;
+ for (d = (struct Descriptor *)pi->Descriptors->Head; d; d = (struct Descriptor *)xSucc(d))
+ NewCaDescriptor(d, pi->ProgramID);
+ // Also scan the PidInfo list for descriptors - some broadcasts send them only here.
+ for (struct PidInfo *p = (struct PidInfo *)pi->InfoList->Head; p; p = (struct PidInfo *)xSucc(p)) {
+ for (d = (struct Descriptor *)p->Descriptors->Head; d; d = (struct Descriptor *)xSucc(d))
+ NewCaDescriptor(d, pi->ProgramID);
}
}
xMemFreeAll(NULL);
@@ -1438,6 +1443,18 @@ void cSIProcessor::TriggerDump(void)
lastDump = 0;
}
+void cSIProcessor::NewCaDescriptor(struct Descriptor *d, int ProgramID)
+{
+ if (DescriptorTag(d) == DESCR_CA) {
+ struct CaDescriptor *cd = (struct CaDescriptor *)d;
+ if (!caDescriptors->Get(currentSource, currentTransponder, ProgramID, cd->CA_type)) {
+ cMutexLock MutexLock(&caDescriptorsMutex);
+ caDescriptors->Add(new cCaDescriptor(currentSource, currentTransponder, ProgramID, cd->CA_type, cd->CA_PID, cd->DataLength, cd->Data));
+ }
+ //XXX update???
+ }
+}
+
int cSIProcessor::GetCaDescriptors(int Source, int Transponder, int ServiceId, int BufSize, uchar *Data)
{
if (BufSize > 0 && Data) {
diff --git a/eit.h b/eit.h
index 17fa9093..e956b013 100644
--- a/eit.h
+++ b/eit.h
@@ -16,7 +16,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: eit.h 1.24 2003/02/02 14:07:39 kls Exp $
+ * $Id: eit.h 1.25 2003/04/12 10:59:26 kls Exp $
***************************************************************************/
#ifndef __EIT_H
@@ -158,6 +158,7 @@ private:
bool AddFilter(unsigned short pid, u_char tid);
bool DelFilter(unsigned short pid, u_char tid);
bool ShutDownFilters(void);
+ void NewCaDescriptor(struct Descriptor *d, int ProgramID);
public:
cSIProcessor(const char *FileName);
~cSIProcessor();
diff --git a/libdtv/libsi/include/libsi.h b/libdtv/libsi/include/libsi.h
index 8e9e2605..cd07fc6d 100644
--- a/libdtv/libsi/include/libsi.h
+++ b/libdtv/libsi/include/libsi.h
@@ -4,11 +4,13 @@
/// ///
//////////////////////////////////////////////////////////////
-// $Revision: 1.6 $
-// $Date: 2002/01/30 17:04:13 $
+// $Revision: 1.7 $
+// $Date: 2003/04/12 11:27:31 $
// $Author: hakenes $
//
-// (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL.
+// (C) 2001-03 Rolf Hakenes <hakenes@hippomi.de>, under the
+// GNU GPL with contribution of Oleg Assovski,
+// www.satmania.com
//
// libsi is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -38,9 +40,9 @@
/* Program Identifier */
#define PID_PAT 0x00 /* Program Association Table */
-#define PID_BAT 0x01 /* Bouquet Association Table */
#define PID_CAT 0x01 /* Conditional Access Table */
#define PID_NIT 0x10 /* Network Information Table */
+#define PID_BAT 0x11 /* Bouquet Association Table */
#define PID_SDT 0x11 /* Service Description Table */
#define PID_EIT 0x12 /* Event Information Table */
#define PID_RST 0x13 /* Running Status Table */
@@ -75,12 +77,13 @@
#define TID_TOT 0x73 /* Time Offset Section */
#define TID_CA_ECM_0 0x80
#define TID_CA_ECM_1 0x81
+#define TID_CA_EMM 0x82
-#define TID_BAT 0x01 /* Bouquet Association Section */
+#define TID_BAT 0x4A /* Bouquet Association Section */
#define TID_EIT 0x12 /* Event Information Section */
-#define TID_RST 0x13 /* Running Status Section */
-#define TID_ST 0x14 /* Stuffung Section */
+#define TID_RST 0x71 /* Running Status Section */
+#define TID_ST 0x72 /* Stuffing Section */
/* 0xFF */ /* Reserved for future use */
/* Descriptor Identifier */
@@ -160,6 +163,40 @@
#define MAX_SECTION_BUFFER 4096
+/* NetworkInfo structure (used to store NIT/BAT information) */
+
+struct NetworkInfo {
+ struct NODE Node;
+ unsigned short ID; // NetworkID / BouquetID
+ struct LIST *Descriptors;
+ struct LIST *TransportStreams;
+};
+
+#define CreateNetworkInfo(ni, id) \
+ do { \
+ xCreateNode (ni, NULL); \
+ (ni)->ID = id; \
+ (ni)->Descriptors = xNewList(NULL); \
+ (ni)->TransportStreams = NULL; \
+ } while(0)
+
+/* TransportStream structure (NIT/BAT TS loop member) */
+
+struct TransportStream {
+ struct NODE Node;
+ int TransportStreamID;
+ unsigned short OriginalNetworkID;
+ struct LIST *Descriptors;
+};
+
+#define CreateTransportStream(ts, tsid, onid) \
+ do { \
+ xCreateNode (ts, NULL); \
+ (ts)->TransportStreamID = tsid; \
+ (ts)->OriginalNetworkID = onid; \
+ (ts)->Descriptors = xNewList(NULL); \
+ } while(0)
+
/* Strukturen zur Aufnahme der SDT und EIT Informationen */
struct Service {
@@ -305,38 +342,32 @@ struct PidInfo {
#define STREAMTYPE_13818_D 13
#define STREAMTYPE_13818_AUX 14
-/* Descriptors */
-
-#define DescriptorTag(x) ((struct Descriptor *)(x))->Tag
-struct Descriptor {
- struct NODE Node;
- unsigned short Tag;
+struct Tot {
+ time_t UTC;
+ time_t Bias;
+ struct LIST *Descriptors;
};
+#define CreateTot(tot, utc) \
+ do \
+ { \
+ xMemAlloc(sizeof(struct Tot), &tot); \
+ tot->UTC = utc; \
+ tot->Bias = ((utc - time(NULL) + 1800)/3600)*3600; \
+ tot->Descriptors = xNewList(NULL); \
+ } while (0)
-/* ConditionalAccessDescriptor */
-struct ConditionalAccessDescriptor {
+/* Descriptors */
+
+#define DescriptorTag(x) ((struct Descriptor *)(x))->Tag
+
+struct Descriptor {
struct NODE Node;
unsigned short Tag;
- unsigned short Amount; /* Data */
- unsigned char *Data;
};
-#define CreateConditionalAccessDescriptor(descr, amount, data) \
- do \
- { \
- unsigned char *tmpptr; \
- \
- xMemAlloc (amount, &tmpptr); \
- memcpy (tmpptr, data, amount); \
- xCreateNode (((struct ConditionalAccessDescriptor *)descr), NULL); \
- ((struct ConditionalAccessDescriptor *)descr)->Tag = DESCR_CA; \
- ((struct ConditionalAccessDescriptor *)descr)->Amount = amount; \
- ((struct ConditionalAccessDescriptor *)descr)->Data = tmpptr; \
- } while (0)
-
/* Iso639LanguageDescriptor */
@@ -434,19 +465,23 @@ struct AncillaryDataDescriptor {
/* BouquetNameDescriptor */
+/*
+ the same used instead of NetworkNameDescriptor because their structures
+ are identical. We pass 'tag' parameter to distinguish between them later
+*/
struct BouquetNameDescriptor {
struct NODE Node; /* Node enthält Namen */
unsigned short Tag;
};
-#define CreateBouquetNameDescriptor(descr, text) \
+#define CreateBouquetNameDescriptor(descr, text, tag) \
do \
{ \
xCreateNode (((struct BouquetNameDescriptor *)descr), NULL); \
((struct NODE *)descr)->Name = text; \
((struct NODE *)descr)->HashKey = xHashKey (text); \
- ((struct BouquetNameDescriptor *)descr)->Tag = DESCR_BOUQUET_NAME; \
+ ((struct BouquetNameDescriptor *)descr)->Tag = tag; \
} while (0)
@@ -514,6 +549,33 @@ struct CaIdentifierDescriptor {
((struct CaIdentifierDescriptor *)descr)->SystemID[num] = id
#define GetCaIdentifierID(descr, num) (((struct CaIdentifierDescriptor *)descr)->SystemID[num])
+/* CaDescriptor */
+
+struct CaDescriptor {
+ struct NODE Node;
+ unsigned short Tag;
+ unsigned short CA_type;
+ unsigned short CA_PID;
+ unsigned int ProviderID;
+ unsigned short DataLength;
+ unsigned char *Data;
+};
+
+#define CreateCaDescriptor(descr, typ, capid, len) \
+ do \
+ { \
+ xCreateNode (((struct CaDescriptor *)descr), NULL); \
+ ((struct CaDescriptor *)descr)->Tag = DESCR_CA; \
+ ((struct CaDescriptor *)descr)->CA_type = typ; \
+ ((struct CaDescriptor *)descr)->CA_PID = capid; \
+ ((struct CaDescriptor *)descr)->ProviderID = 0; \
+ ((struct CaDescriptor *)descr)->DataLength = len; \
+ xMemAlloc (len+1, &((struct CaDescriptor *)descr)->Data); \
+ } while (0)
+
+#define SetCaData(descr, num, id) \
+ ((struct CaDescriptor *)descr)->Data[num] = id
+#define GetCaData(descr, num) (((struct CaDescriptor *)descr)->Data[num])
/* StreamIdentifierDescriptor */
@@ -968,6 +1030,122 @@ struct SubtitlingItem {
xAddTail (((struct SubtitlingDescriptor *)desc)->Items, item); \
} while (0)
+/* SatelliteDeliverySystemDescriptor */
+
+struct SatelliteDeliverySystemDescriptor {
+ struct NODE Node;
+ unsigned short Tag;
+ long Frequency;
+ short OrbitalPosition;
+ char Polarization;
+ long SymbolRate;
+ char FEC;
+};
+
+#define CreateSatelliteDeliverySystemDescriptor(descr, freq, orb, polar, sr, fec) \
+ do \
+ { \
+ xCreateNode (((struct SatelliteDeliverySystemDescriptor *)descr), NULL); \
+ ((struct SatelliteDeliverySystemDescriptor *)descr)->Tag = DESCR_SAT_DEL_SYS; \
+ ((struct SatelliteDeliverySystemDescriptor *)descr)->Frequency = freq; \
+ ((struct SatelliteDeliverySystemDescriptor *)descr)->OrbitalPosition = orb; \
+ ((struct SatelliteDeliverySystemDescriptor *)descr)->Polarization = polar; \
+ ((struct SatelliteDeliverySystemDescriptor *)descr)->SymbolRate = sr; \
+ ((struct SatelliteDeliverySystemDescriptor *)descr)->FEC = fec; \
+ } while (0)
+
+/* ServiceListDescriptor */
+
+struct ServiceListDescriptor {
+ struct NODE Node;
+ unsigned short Tag;
+ struct LIST *ServiceList;
+};
+
+#define CreateServiceListDescriptor(descr) \
+ do \
+ { \
+ xCreateNode (((struct ServiceListDescriptor *)descr), NULL); \
+ ((struct ServiceListDescriptor *)descr)->Tag = DESCR_SERVICE_LIST; \
+ ((struct ServiceListDescriptor *)descr)->ServiceList = xNewList(NULL); \
+ } while (0)
+
+struct ServiceListEntry {
+ struct NODE Node;
+ int ServiceID;
+ unsigned short ServiceType;
+};
+
+#define AddServiceListEntry(descr, id, typ) \
+ do \
+ { \
+ struct ServiceListEntry *newent; \
+ \
+ xCreateNode (newent, NULL); \
+ newent->ServiceID = id; \
+ newent->ServiceType = typ; \
+ xAddTail (((struct ServiceListDescriptor *)descr)->ServiceList, newent); \
+ } while (0)
+
+/* LocalTimeOffsetDescriptor */
+
+struct LocalTimeOffsetDescriptor {
+ struct NODE Node;
+ unsigned short Tag;
+ struct LIST *LocalTimeOffsets;
+};
+
+#define CreateLocalTimeOffsetDescriptor(descr) \
+ do \
+ { \
+ xCreateNode (((struct LocalTimeOffsetDescriptor *)descr), NULL); \
+ ((struct LocalTimeOffsetDescriptor *)descr)->Tag = DESCR_LOCAL_TIME_OFF; \
+ ((struct LocalTimeOffsetDescriptor *)descr)->LocalTimeOffsets = xNewList(NULL); \
+ } while (0)
+
+struct LocalTimeOffsetEntry {
+ struct NODE Node;
+ char CountryCode[4];
+ char RegionID;
+ time_t CurrentOffset;
+ time_t ChangeTime;
+ time_t NextOffset;
+};
+
+#define CreateLocalTimeOffsetEntry(newent, code1, code2, code3, reg, co, ct, no) \
+ do \
+ { \
+ xCreateNode (newent, NULL); \
+ newent->CountryCode[0] = code1; \
+ newent->CountryCode[1] = code2; \
+ newent->CountryCode[2] = code3; \
+ newent->CountryCode[3] = '\0'; \
+ newent->RegionID = reg; \
+ newent->CurrentOffset = co; \
+ newent->ChangeTime = ct; \
+ newent->NextOffset = no; \
+ } while (0)
+
+#define AddLocalTimeOffsetEntry(descr, code1, code2, code3, reg, co, ct, no) \
+ do \
+ { \
+ struct LocalTimeOffsetEntry *newent; \
+ \
+ xCreateNode (newent, NULL); \
+ newent->CountryCode[0] = code1; \
+ newent->CountryCode[1] = code2; \
+ newent->CountryCode[2] = code3; \
+ newent->CountryCode[3] = '\0'; \
+ newent->RegionID = reg; \
+ newent->CurrentOffset = co; \
+ newent->ChangeTime = ct; \
+ newent->NextOffset = no; \
+ xAddTail (((struct LocalTimeOffsetDescriptor *)descr)->LocalTimeOffsets, newent); \
+ } while (0)
+
+#define timezonecmp(ptoe,cod,reg) \
+ (strncmp(ptoe->CountryCode, cod, 3) || (ptoe->RegionID != reg))
+
/* Prototypes */
@@ -979,13 +1157,17 @@ extern "C" {
/* si_parser.c */
struct LIST *siParsePAT (u_char *);
+struct LIST *siParseCAT (u_char *);
struct Pid *siParsePMT (u_char *);
struct LIST *siParseSDT (u_char *);
+struct LIST *siParseNIT (u_char *);
struct LIST *siParseEIT (u_char *);
time_t siParseTDT (u_char *);
+struct Tot *siParseTOT (u_char *);
void siParseDescriptors (struct LIST *, u_char *, int, u_char);
void siParseDescriptor (struct LIST *, u_char *);
char *siGetDescriptorText (u_char *, int);
+char *siGetDescriptorName (u_char *, int);
u_long crc32 (char *data, int len);
/* si_debug_services.c */
@@ -999,6 +1181,8 @@ void siDebugPids (char *, struct LIST *);
void siDebugDescriptors (char *, struct LIST *);
void siDebugEitServices (struct LIST *);
void siDebugEitEvents (char *, struct LIST *);
+void siDumpDescriptor (void *);
+void siDumpSection (void *);
#ifdef __cplusplus
}
diff --git a/libdtv/libsi/include/si_tables.h b/libdtv/libsi/include/si_tables.h
index dfda3bf9..9da31a0f 100644
--- a/libdtv/libsi/include/si_tables.h
+++ b/libdtv/libsi/include/si_tables.h
@@ -5,11 +5,13 @@
/// ///
//////////////////////////////////////////////////////////////
-// $Revision: 1.3 $
-// $Date: 2001/10/07 10:24:46 $
+// $Revision: 1.4 $
+// $Date: 2003/04/12 11:27:31 $
// $Author: hakenes $
//
-// (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL.
+// (C) 2001-03 Rolf Hakenes <hakenes@hippomi.de>, under the
+// GNU GPL with contribution of Oleg Assovski,
+// www.satmania.com
//
// libsi is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -32,12 +34,22 @@
#define BcdTimeToSeconds(x) ((3600 * ((10*((x##_h & 0xF0)>>4)) + (x##_h & 0xF))) + \
(60 * ((10*((x##_m & 0xF0)>>4)) + (x##_m & 0xF))) + \
((10*((x##_s & 0xF0)>>4)) + (x##_s & 0xF)))
+#define BcdTimeToMinutes(x) ((60 * ((10*((x##_h & 0xF0)>>4)) + (x##_h & 0xF))) + \
+ (((10*((x##_m & 0xF0)>>4)) + (x##_m & 0xF))))
+#define BcdCharToInt(x) (10*((x & 0xF0)>>4) + (x & 0xF))
+#define CheckBcdChar(x) ((((x & 0xF0)>>4) <= 9) && \
+ ((x & 0x0F) <= 9))
+#define CheckBcdSignedChar(x) ((((x & 0xF0)>>4) >= 0) && (((x & 0xF0)>>4) <= 9) && \
+ ((x & 0x0F) >= 0) && ((x & 0x0F) <= 9))
#define TableHasMoreSections(x) (((pat_t *)(x))->last_section_number > ((pat_t *)(x))->section_number)
#define GetTableId(x) ((pat_t *)(x))->table_id
#define GetSectionNumber(x) ((pat_t *)(x))->section_number
#define GetLastSectionNumber(x) ((pat_t *)(x))->last_section_number
#define GetServiceId(x) (((eit_t *)(x))->service_id_hi << 8) | ((eit_t *)(x))->service_id_lo
+#define GetSegmentLastSectionNumber(x) ((eit_t *)(x))->segment_last_section_number
+#define GetLastTableId(x) ((eit_t *)(x))->segment_last_table_id
+#define GetSectionLength(x) HILO(((pat_t *)(x))->section_length)
/*
*
@@ -113,7 +125,37 @@ typedef struct {
* applicable.
*
*/
- /* TO BE DONE */
+#define CAT_LEN 8
+
+typedef struct {
+ u_char table_id :8;
+#if BYTE_ORDER == BIG_ENDIAN
+ u_char section_syntax_indicator :1;
+ u_char dummy :1; // has to be 0
+ u_char :2;
+ u_char section_length_hi :4;
+#else
+ u_char section_length_hi :4;
+ u_char :2;
+ u_char dummy :1; // has to be 0
+ u_char section_syntax_indicator :1;
+#endif
+ u_char section_length_lo :8;
+ u_char reserved_1 :8;
+ u_char reserved_2 :8;
+#if BYTE_ORDER == BIG_ENDIAN
+ u_char :2;
+ u_char version_number :5;
+ u_char current_next_indicator :1;
+#else
+ u_char current_next_indicator :1;
+ u_char version_number :5;
+ u_char :2;
+#endif
+ u_char section_number :8;
+ u_char last_section_number :8;
+} cat_t;
+
/*
*
* 3) Program Map Table (PMT):
@@ -297,7 +339,7 @@ typedef struct {
* bouquet.
*
*/
- /* TO BE DONE */
+/* SEE NIT (It has the same structure but has different allowed descriptors) */
/*
*
* 2) Service Description Table (SDT):
@@ -339,6 +381,9 @@ typedef struct {
u_char :8;
} sdt_t;
+#define GetSDTTransportStreamId(x) (HILO(((sdt_t *) x)->transport_stream_id))
+#define GetSDTOriginalNetworkId(x) (HILO(((sdt_t *) x)->original_network_id))
+
#define SDT_DESCR_LEN 5
typedef struct {
@@ -483,7 +528,36 @@ typedef struct {
* to the frequent updating of the time information.
*
*/
- /* TO BE DONE */
+#define TOT_LEN 10
+
+typedef struct {
+ u_char table_id :8;
+#if BYTE_ORDER == BIG_ENDIAN
+ u_char section_syntax_indicator :1;
+ u_char :3;
+ u_char section_length_hi :4;
+#else
+ u_char section_length_hi :4;
+ u_char :3;
+ u_char section_syntax_indicator :1;
+#endif
+ u_char section_length_lo :8;
+ u_char utc_mjd_hi :8;
+ u_char utc_mjd_lo :8;
+ u_char utc_time_h :8;
+ u_char utc_time_m :8;
+ u_char utc_time_s :8;
+#if BYTE_ORDER == BIG_ENDIAN
+ u_char :4;
+ u_char descriptors_loop_length_hi :4;
+#else
+ u_char descriptors_loop_length_hi :4;
+ u_char :4;
+#endif
+ u_char descriptors_loop_length_lo :8;
+} tot_t;
+
+
/*
*
* 7) Stuffing Table (ST):
@@ -545,6 +619,25 @@ typedef struct descr_gen_struct {
#define GetDescriptorLength(x) (((descr_gen_t *) x)->descriptor_length+DESCR_GEN_LEN)
+/* 0x09 ca_descriptor */
+
+#define DESCR_CA_LEN 6
+typedef struct descr_ca_struct {
+ u_char descriptor_tag :8;
+ u_char descriptor_length :8;
+ u_char CA_type_hi :8;
+ u_char CA_type_lo :8;
+#if BYTE_ORDER == BIG_ENDIAN
+ u_char reserved :3;
+ u_char CA_PID_hi :5;
+#else
+ u_char CA_PID_hi :5;
+ u_char reserved :3;
+#endif
+ u_char CA_PID_lo :8;
+} descr_ca_t;
+#define CastCaDescriptor(x) ((descr_ca_t *)(x))
+
/* 0x0A iso_639_language_descriptor */
#define DESCR_ISO_639_LANGUAGE_LEN 5
@@ -560,25 +653,31 @@ typedef struct descr_iso_639_language_struct {
/* 0x40 network_name_descriptor */
-#define DESCR_NETWORK_NAME_LEN XX
+#define DESCR_NETWORK_NAME_LEN 2
typedef struct descr_network_name_struct {
u_char descriptor_tag :8;
u_char descriptor_length :8;
- /* TBD */
} descr_network_name_t;
#define CastNetworkNameDescriptor(x) ((descr_network_name_t *)(x))
/* 0x41 service_list_descriptor */
-#define DESCR_SERVICE_LIST_LEN XX
+#define DESCR_SERVICE_LIST_LEN 2
typedef struct descr_service_list_struct {
u_char descriptor_tag :8;
u_char descriptor_length :8;
- /* TBD */
} descr_service_list_t;
#define CastServiceListDescriptor(x) ((descr_service_list_t *)(x))
+#define DESCR_SERVICE_LIST_LOOP_LEN 3
+typedef struct descr_service_list_loop_struct {
+ u_char service_id_hi :8;
+ u_char service_id_lo :8;
+ u_char service_type :8;
+} descr_service_list_loop_t;
+#define CastServiceListDescriptorLoop(x) ((descr_service_list_loop_t *)(x))
+
/* 0x42 stuffing_descriptor */
@@ -604,13 +703,13 @@ typedef struct descr_satellite_delivery_system_struct {
u_char orbital_position1 :8;
u_char orbital_position2 :8;
#if BYTE_ORDER == BIG_ENDIAN
- u_char modulation :5;
- u_char polarization :2;
- u_char west_east_flag :1;
-#else
u_char west_east_flag :1;
u_char polarization :2;
u_char modulation :5;
+#else
+ u_char modulation :5;
+ u_char polarization :2;
+ u_char west_east_flag :1;
#endif
u_char symbol_rate1 :8;
u_char symbol_rate2 :8;
@@ -964,14 +1063,39 @@ typedef struct descr_telephone_struct {
/* 0x58 local_time_offset_descriptor */
-#define DESCR_LOCAL_TIME_OFFSET_LEN XX
+#define DESCR_LOCAL_TIME_OFFSET_LEN 2
typedef struct descr_local_time_offset_struct {
u_char descriptor_tag :8;
u_char descriptor_length :8;
- /* TBD */
} descr_local_time_offset_t;
#define CastLocalTimeOffsetDescriptor(x) ((descr_local_time_offset_t *)(x))
+#define LOCAL_TIME_OFFSET_ENTRY_LEN 15
+typedef struct local_time_offset_entry_struct {
+ u_char country_code1 :8;
+ u_char country_code2 :8;
+ u_char country_code3 :8;
+#if BYTE_ORDER == BIG_ENDIAN
+ u_char country_region_id :6;
+ u_char :1;
+ u_char local_time_offset_polarity :1;
+#else
+ u_char local_time_offset_polarity :1;
+ u_char :1;
+ u_char country_region_id :6;
+#endif
+ u_char local_time_offset_h :8;
+ u_char local_time_offset_m :8;
+ u_char time_of_change_mjd_hi :8;
+ u_char time_of_change_mjd_lo :8;
+ u_char time_of_change_time_h :8;
+ u_char time_of_change_time_m :8;
+ u_char time_of_change_time_s :8;
+ u_char next_time_offset_h :8;
+ u_char next_time_offset_m :8;
+} local_time_offset_entry_t ;
+#define CastLocalTimeOffsetEntry(x) ((local_time_offset_entry_t *)(x))
+
/* 0x59 subtitling_descriptor */
diff --git a/libdtv/libsi/si_debug_services.c b/libdtv/libsi/si_debug_services.c
index ae2a92a6..ac8de34c 100644
--- a/libdtv/libsi/si_debug_services.c
+++ b/libdtv/libsi/si_debug_services.c
@@ -4,11 +4,13 @@
/// ///
//////////////////////////////////////////////////////////////
-// $Revision: 1.4 $
-// $Date: 2001/10/07 10:24:46 $
+// $Revision: 1.5 $
+// $Date: 2003/02/04 18:45:35 $
// $Author: hakenes $
//
-// (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL.
+// (C) 2001-03 Rolf Hakenes <hakenes@hippomi.de>, under the
+// GNU GPL with contribution of Oleg Assovski,
+// www.satmania.com
//
// libsi is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -26,11 +28,13 @@
// Boston, MA 02111-1307, USA.
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "../liblx/liblx.h"
#include "libsi.h"
+#include "si_tables.h"
#include "si_debug_services.h"
@@ -208,6 +212,8 @@ void siDebugPids (char *Prepend, struct LIST *PidList)
printf ("%s ProgramID: %d\n", Prepend, Pid->ProgramID);
printf ("%s PcrPid: %d\n", Prepend, Pid->PcrPID);
printf ("%s PmtVersion: %d\n", Prepend, Pid->PmtVersion);
+ sprintf (NewPrepend, "%s ", Prepend);
+ siDebugDescriptors (NewPrepend, Pid->Descriptors);
xForeach (Pid->InfoList, PidInfo)
{
@@ -256,6 +262,11 @@ void siDebugDescriptors (char *Prepend, struct LIST *Descriptors)
printf ("\n");
break;
+ case DESCR_NW_NAME:
+ printf ("%sDescriptor: Network Name\n", Prepend);
+ printf ("%s Name: %s\n", Prepend, xName (Descriptor));
+ break;
+
case DESCR_BOUQUET_NAME:
printf ("%sDescriptor: Bouquet Name\n", Prepend);
printf ("%s Name: %s\n", Prepend, xName (Descriptor));
@@ -336,12 +347,38 @@ void siDebugDescriptors (char *Prepend, struct LIST *Descriptors)
case DESCR_CA_IDENT:
printf ("%sDescriptor: Conditional Access Identity\n", Prepend);
{
- int j;
+ int j,k;
for (j = 0; j < ((struct CaIdentifierDescriptor *)Descriptor)->Amount; j++)
- printf ("%s SystemID: 0x%04x\n", Prepend, GetCaIdentifierID (Descriptor, j));
+ {
+ printf ("%s SystemID: 0x%04x", Prepend, GetCaIdentifierID (Descriptor, j));
+ k = GetCaIdentifierID (Descriptor, j) >> 8;
+ if (k < 0 || k > MAX_CA_IDENT) printf (" (unknown)\n");
+ else printf (" (%s)\n", CaIdents[k]);
+ }
}
break;
+ case DESCR_CA:
+ {
+ int j,k;
+
+ printf ("%sDescriptor: Conditional Access\n", Prepend);
+ printf ("%s CA type: 0x%04x", Prepend, (((struct CaDescriptor *)Descriptor)->CA_type));
+ k = (((struct CaDescriptor *)Descriptor)->CA_type) >> 8;
+ if (k < 0 || k > MAX_CA_IDENT) printf (" (unknown)\n");
+ else printf (" (%s)\n", CaIdents[k]);
+ printf ("%s CA PID: %d\n", Prepend, (((struct CaDescriptor *)Descriptor)->CA_PID));
+ printf ("%s ProviderID: 0x%04X\n", Prepend, (((struct CaDescriptor *)Descriptor)->ProviderID));
+ if (((struct CaDescriptor *)Descriptor)->DataLength > 0)
+ {
+ printf ("%s CA data:", Prepend);
+ for (j = 0; j < ((struct CaDescriptor *)Descriptor)->DataLength; j++)
+ printf (" 0x%02x", GetCaData (Descriptor, j));
+ printf ("\n");
+ }
+ }
+ break;
+
case DESCR_CONTENT:
printf ("%sDescriptor: Content\n", Prepend);
{
@@ -489,16 +526,57 @@ void siDebugDescriptors (char *Prepend, struct LIST *Descriptors)
}
break;
- case DESCR_NW_NAME:
+ case DESCR_SAT_DEL_SYS:
+ {
+ struct SatelliteDeliverySystemDescriptor *sds =
+ (struct SatelliteDeliverySystemDescriptor *)Descriptor;
+
+ printf ("%sDescriptor: Satellite Delivery System\n", Prepend);
+ printf ("%s Frequency: %ld\n", Prepend, sds->Frequency);
+ printf ("%s OrbitalPosition: %d\n", Prepend, sds->OrbitalPosition);
+ printf ("%s Polarization: %c\n", Prepend, sds->Polarization);
+ printf ("%s SymbolRate: %ld\n", Prepend, sds->SymbolRate);
+ printf ("%s FEC: %c\n", Prepend, sds->FEC);
+ }
+ break;
+
case DESCR_SERVICE_LIST:
+ {
+ struct ServiceListEntry *Entry;
+
+ printf ("%sDescriptor: Service List\n", Prepend);
+ xForeach (((struct ServiceListDescriptor *)Descriptor)->ServiceList, Entry)
+ {
+ printf ("%s Entry:\n");
+ printf ("%s ServiceID: %d\n", Prepend, Entry->ServiceID);
+ printf ("%s ServiceType: %04x\n", Prepend, Entry->ServiceType);
+ }
+ }
+ break;
+
+ case DESCR_LOCAL_TIME_OFF:
+ {
+ struct LocalTimeOffsetEntry *Offset;
+
+ printf ("%sDescriptor: Local Time Offset\n", Prepend);
+ xForeach (((struct LocalTimeOffsetDescriptor *)Descriptor)->LocalTimeOffsets, Offset)
+ {
+ printf ("%s Offset:\n");
+ printf ("%s CountryCode: %s\n", Offset->CountryCode);
+ printf ("%s RegionID: %c\n", Offset->RegionID);
+ printf ("%s CurrentOffset: %ld\n", Offset->CurrentOffset);
+ printf ("%s ChangeTime: %ld\n", Offset->ChangeTime);
+ printf ("%s NextOffset: %ld\n", Offset->NextOffset);
+ }
+ }
+ break;
+
case DESCR_STUFFING:
- case DESCR_SAT_DEL_SYS:
case DESCR_CABLE_DEL_SYS:
case DESCR_VBI_DATA:
case DESCR_VBI_TELETEXT:
case DESCR_MOSAIC:
case DESCR_TELEPHONE:
- case DESCR_LOCAL_TIME_OFF:
case DESCR_TERR_DEL_SYS:
case DESCR_ML_NW_NAME:
case DESCR_ML_BQ_NAME:
@@ -527,3 +605,39 @@ void siDebugDescriptors (char *Prepend, struct LIST *Descriptors)
return;
}
+void siDumpDescriptor (void * Descriptor)
+{
+ int Length, i;
+ unsigned char *ptr;
+
+ Length = GetDescriptorLength (Descriptor);
+ for (i = 0, ptr = (char*) Descriptor; i < Length; i++) {
+ if ((i % 8) == 0)
+ printf ("\n");
+ printf ("0x%02X ", (unsigned int) ptr[i]);
+ }
+ printf ( "\n");
+}
+
+void siDumpSection (void *Section)
+{
+ int Length, i;
+ unsigned char *ptr;
+ char str[9];
+
+ Length = GetSectionLength (Section) + 3;
+ for (i = 0, ptr = (unsigned char*) Section, memset (str, 0, 9); i < Length; i++) {
+ if ((i % 8) == 0)
+ {
+ printf (" %s\n", str);
+ memset (str, 0, 8);
+ }
+ printf ("0x%02X ", (unsigned int) ptr[i]);
+ if (ptr[i] < 0x20 || (ptr[i] > 'z' && ptr[i] < ((unsigned char )'Ā')) )
+ str[i % 8] = '.';
+ else
+ str[i % 8] = ptr[i];
+ }
+ printf (" %*s\n", (8 - ((abs(i - 1) % 8) ? (abs(i - 1) % 8) : 8)) * 5, str);
+}
+
diff --git a/libdtv/libsi/si_debug_services.h b/libdtv/libsi/si_debug_services.h
index d33b0aa7..869c6d04 100644
--- a/libdtv/libsi/si_debug_services.h
+++ b/libdtv/libsi/si_debug_services.h
@@ -4,8 +4,8 @@
/// ///
//////////////////////////////////////////////////////////////
-// $Revision: 1.1 $
-// $Date: 2001/08/15 10:00:00 $
+// $Revision: 1.2 $
+// $Date: 2003/04/12 11:27:31 $
// $Author: hakenes $
//
// (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL.
@@ -197,7 +197,7 @@ static struct content_type ContentTypes[] = {
};
#define CONTENT_TYPE_NUMBER 79
-static char StreamTypes[][70] = {
+static char *StreamTypes[] = {
"ITU-T|ISO/IEC Reserved",
"ISO/IEC Video",
"13818-2 Video or 11172-2 constrained parameter video stream",
@@ -215,3 +215,31 @@ static char StreamTypes[][70] = {
"ITU-T Rec. H.222.0 | ISO 13818-1 Reserved",
"User private"
};
+
+static char *CaIdents[] = {
+ "Standardized systems",
+ "Canal Plus",
+ "CCETT",
+ "Deutsche Telecom",
+ "Eurodec",
+ "France Telecom",
+ "Irdeto",
+ "Jerrold/GI",
+ "Matra Communication",
+ "News Datacom",
+ "Nokia",
+ "Norwegian Telekom",
+ "NTL",
+ "Philips",
+ "Scientific Atlanta",
+ "Sony",
+ "Tandberg Television",
+ "Thomson",
+ "TV/Com",
+ "HPT - Croatian Post and Telecommunications",
+ "HRT - Croatian Radio and Television",
+ "IBM",
+ "Nera",
+ "BetaTechnik"
+};
+#define MAX_CA_IDENT 24
diff --git a/libdtv/libsi/si_parser.c b/libdtv/libsi/si_parser.c
index ccca6e5e..e8cf8b21 100644
--- a/libdtv/libsi/si_parser.c
+++ b/libdtv/libsi/si_parser.c
@@ -4,11 +4,13 @@
/// ///
//////////////////////////////////////////////////////////////
-// $Revision: 1.6 $
-// $Date: 2002/01/30 17:04:13 $
+// $Revision: 1.8 $
+// $Date: 2003/02/04 18:45:35 $
// $Author: hakenes $
//
-// (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL.
+// (C) 2001-03 Rolf Hakenes <hakenes@hippomi.de>, under the
+// GNU GPL with contribution of Oleg Assovski,
+// www.satmania.com
//
// libsi is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -52,7 +54,7 @@ struct LIST *siParsePAT (u_char *Buffer)
Pat = (pat_t *) Buffer; Ptr = Buffer;
if (Pat->table_id != TID_PAT) {
-// fprintf (stderr, "PAT: wrong TID %d\n", Pat->table_id);
+ // fprintf (stderr, "PAT: wrong TID %d\n", Pat->table_id);
return NULL;
}
@@ -83,6 +85,43 @@ struct LIST *siParsePAT (u_char *Buffer)
}
+struct LIST *siParseCAT (u_char *Buffer)
+{
+ cat_t *Cat;
+ u_char *Ptr;
+ int SectionLength;
+ int TransportStreamID;
+ int CatVersion;
+ struct Descriptor *Descriptor;
+ struct LIST *DescriptorList = NULL;
+
+ if (!Buffer) return NULL;
+
+ Cat = (cat_t *) Buffer; Ptr = Buffer;
+
+ if (Cat->table_id != TID_CAT) {
+ // fprintf (stderr, "CAT: wrong TID %d\n", Cat->table_id);
+ return NULL;
+ }
+
+ SectionLength = HILO (Cat->section_length) + 3 - CAT_LEN - 4;
+
+ if (crc32 (Ptr, HILO (Cat->section_length) + 3)) return (NULL);
+
+ CatVersion = Cat->version_number;
+
+ Ptr += CAT_LEN;
+
+ if (SectionLength >= 0)
+ {
+ DescriptorList = xNewList (NULL);
+ siParseDescriptors (DescriptorList, Ptr, SectionLength, Cat->table_id);
+ }
+
+ return (DescriptorList);
+}
+
+
struct Pid *siParsePMT (u_char *Buffer)
{
pmt_t *Pmt;
@@ -101,7 +140,7 @@ struct Pid *siParsePMT (u_char *Buffer)
Pmt = (pmt_t *) Buffer; Ptr = Buffer;
if (Pmt->table_id != TID_PMT) {
-// fprintf (stderr, "PMT: wrong TID %d\n", Pmt->table_id);
+ // fprintf (stderr, "PMT: wrong TID %d\n", Pmt->table_id);
return NULL;
}
@@ -147,6 +186,89 @@ struct Pid *siParsePMT (u_char *Buffer)
}
+struct LIST *siParseNIT (u_char *Buffer)
+{
+ nit_t *Nit;
+ nit_mid_t *NitMid;
+ nit_ts_t *TSDesc;
+ u_char *Ptr;
+ int SectionLength, LoopLength, Loop2Length;
+ int TransportStreamID;
+ int NitVersion;
+ int NetworkID;
+ struct TransportStream *TransportStream;
+ struct LIST *TSList = NULL;
+ struct LIST *Networks;
+ struct NetworkInfo *Network;
+
+ if (!Buffer) return NULL;
+
+ Nit = (nit_t *) Buffer;
+ Ptr = Buffer;
+
+ if (Nit->table_id != TID_NIT_ACT && Nit->table_id != TID_NIT_OTH && Nit->table_id != TID_BAT) {
+ return NULL;
+ }
+
+ SectionLength = HILO (Nit->section_length) + 3 - NIT_LEN - 4;
+
+ if (crc32 (Ptr, HILO (Nit->section_length) + 3)) return (NULL);
+
+ NitVersion = Nit->version_number;
+ NetworkID = HILO (Nit->network_id);
+ if (NetworkID == 65535)
+ NetworkID = 0;
+ CreateNetworkInfo (Network, NetworkID);
+ Networks = xNewList (NULL);
+ xAddTail (Networks, Network);
+
+ Ptr += NIT_LEN;
+
+ LoopLength = HILO (Nit->network_descriptor_length);
+// fprintf (stderr, "table 0x%X, SectionLen = %d, LoopLen = %d\n",
+// Nit->table_id, SectionLength, LoopLength);
+ if (LoopLength > SectionLength - SDT_DESCR_LEN)
+ return (Networks);
+
+ if (LoopLength <= SectionLength) {
+ if (SectionLength >= 0) siParseDescriptors (Network->Descriptors, Ptr, LoopLength, Nit->table_id);
+ SectionLength -= LoopLength;
+ Ptr += LoopLength;
+ NitMid = (nit_mid_t *) Ptr;
+ LoopLength = HILO (NitMid->transport_stream_loop_length);
+// fprintf (stderr, "table 0x%X, TS LoopLen = %d\n",
+// Nit->table_id, LoopLength);
+ if ((SectionLength > 0) && (LoopLength <= SectionLength)) {
+ SectionLength -= SIZE_NIT_MID;
+ Ptr += SIZE_NIT_MID;
+ while (LoopLength > 0) {
+ TSDesc = (nit_ts_t *) Ptr;
+ CreateTransportStream (TransportStream, HILO(TSDesc->transport_stream_id), HILO(TSDesc->original_network_id));
+ if (TransportStream->TransportStreamID == 65535)
+ TransportStream->TransportStreamID = 0;
+ if (TransportStream->OriginalNetworkID == 65535)
+ TransportStream->OriginalNetworkID = 0;
+ Loop2Length = HILO (TSDesc->transport_descriptors_length);
+// fprintf (stderr, "table 0x%X, TSdesc LoopLen = %d\n",
+// Nit->table_id, Loop2Length);
+ Ptr += NIT_TS_LEN;
+ if (Loop2Length <= LoopLength) {
+ if (LoopLength >= 0) siParseDescriptors (TransportStream->Descriptors, Ptr, Loop2Length, Nit->table_id);
+ }
+ if (!Network->TransportStreams)
+ Network->TransportStreams = xNewList (NULL);
+ xAddTail (Network->TransportStreams, TransportStream);
+ LoopLength -= Loop2Length + NIT_TS_LEN;
+ SectionLength -= Loop2Length + NIT_TS_LEN;
+ Ptr += Loop2Length;
+ }
+ }
+ }
+
+ return (Networks);
+}
+
+
struct LIST *siParseSDT (u_char *Buffer)
{
sdt_t *Sdt;
@@ -164,7 +286,7 @@ struct LIST *siParseSDT (u_char *Buffer)
Sdt = (sdt_t *) Buffer; Ptr = Buffer;
if (Sdt->table_id != TID_SDT_ACT && Sdt->table_id != TID_SDT_OTH) {
-// fprintf (stderr, "SDT: wrong TID %d\n", Sdt->table_id);
+ // fprintf (stderr, "SDT: wrong TID %d\n", Sdt->table_id);
return NULL;
}
@@ -250,7 +372,7 @@ struct LIST *siParseEIT (u_char *Buffer)
Eit->table_id <= TID_EIT_ACT_SCH + 0x0F) &&
!(Eit->table_id >= TID_EIT_OTH_SCH &&
Eit->table_id <= TID_EIT_OTH_SCH + 0x0F)) {
-// fprintf (stderr, "EIT: wrong TID %d\n", Eit->table_id);
+ // fprintf (stderr, "EIT: wrong TID %d\n", Eit->table_id);
return NULL;
}
@@ -331,7 +453,7 @@ time_t siParseTDT (u_char *Buffer)
Tdt = (tdt_t *) Buffer; Ptr = Buffer;
if (Tdt->table_id != TID_TDT) {
-// fprintf (stderr, "TDT: wrong TID %d\n", Tdt->table_id);
+ // fprintf (stderr, "TDT: wrong TID %d\n", Tdt->table_id);
return 0;
}
@@ -344,6 +466,44 @@ time_t siParseTDT (u_char *Buffer)
}
+struct Tot *siParseTOT (u_char *Buffer)
+{
+ tot_t *Tot;
+ u_char *Ptr;
+ int SectionLength, LoopLength;
+ struct Tot *table;
+ time_t CurrentTime;
+
+ if (!Buffer) return NULL;
+
+ Tot = (tot_t *) Buffer;
+ Ptr = Buffer;
+
+ if (Tot->table_id != TID_TOT) {
+ return NULL;
+ }
+
+ if (crc32 (Ptr, HILO (Tot->section_length) + 3)) return (NULL);
+// SectionLength = HILO (Tot->section_length) + 3 - TOT_LEN - 4;
+
+ CurrentTime = MjdToEpochTime (Tot->utc_mjd) +
+ BcdTimeToSeconds (Tot->utc_time);
+ LoopLength = HILO (Tot->descriptors_loop_length);
+ if (!LoopLength)
+ return NULL;
+
+ CreateTot (table, CurrentTime);
+
+ Ptr += TOT_LEN;
+
+ siParseDescriptors (table->Descriptors, Ptr, LoopLength, Tot->table_id);
+
+ // fprintf (stderr, "TOT Bias: %d\n", table->Bias);
+ return (table);
+}
+
+static u_char TempTableID = 0;
+
void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
int Length, u_char TableID)
{
@@ -352,6 +512,7 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
DescriptorLength = 0;
Ptr = Buffer;
+ TempTableID = TableID;
while (DescriptorLength < Length)
{
@@ -362,15 +523,17 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
case TID_NIT_ACT: case TID_NIT_OTH:
switch (GetDescriptorTag(Ptr))
{
- case DESCR_NW_NAME:
- case DESCR_SERVICE_LIST:
- case DESCR_STUFFING:
case DESCR_SAT_DEL_SYS:
case DESCR_CABLE_DEL_SYS:
+ case DESCR_SERVICE_LIST:
+ case DESCR_PRIV_DATA_SPEC:
+// fprintf (stderr, "Got descriptor with tag = 0x%X\n", GetDescriptorTag(Ptr));
+// siDumpDescriptor (Ptr);
+ case DESCR_NW_NAME:
+ case DESCR_STUFFING:
case DESCR_LINKAGE:
case DESCR_TERR_DEL_SYS:
case DESCR_ML_NW_NAME:
- case DESCR_PRIV_DATA_SPEC:
case DESCR_CELL_LIST:
case DESCR_CELL_FREQ_LINK:
case DESCR_ANNOUNCEMENT_SUPPORT:
@@ -378,8 +541,7 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
break;
default:
- /* fprintf (stderr, "forbidden descriptor 0x%x in NIT\n",
- GetDescriptorTag(Ptr));*/
+ // fprintf (stderr, "forbidden descriptor 0x%x in NIT\n", GetDescriptorTag(Ptr));
break;
}
break;
@@ -396,12 +558,12 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
case DESCR_CA_IDENT:
case DESCR_ML_BQ_NAME:
case DESCR_PRIV_DATA_SPEC:
+ // fprintf (stderr, "Got descriptor with tag = 0x%X\n", GetDescriptorTag(Ptr));
siParseDescriptor (Descriptors, Ptr);
break;
default:
- /*fprintf (stderr, "forbidden descriptor 0x%x in BAT\n",
- GetDescriptorTag(Ptr));*/
+ // fprintf (stderr, "forbidden descriptor 0x%x in BAT\n", GetDescriptorTag(Ptr));
break;
}
break;
@@ -426,8 +588,7 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
break;
default:
- /* fprintf (stderr, "forbidden descriptor 0x%x in SDT\n",
- GetDescriptorTag(Ptr)); */
+ // fprintf (stderr, "forbidden descriptor 0x%x in SDT\n", GetDescriptorTag(Ptr));
break;
}
break;
@@ -470,8 +631,7 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
break;
default:
- /*fprintf (stderr, "forbidden descriptor 0x%x in EIT\n",
- GetDescriptorTag(Ptr));*/
+ // fprintf (stderr, "forbidden descriptor 0x%x in EIT\n", GetDescriptorTag(Ptr));
break;
}
break;
@@ -484,8 +644,7 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
break;
default:
- /*fprintf (stderr, "forbidden descriptor 0x%x in TOT\n",
- GetDescriptorTag(Ptr));*/
+ // fprintf (stderr, "forbidden descriptor 0x%x in TOT\n", GetDescriptorTag(Ptr));
break;
}
break;
@@ -522,15 +681,28 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
break;
default:
- /* fprintf (stderr, "forbidden descriptor 0x%x in PMT\n",
- GetDescriptorTag(Ptr)); */
+ // fprintf (stderr, "forbidden descriptor 0x%x in PMT\n", GetDescriptorTag(Ptr));
+ break;
+ }
+ break;
+
+ case TID_CAT:
+ switch (GetDescriptorTag(Ptr))
+ {
+ case DESCR_CA_SYSTEM:
+ case DESCR_CA:
+ case DESCR_CA_IDENT:
+ siParseDescriptor (Descriptors, Ptr);
+ break;
+
+ default:
+ // fprintf (stderr, "forbidden descriptor 0x%x in CAT\n", GetDescriptorTag(Ptr));
break;
}
break;
default:
- fprintf (stderr, "descriptor 0x%x in unsupported table 0x%x\n",
- GetDescriptorTag(Ptr), TableID);
+ // fprintf (stderr, "descriptor 0x%x in unsupported table 0x%x\n", GetDescriptorTag(Ptr), TableID);
break;
}
DescriptorLength += GetDescriptorLength (Ptr);
@@ -550,6 +722,7 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
if (!Descriptors || !Buffer) return;
Ptr = Buffer;
+// fprintf (stderr, "Got descriptor with tag = 0x%X\n", GetDescriptorTag(Buffer));
switch (GetDescriptorTag(Buffer))
{
@@ -558,10 +731,12 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
CastAncillaryDataDescriptor(Buffer)->ancillary_data_identifier);
break;
+ case DESCR_NW_NAME:
case DESCR_BOUQUET_NAME:
- Text = siGetDescriptorText (Buffer + DESCR_BOUQUET_NAME_LEN,
+ Text = siGetDescriptorName (Buffer + DESCR_BOUQUET_NAME_LEN,
GetDescriptorLength (Buffer) - DESCR_BOUQUET_NAME_LEN);
- CreateBouquetNameDescriptor (Descriptor, Text);
+// fprintf (stderr, "Got descriptor with tag = 0x%X, text = '%s'\n", GetDescriptorTag(Buffer), Text);
+ CreateBouquetNameDescriptor (Descriptor, Text, GetDescriptorTag(Buffer));
break;
case DESCR_COMPONENT:
@@ -577,9 +752,9 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
break;
case DESCR_SERVICE:
- Text = siGetDescriptorText (Buffer + DESCR_SERVICE_LEN,
+ Text = siGetDescriptorName (Buffer + DESCR_SERVICE_LEN,
CastServiceDescriptor(Buffer)->provider_name_length);
- Text2 = siGetDescriptorText (Buffer + DESCR_SERVICE_LEN +
+ Text2 = siGetDescriptorName (Buffer + DESCR_SERVICE_LEN +
CastServiceDescriptor(Buffer)->provider_name_length + 1,
*((u_char *)(Buffer + DESCR_SERVICE_LEN +
CastServiceDescriptor(Buffer)->provider_name_length)));
@@ -598,7 +773,7 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
break;
case DESCR_SHORT_EVENT:
- Text = siGetDescriptorText (Buffer + DESCR_SHORT_EVENT_LEN,
+ Text = siGetDescriptorName (Buffer + DESCR_SHORT_EVENT_LEN,
CastShortEventDescriptor(Buffer)->event_name_length);
Text2 = siGetDescriptorText (Buffer + DESCR_SHORT_EVENT_LEN +
CastShortEventDescriptor(Buffer)->event_name_length + 1,
@@ -623,6 +798,7 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
CastExtendedEventDescriptor(Buffer)->lang_code3, Text);
Length = CastExtendedEventDescriptor(Buffer)->length_of_items;
Ptr += DESCR_EXTENDED_EVENT_LEN;
+// printf ("EEDesc #%d, %s\n", CastExtendedEventDescriptor(Buffer)->descriptor_number, Text);
while ((Length > 0) && (Length < GetDescriptorLength (Buffer)))
{
Text = siGetDescriptorText (Ptr + ITEM_EXTENDED_EVENT_LEN,
@@ -631,6 +807,7 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
CastExtendedEventItem(Ptr)->item_description_length + 1,
*((u_char *)(Ptr + ITEM_EXTENDED_EVENT_LEN +
CastExtendedEventItem(Ptr)->item_description_length)));
+// printf ("EEItem #%d, %s, %s\n", CastExtendedEventDescriptor(Buffer)->descriptor_number, Text, Text2);
AddExtendedEventItem (Descriptor, Text2, Text);
Length -= ITEM_EXTENDED_EVENT_LEN + CastExtendedEventItem(Ptr)->item_description_length +
*((u_char *)(Ptr + ITEM_EXTENDED_EVENT_LEN +
@@ -642,15 +819,85 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
break;
case DESCR_CA_IDENT:
- CreateCaIdentifierDescriptor (Descriptor,
- (GetDescriptorLength(Buffer) - DESCR_CA_IDENTIFIER_LEN) / 2);
Length = GetDescriptorLength (Buffer) - DESCR_CA_IDENTIFIER_LEN;
+ CreateCaIdentifierDescriptor (Descriptor, Length / 2);
Ptr += DESCR_CA_IDENTIFIER_LEN; i = 0;
while (Length > 0)
- { SetCaIdentifierID(Descriptor, i, *((u_short *) Ptr));
+ { SetCaIdentifierID(Descriptor, i, ((*((u_char *) Ptr)<<8) + *((u_char *) (Ptr+1))));
Length -= 2; Ptr += 2; i++; }
break;
+ case DESCR_CA:
+ {
+ struct CaDescriptor *CD;
+
+ Length = GetDescriptorLength (Buffer) - DESCR_CA_LEN;
+ CreateCaDescriptor (Descriptor,
+ HILO(CastCaDescriptor(Buffer)->CA_type),
+ HILO(CastCaDescriptor(Buffer)->CA_PID), Length);
+ Ptr += DESCR_CA_LEN; i = 0;
+ while (Length > 0)
+ { SetCaData(Descriptor, i, *Ptr);
+ Length --; Ptr ++; i++; }
+
+ /*
+ * The following analyses are more or less directly copied from
+ * MultiDec 8.4b Sources. Thanx to Espresso for his great work !!
+ */
+ CD = (struct CaDescriptor *) Descriptor;
+
+ // fprintf (stderr, "TableID: %02x - CA - Type: 0x%04x, PID: %d\n", TempTableID, CD->CA_type, CD->CA_PID);
+
+ if ((CD->CA_type >> 8) == 0x01) /* SECA */
+ {
+ CD->ProviderID = (GetCaData (CD, 0) << 8) | GetCaData (CD, 1);
+ }
+ else if ((CD->CA_type >> 8) == 0x05) /* Viaccess ? (France Telecom) */
+ {
+ i=0;
+ while (i < CD->DataLength)
+ {
+ if ((GetCaData (CD, i) == 0x14) && (GetCaData (CD, i+1) == 0x03))
+ {
+ CD->ProviderID = (GetCaData (CD, i+2) << 16) |
+ (GetCaData (CD, i+3) << 8) |
+ (GetCaData (CD, i+4) & 0xf0);
+ i = CD->DataLength;
+ }
+ i++;
+ }
+ }
+ if (CD->CA_type==0x0100) /* SECA 1 */
+ {
+ /* bptr=MyPtr+19;
+
+ i=19;
+ while ( i+4 < ca_info->len ) {
+ if ( (*bptr&0xE0) == 0xE0 ) {
+ CA_ECM=(( *bptr&0x1f)<<8)+*(bptr+1);
+ Prov_Ident = ( *(bptr+2)<<8) | *(bptr+3);
+ j=0;
+ while ( j < ProgrammNeu[ProgrammNummer].CA_Anzahl ) {
+ if (( ProgrammNeu[ProgrammNummer].CA_System[j].CA_Typ == CA_Typ )
+ && ( ProgrammNeu[ProgrammNummer].CA_System[j].ECM == CA_ECM )) break;
+ j++;
+ };
+
+ if ( j < MAX_CA_SYSTEMS ) {
+ if ( j >= ProgrammNeu[ProgrammNummer].CA_Anzahl )
+ ProgrammNeu[ProgrammNummer].CA_Anzahl++;
+ ProgrammNeu[ProgrammNummer].CA_System[j].CA_Typ =CA_Typ;
+ ProgrammNeu[ProgrammNummer].CA_System[j].ECM =CA_ECM ;
+ ProgrammNeu[ProgrammNummer].CA_System[j].Provider_Id = Prov_Ident;
+ };
+ }
+ i+=0x0f;
+ bptr+=0x0f;
+ }; */
+ }
+ }
+ break;
+
case DESCR_CONTENT:
CreateContentDescriptor (Descriptor,
(GetDescriptorLength(Buffer) - DESCR_CONTENT_LEN) / 2);
@@ -705,12 +952,6 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
HILO (CastTimeShiftedEventDescriptor(Ptr)->reference_event_id));
break;
- case DESCR_CA:
- CreateConditionalAccessDescriptor (Descriptor,
- *(Ptr + 1) + 2, // we'll need the entire raw data!
- Ptr);
- break;
-
case DESCR_ISO_639_LANGUAGE:
CreateIso639LanguageDescriptor (Descriptor,
CastIso639LanguageDescriptor(Buffer)->lang_code1,
@@ -789,6 +1030,80 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
}
break;
+ case DESCR_SAT_DEL_SYS:
+// fprintf (stderr, "got descriptor 0x%x\n", GetDescriptorTag(Buffer));
+ {
+ descr_satellite_delivery_system_t *sds;
+ sds = (descr_satellite_delivery_system_t *) Ptr;
+ if (CheckBcdChar (sds->frequency1) && CheckBcdChar (sds->frequency2) &&
+ CheckBcdChar (sds->frequency3) && CheckBcdChar (sds->frequency4) &&
+ CheckBcdChar (sds->orbital_position1) &&
+ CheckBcdChar (sds->orbital_position2) &&
+ CheckBcdChar (sds->symbol_rate1) && CheckBcdChar (sds->symbol_rate1) &&
+ CheckBcdChar (sds->symbol_rate3) && (sds->fec_inner != 0) && (sds->modulation == 1))
+ {
+ CreateSatelliteDeliverySystemDescriptor (Descriptor,
+ BcdCharToInt (sds->frequency1) * 10 * 1000 * 1000 +
+ BcdCharToInt (sds->frequency2) * 100 * 1000 +
+ BcdCharToInt (sds->frequency3) * 1000 +
+ BcdCharToInt (sds->frequency4) * 10,
+ (sds->west_east_flag ? 1 : -1) *
+ (BcdCharToInt (sds->orbital_position1) * 100 +
+ BcdCharToInt (sds->orbital_position2)),
+ sds->polarization,
+ BcdCharToInt (sds->symbol_rate1) * 10 * 1000 +
+ BcdCharToInt (sds->symbol_rate2) * 100 +
+ BcdCharToInt (sds->symbol_rate3),
+ sds->fec_inner);
+ }
+ /* else
+ {
+ fprintf (stderr, "Illegal sds descriptor\n");
+ siDumpDescriptor (Buffer);
+ } */
+ }
+ break;
+
+ case DESCR_SERVICE_LIST:
+// fprintf (stderr, "got descriptor 0x%x\n", GetDescriptorTag(Buffer));
+ CreateServiceListDescriptor (Descriptor);
+ Length = GetDescriptorLength (Buffer) - DESCR_SERVICE_LIST_LEN;
+ Ptr += DESCR_SERVICE_LIST_LEN;
+ while (Length > 0)
+ {
+ AddServiceListEntry (Descriptor,
+ HILO (CastServiceListDescriptorLoop(Ptr)->service_id),
+ CastServiceListDescriptorLoop(Ptr)->service_type);
+ Length -= DESCR_SERVICE_LIST_LEN;
+ Ptr += DESCR_SERVICE_LIST_LEN;
+ }
+ break;
+
+ case DESCR_LOCAL_TIME_OFF:
+ CreateLocalTimeOffsetDescriptor (Descriptor);
+ Length = GetDescriptorLength (Buffer) - DESCR_LOCAL_TIME_OFFSET_LEN;
+ Ptr += DESCR_LOCAL_TIME_OFFSET_LEN;
+ while (Length > 0)
+ {
+ time_t ct, co, no;
+ ct = MjdToEpochTime (CastLocalTimeOffsetEntry(Ptr)->time_of_change_mjd) +
+ BcdTimeToSeconds (CastLocalTimeOffsetEntry(Ptr)->time_of_change_time);
+ co = (BcdCharToInt(CastLocalTimeOffsetEntry(Ptr)->local_time_offset_h) * 3600 +
+ BcdCharToInt(CastLocalTimeOffsetEntry(Ptr)->local_time_offset_m) * 60) *
+ ((CastLocalTimeOffsetEntry(Ptr)->local_time_offset_polarity) ? -1 : 1);
+ no = (BcdCharToInt(CastLocalTimeOffsetEntry(Ptr)->next_time_offset_h) * 3600 +
+ BcdCharToInt(CastLocalTimeOffsetEntry(Ptr)->next_time_offset_m) * 60) *
+ ((CastLocalTimeOffsetEntry(Ptr)->local_time_offset_polarity) ? -1 : 1);
+ AddLocalTimeOffsetEntry (Descriptor,
+ CastLocalTimeOffsetEntry(Ptr)->country_code1,
+ CastLocalTimeOffsetEntry(Ptr)->country_code2,
+ CastLocalTimeOffsetEntry(Ptr)->country_code3,
+ CastLocalTimeOffsetEntry(Ptr)->country_region_id, co, ct, no);
+ Length -= LOCAL_TIME_OFFSET_ENTRY_LEN;
+ Ptr += LOCAL_TIME_OFFSET_ENTRY_LEN;
+ }
+ break;
+
case DESCR_VIDEO_STREAM:
case DESCR_AUDIO_STREAM:
case DESCR_HIERARCHY:
@@ -804,15 +1119,11 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
case DESCR_SMOOTHING_BUFFER:
case DESCR_STD:
case DESCR_IBP:
- case DESCR_NW_NAME:
- case DESCR_SERVICE_LIST:
- case DESCR_SAT_DEL_SYS:
case DESCR_CABLE_DEL_SYS:
case DESCR_VBI_DATA:
case DESCR_VBI_TELETEXT:
case DESCR_MOSAIC:
case DESCR_TELEPHONE:
- case DESCR_LOCAL_TIME_OFF:
case DESCR_TERR_DEL_SYS:
case DESCR_ML_NW_NAME:
case DESCR_ML_BQ_NAME:
@@ -833,6 +1144,8 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
case DESCR_CELL_FREQ_LINK:
case DESCR_ANNOUNCEMENT_SUPPORT:
default:
+// fprintf (stderr, "Unsupported descriptor with tag = 0x%02X\n", GetDescriptorTag(Ptr));
+// siDumpDescriptor (Buffer);
/* fprintf (stderr, "unsupported descriptor 0x%x\n",
GetDescriptorTag(Buffer)); */
break;
@@ -845,14 +1158,19 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
/*
* ToDo: ETSI conformal text definition
*/
-char *siGetDescriptorText (u_char *Buffer, int Length)
+#define GDT_TEXT_DESCRIPTOR 0
+#define GDT_NAME_DESCRIPTOR 1
+char *siGetDescriptorTextHandler (u_char *, int , int );
+
+char *siGetDescriptorTextHandler (u_char *Buffer, int Length, int type)
{
char *tmp, *result;
int i;
if ((Length < 0) || (Length > 4095))
return (xSetText ("text error"));
- if (*Buffer == 0x05 || (*Buffer >= 0x20 && *Buffer <= 0xff))
+/* ASSENIZATION: removing coding detection - suppose they are all ANSI */
+ // if (*Buffer == 0x05 || (*Buffer >= 0x20 && *Buffer <= 0xff))
{
xMemAlloc (Length+1, &result);
tmp = result;
@@ -860,15 +1178,16 @@ char *siGetDescriptorText (u_char *Buffer, int Length)
{
if (*Buffer == 0) break;
- if ((*Buffer >= ' ' && *Buffer <= '~') ||
+ if ((*Buffer >= ' ' && *Buffer <= '~') || (*Buffer == '\n') ||
(*Buffer >= 0xa0 && *Buffer <= 0xff)) *tmp++ = *Buffer;
- if (*Buffer == 0x8A || *Buffer == '\n') *tmp++ = '\n';
+ if (*Buffer == 0x8A) *tmp++ = '\n';
if (*Buffer == 0x86 || *Buffer == 0x87) *tmp++ = ' ';
+ if ((*Buffer == 0x86 || *Buffer == 0x87) && !(GDT_NAME_DESCRIPTOR & type)) *tmp++ = ' ';
Buffer++;
}
*tmp = '\0';
}
- else
+ /* else
{
switch (*Buffer)
{
@@ -881,11 +1200,22 @@ char *siGetDescriptorText (u_char *Buffer, int Length)
case 0x12: result = xSetText ("Coding according to KSC 5601"); break;
default: result = xSetText ("Unknown coding"); break;
}
- }
+ } */
return (result);
}
+char *siGetDescriptorText (u_char *Buffer, int Length)
+{
+ return siGetDescriptorTextHandler (Buffer, Length, GDT_TEXT_DESCRIPTOR);
+}
+
+char *siGetDescriptorName (u_char *Buffer, int Length)
+{
+ return siGetDescriptorTextHandler (Buffer, Length, GDT_NAME_DESCRIPTOR);
+}
+
+
// CRC32 lookup table for polynomial 0x04c11db7
static u_long crc_table[256] = {