Now using 'libdtv' version 0.0.5

This commit is contained in:
Klaus Schmidinger 2003-04-12 11:32:31 +02:00
parent 7c84508417
commit f8a7e51d00
9 changed files with 929 additions and 128 deletions

View File

@ -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 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 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 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> Ulrich Röder <roeder@efr-net.de>
for pointing out that there are channels that have a symbol rate higher than for pointing out that there are channels that have a symbol rate higher than

View File

@ -2020,3 +2020,5 @@ Video Disk Recorder Revision History
- Implemented a "resume ID" which allows several users to each have their own - 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 resume.vdr files (thanks to Martin Hammerschmid). This parameter can be set in
the "Setup/Replay" menu (see MANUAL for details). 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).

51
eit.c
View File

@ -16,7 +16,7 @@
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (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" #include "eit.h"
@ -1011,29 +1011,37 @@ private:
int length; int length;
uchar *data; uchar *data;
public: 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(); virtual ~cCaDescriptor();
int Length(void) const { return length; } int Length(void) const { return length; }
const uchar *Data(void) const { return data; } 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; source = Source;
transponder = Transponder; transponder = Transponder;
serviceId = ServiceId; serviceId = ServiceId;
caSystem = CaSystem; caSystem = CaSystem;
length = Length; length = Length + 6;
data = MALLOC(uchar, length); data = MALLOC(uchar, length);
memcpy(data, Data, length); data[0] = DESCR_CA;
/*//XXX just while debugging... 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 buffer[1024];
char *q = buffer; char *q = buffer;
q += sprintf(q, "CAM: %04X %5d %4d", source, transponder, serviceId); q += sprintf(q, "CAM: %04X %5d %4d", source, transponder, serviceId);
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
q += sprintf(q, " %02X", data[i]); q += sprintf(q, " %02X", data[i]);
dsyslog(buffer); dsyslog(buffer);
*///XXX #endif
} }
cCaDescriptor::~cCaDescriptor() cCaDescriptor::~cCaDescriptor()
@ -1312,16 +1320,13 @@ void cSIProcessor::Action()
if (pid == pmtPid && buf[0] == 0x02 && currentSource && currentTransponder) { if (pid == pmtPid && buf[0] == 0x02 && currentSource && currentTransponder) {
struct Pid *pi = siParsePMT(buf); struct Pid *pi = siParsePMT(buf);
if (pi) { if (pi) {
for (struct LIST *d = (struct LIST *)pi->Descriptors; d; d = (struct LIST *)xSucc(d)) { struct Descriptor *d;
if (DescriptorTag(d) == DESCR_CA) { for (d = (struct Descriptor *)pi->Descriptors->Head; d; d = (struct Descriptor *)xSucc(d))
uchar *Data = ((ConditionalAccessDescriptor *)d)->Data; NewCaDescriptor(d, pi->ProgramID);
int CaSystem = (Data[2] << 8) | Data[3]; // Also scan the PidInfo list for descriptors - some broadcasts send them only here.
if (!caDescriptors->Get(currentSource, currentTransponder, pi->ProgramID, CaSystem)) { for (struct PidInfo *p = (struct PidInfo *)pi->InfoList->Head; p; p = (struct PidInfo *)xSucc(p)) {
cMutexLock MutexLock(&caDescriptorsMutex); for (d = (struct Descriptor *)p->Descriptors->Head; d; d = (struct Descriptor *)xSucc(d))
caDescriptors->Add(new cCaDescriptor(currentSource, currentTransponder, pi->ProgramID, CaSystem, ((ConditionalAccessDescriptor *)d)->Amount, Data)); NewCaDescriptor(d, pi->ProgramID);
}
//XXX update???
}
} }
} }
xMemFreeAll(NULL); xMemFreeAll(NULL);
@ -1438,6 +1443,18 @@ void cSIProcessor::TriggerDump(void)
lastDump = 0; 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) int cSIProcessor::GetCaDescriptors(int Source, int Transponder, int ServiceId, int BufSize, uchar *Data)
{ {
if (BufSize > 0 && Data) { if (BufSize > 0 && Data) {

3
eit.h
View File

@ -16,7 +16,7 @@
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (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 #ifndef __EIT_H
@ -158,6 +158,7 @@ private:
bool AddFilter(unsigned short pid, u_char tid); bool AddFilter(unsigned short pid, u_char tid);
bool DelFilter(unsigned short pid, u_char tid); bool DelFilter(unsigned short pid, u_char tid);
bool ShutDownFilters(void); bool ShutDownFilters(void);
void NewCaDescriptor(struct Descriptor *d, int ProgramID);
public: public:
cSIProcessor(const char *FileName); cSIProcessor(const char *FileName);
~cSIProcessor(); ~cSIProcessor();

View File

@ -4,11 +4,13 @@
/// /// /// ///
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// $Revision: 1.6 $ // $Revision: 1.7 $
// $Date: 2002/01/30 17:04:13 $ // $Date: 2003/04/12 11:27:31 $
// $Author: hakenes $ // $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 // libsi is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@ -38,9 +40,9 @@
/* Program Identifier */ /* Program Identifier */
#define PID_PAT 0x00 /* Program Association Table */ #define PID_PAT 0x00 /* Program Association Table */
#define PID_BAT 0x01 /* Bouquet Association Table */
#define PID_CAT 0x01 /* Conditional Access Table */ #define PID_CAT 0x01 /* Conditional Access Table */
#define PID_NIT 0x10 /* Network Information Table */ #define PID_NIT 0x10 /* Network Information Table */
#define PID_BAT 0x11 /* Bouquet Association Table */
#define PID_SDT 0x11 /* Service Description Table */ #define PID_SDT 0x11 /* Service Description Table */
#define PID_EIT 0x12 /* Event Information Table */ #define PID_EIT 0x12 /* Event Information Table */
#define PID_RST 0x13 /* Running Status Table */ #define PID_RST 0x13 /* Running Status Table */
@ -75,12 +77,13 @@
#define TID_TOT 0x73 /* Time Offset Section */ #define TID_TOT 0x73 /* Time Offset Section */
#define TID_CA_ECM_0 0x80 #define TID_CA_ECM_0 0x80
#define TID_CA_ECM_1 0x81 #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_EIT 0x12 /* Event Information Section */
#define TID_RST 0x13 /* Running Status Section */ #define TID_RST 0x71 /* Running Status Section */
#define TID_ST 0x14 /* Stuffung Section */ #define TID_ST 0x72 /* Stuffing Section */
/* 0xFF */ /* Reserved for future use */ /* 0xFF */ /* Reserved for future use */
/* Descriptor Identifier */ /* Descriptor Identifier */
@ -160,6 +163,40 @@
#define MAX_SECTION_BUFFER 4096 #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 */ /* Strukturen zur Aufnahme der SDT und EIT Informationen */
struct Service { struct Service {
@ -305,6 +342,23 @@ struct PidInfo {
#define STREAMTYPE_13818_D 13 #define STREAMTYPE_13818_D 13
#define STREAMTYPE_13818_AUX 14 #define STREAMTYPE_13818_AUX 14
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)
/* Descriptors */ /* Descriptors */
#define DescriptorTag(x) ((struct Descriptor *)(x))->Tag #define DescriptorTag(x) ((struct Descriptor *)(x))->Tag
@ -315,29 +369,6 @@ struct Descriptor {
}; };
/* ConditionalAccessDescriptor */
struct ConditionalAccessDescriptor {
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 */ /* Iso639LanguageDescriptor */
struct Iso639LanguageDescriptor { struct Iso639LanguageDescriptor {
@ -434,19 +465,23 @@ struct AncillaryDataDescriptor {
/* BouquetNameDescriptor */ /* BouquetNameDescriptor */
/*
the same used instead of NetworkNameDescriptor because their structures
are identical. We pass 'tag' parameter to distinguish between them later
*/
struct BouquetNameDescriptor { struct BouquetNameDescriptor {
struct NODE Node; /* Node enthält Namen */ struct NODE Node; /* Node enthält Namen */
unsigned short Tag; unsigned short Tag;
}; };
#define CreateBouquetNameDescriptor(descr, text) \ #define CreateBouquetNameDescriptor(descr, text, tag) \
do \ do \
{ \ { \
xCreateNode (((struct BouquetNameDescriptor *)descr), NULL); \ xCreateNode (((struct BouquetNameDescriptor *)descr), NULL); \
((struct NODE *)descr)->Name = text; \ ((struct NODE *)descr)->Name = text; \
((struct NODE *)descr)->HashKey = xHashKey (text); \ ((struct NODE *)descr)->HashKey = xHashKey (text); \
((struct BouquetNameDescriptor *)descr)->Tag = DESCR_BOUQUET_NAME; \ ((struct BouquetNameDescriptor *)descr)->Tag = tag; \
} while (0) } while (0)
@ -514,6 +549,33 @@ struct CaIdentifierDescriptor {
((struct CaIdentifierDescriptor *)descr)->SystemID[num] = id ((struct CaIdentifierDescriptor *)descr)->SystemID[num] = id
#define GetCaIdentifierID(descr, num) (((struct CaIdentifierDescriptor *)descr)->SystemID[num]) #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 */ /* StreamIdentifierDescriptor */
@ -968,6 +1030,122 @@ struct SubtitlingItem {
xAddTail (((struct SubtitlingDescriptor *)desc)->Items, item); \ xAddTail (((struct SubtitlingDescriptor *)desc)->Items, item); \
} while (0) } 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 */ /* Prototypes */
@ -979,13 +1157,17 @@ extern "C" {
/* si_parser.c */ /* si_parser.c */
struct LIST *siParsePAT (u_char *); struct LIST *siParsePAT (u_char *);
struct LIST *siParseCAT (u_char *);
struct Pid *siParsePMT (u_char *); struct Pid *siParsePMT (u_char *);
struct LIST *siParseSDT (u_char *); struct LIST *siParseSDT (u_char *);
struct LIST *siParseNIT (u_char *);
struct LIST *siParseEIT (u_char *); struct LIST *siParseEIT (u_char *);
time_t siParseTDT (u_char *); time_t siParseTDT (u_char *);
struct Tot *siParseTOT (u_char *);
void siParseDescriptors (struct LIST *, u_char *, int, u_char); void siParseDescriptors (struct LIST *, u_char *, int, u_char);
void siParseDescriptor (struct LIST *, u_char *); void siParseDescriptor (struct LIST *, u_char *);
char *siGetDescriptorText (u_char *, int); char *siGetDescriptorText (u_char *, int);
char *siGetDescriptorName (u_char *, int);
u_long crc32 (char *data, int len); u_long crc32 (char *data, int len);
/* si_debug_services.c */ /* si_debug_services.c */
@ -999,6 +1181,8 @@ void siDebugPids (char *, struct LIST *);
void siDebugDescriptors (char *, struct LIST *); void siDebugDescriptors (char *, struct LIST *);
void siDebugEitServices (struct LIST *); void siDebugEitServices (struct LIST *);
void siDebugEitEvents (char *, struct LIST *); void siDebugEitEvents (char *, struct LIST *);
void siDumpDescriptor (void *);
void siDumpSection (void *);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,11 +5,13 @@
/// /// /// ///
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// $Revision: 1.3 $ // $Revision: 1.4 $
// $Date: 2001/10/07 10:24:46 $ // $Date: 2003/04/12 11:27:31 $
// $Author: hakenes $ // $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 // libsi is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // 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))) + \ #define BcdTimeToSeconds(x) ((3600 * ((10*((x##_h & 0xF0)>>4)) + (x##_h & 0xF))) + \
(60 * ((10*((x##_m & 0xF0)>>4)) + (x##_m & 0xF))) + \ (60 * ((10*((x##_m & 0xF0)>>4)) + (x##_m & 0xF))) + \
((10*((x##_s & 0xF0)>>4)) + (x##_s & 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 TableHasMoreSections(x) (((pat_t *)(x))->last_section_number > ((pat_t *)(x))->section_number)
#define GetTableId(x) ((pat_t *)(x))->table_id #define GetTableId(x) ((pat_t *)(x))->table_id
#define GetSectionNumber(x) ((pat_t *)(x))->section_number #define GetSectionNumber(x) ((pat_t *)(x))->section_number
#define GetLastSectionNumber(x) ((pat_t *)(x))->last_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 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. * 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): * 3) Program Map Table (PMT):
@ -297,7 +339,7 @@ typedef struct {
* bouquet. * bouquet.
* *
*/ */
/* TO BE DONE */ /* SEE NIT (It has the same structure but has different allowed descriptors) */
/* /*
* *
* 2) Service Description Table (SDT): * 2) Service Description Table (SDT):
@ -339,6 +381,9 @@ typedef struct {
u_char :8; u_char :8;
} sdt_t; } 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 #define SDT_DESCR_LEN 5
typedef struct { typedef struct {
@ -483,7 +528,36 @@ typedef struct {
* to the frequent updating of the time information. * 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): * 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) #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 */ /* 0x0A iso_639_language_descriptor */
#define DESCR_ISO_639_LANGUAGE_LEN 5 #define DESCR_ISO_639_LANGUAGE_LEN 5
@ -560,25 +653,31 @@ typedef struct descr_iso_639_language_struct {
/* 0x40 network_name_descriptor */ /* 0x40 network_name_descriptor */
#define DESCR_NETWORK_NAME_LEN XX #define DESCR_NETWORK_NAME_LEN 2
typedef struct descr_network_name_struct { typedef struct descr_network_name_struct {
u_char descriptor_tag :8; u_char descriptor_tag :8;
u_char descriptor_length :8; u_char descriptor_length :8;
/* TBD */
} descr_network_name_t; } descr_network_name_t;
#define CastNetworkNameDescriptor(x) ((descr_network_name_t *)(x)) #define CastNetworkNameDescriptor(x) ((descr_network_name_t *)(x))
/* 0x41 service_list_descriptor */ /* 0x41 service_list_descriptor */
#define DESCR_SERVICE_LIST_LEN XX #define DESCR_SERVICE_LIST_LEN 2
typedef struct descr_service_list_struct { typedef struct descr_service_list_struct {
u_char descriptor_tag :8; u_char descriptor_tag :8;
u_char descriptor_length :8; u_char descriptor_length :8;
/* TBD */
} descr_service_list_t; } descr_service_list_t;
#define CastServiceListDescriptor(x) ((descr_service_list_t *)(x)) #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 */ /* 0x42 stuffing_descriptor */
@ -604,13 +703,13 @@ typedef struct descr_satellite_delivery_system_struct {
u_char orbital_position1 :8; u_char orbital_position1 :8;
u_char orbital_position2 :8; u_char orbital_position2 :8;
#if BYTE_ORDER == BIG_ENDIAN #if BYTE_ORDER == BIG_ENDIAN
u_char modulation :5;
u_char polarization :2;
u_char west_east_flag :1; u_char west_east_flag :1;
u_char polarization :2;
u_char modulation :5;
#else #else
u_char west_east_flag :1;
u_char polarization :2;
u_char modulation :5; u_char modulation :5;
u_char polarization :2;
u_char west_east_flag :1;
#endif #endif
u_char symbol_rate1 :8; u_char symbol_rate1 :8;
u_char symbol_rate2 :8; u_char symbol_rate2 :8;
@ -964,14 +1063,39 @@ typedef struct descr_telephone_struct {
/* 0x58 local_time_offset_descriptor */ /* 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 { typedef struct descr_local_time_offset_struct {
u_char descriptor_tag :8; u_char descriptor_tag :8;
u_char descriptor_length :8; u_char descriptor_length :8;
/* TBD */
} descr_local_time_offset_t; } descr_local_time_offset_t;
#define CastLocalTimeOffsetDescriptor(x) ((descr_local_time_offset_t *)(x)) #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 */ /* 0x59 subtitling_descriptor */

View File

@ -4,11 +4,13 @@
/// /// /// ///
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// $Revision: 1.4 $ // $Revision: 1.5 $
// $Date: 2001/10/07 10:24:46 $ // $Date: 2003/02/04 18:45:35 $
// $Author: hakenes $ // $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 // libsi is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@ -26,11 +28,13 @@
// Boston, MA 02111-1307, USA. // Boston, MA 02111-1307, USA.
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include "../liblx/liblx.h" #include "../liblx/liblx.h"
#include "libsi.h" #include "libsi.h"
#include "si_tables.h"
#include "si_debug_services.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 ProgramID: %d\n", Prepend, Pid->ProgramID);
printf ("%s PcrPid: %d\n", Prepend, Pid->PcrPID); printf ("%s PcrPid: %d\n", Prepend, Pid->PcrPID);
printf ("%s PmtVersion: %d\n", Prepend, Pid->PmtVersion); printf ("%s PmtVersion: %d\n", Prepend, Pid->PmtVersion);
sprintf (NewPrepend, "%s ", Prepend);
siDebugDescriptors (NewPrepend, Pid->Descriptors);
xForeach (Pid->InfoList, PidInfo) xForeach (Pid->InfoList, PidInfo)
{ {
@ -256,6 +262,11 @@ void siDebugDescriptors (char *Prepend, struct LIST *Descriptors)
printf ("\n"); printf ("\n");
break; break;
case DESCR_NW_NAME:
printf ("%sDescriptor: Network Name\n", Prepend);
printf ("%s Name: %s\n", Prepend, xName (Descriptor));
break;
case DESCR_BOUQUET_NAME: case DESCR_BOUQUET_NAME:
printf ("%sDescriptor: Bouquet Name\n", Prepend); printf ("%sDescriptor: Bouquet Name\n", Prepend);
printf ("%s Name: %s\n", Prepend, xName (Descriptor)); printf ("%s Name: %s\n", Prepend, xName (Descriptor));
@ -336,12 +347,38 @@ void siDebugDescriptors (char *Prepend, struct LIST *Descriptors)
case DESCR_CA_IDENT: case DESCR_CA_IDENT:
printf ("%sDescriptor: Conditional Access Identity\n", Prepend); printf ("%sDescriptor: Conditional Access Identity\n", Prepend);
{ {
int j; int j,k;
for (j = 0; j < ((struct CaIdentifierDescriptor *)Descriptor)->Amount; j++) 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; 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: case DESCR_CONTENT:
printf ("%sDescriptor: Content\n", Prepend); printf ("%sDescriptor: Content\n", Prepend);
{ {
@ -489,16 +526,57 @@ void siDebugDescriptors (char *Prepend, struct LIST *Descriptors)
} }
break; break;
case DESCR_NW_NAME:
case DESCR_SERVICE_LIST:
case DESCR_STUFFING:
case DESCR_SAT_DEL_SYS: 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_CABLE_DEL_SYS: case DESCR_CABLE_DEL_SYS:
case DESCR_VBI_DATA: case DESCR_VBI_DATA:
case DESCR_VBI_TELETEXT: case DESCR_VBI_TELETEXT:
case DESCR_MOSAIC: case DESCR_MOSAIC:
case DESCR_TELEPHONE: case DESCR_TELEPHONE:
case DESCR_LOCAL_TIME_OFF:
case DESCR_TERR_DEL_SYS: case DESCR_TERR_DEL_SYS:
case DESCR_ML_NW_NAME: case DESCR_ML_NW_NAME:
case DESCR_ML_BQ_NAME: case DESCR_ML_BQ_NAME:
@ -527,3 +605,39 @@ void siDebugDescriptors (char *Prepend, struct LIST *Descriptors)
return; 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);
}

View File

@ -4,8 +4,8 @@
/// /// /// ///
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// $Revision: 1.1 $ // $Revision: 1.2 $
// $Date: 2001/08/15 10:00:00 $ // $Date: 2003/04/12 11:27:31 $
// $Author: hakenes $ // $Author: hakenes $
// //
// (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. // (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 #define CONTENT_TYPE_NUMBER 79
static char StreamTypes[][70] = { static char *StreamTypes[] = {
"ITU-T|ISO/IEC Reserved", "ITU-T|ISO/IEC Reserved",
"ISO/IEC Video", "ISO/IEC Video",
"13818-2 Video or 11172-2 constrained parameter video stream", "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", "ITU-T Rec. H.222.0 | ISO 13818-1 Reserved",
"User private" "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

View File

@ -4,11 +4,13 @@
/// /// /// ///
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// $Revision: 1.6 $ // $Revision: 1.8 $
// $Date: 2002/01/30 17:04:13 $ // $Date: 2003/02/04 18:45:35 $
// $Author: hakenes $ // $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 // libsi is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // 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; Pat = (pat_t *) Buffer; Ptr = Buffer;
if (Pat->table_id != TID_PAT) { 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; 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) struct Pid *siParsePMT (u_char *Buffer)
{ {
pmt_t *Pmt; pmt_t *Pmt;
@ -101,7 +140,7 @@ struct Pid *siParsePMT (u_char *Buffer)
Pmt = (pmt_t *) Buffer; Ptr = Buffer; Pmt = (pmt_t *) Buffer; Ptr = Buffer;
if (Pmt->table_id != TID_PMT) { 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; 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) struct LIST *siParseSDT (u_char *Buffer)
{ {
sdt_t *Sdt; sdt_t *Sdt;
@ -164,7 +286,7 @@ struct LIST *siParseSDT (u_char *Buffer)
Sdt = (sdt_t *) Buffer; Ptr = Buffer; Sdt = (sdt_t *) Buffer; Ptr = Buffer;
if (Sdt->table_id != TID_SDT_ACT && Sdt->table_id != TID_SDT_OTH) { 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; 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_ACT_SCH + 0x0F) &&
!(Eit->table_id >= TID_EIT_OTH_SCH && !(Eit->table_id >= TID_EIT_OTH_SCH &&
Eit->table_id <= TID_EIT_OTH_SCH + 0x0F)) { 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; return NULL;
} }
@ -331,7 +453,7 @@ time_t siParseTDT (u_char *Buffer)
Tdt = (tdt_t *) Buffer; Ptr = Buffer; Tdt = (tdt_t *) Buffer; Ptr = Buffer;
if (Tdt->table_id != TID_TDT) { 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; 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, void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
int Length, u_char TableID) int Length, u_char TableID)
{ {
@ -352,6 +512,7 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
DescriptorLength = 0; DescriptorLength = 0;
Ptr = Buffer; Ptr = Buffer;
TempTableID = TableID;
while (DescriptorLength < Length) while (DescriptorLength < Length)
{ {
@ -362,15 +523,17 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
case TID_NIT_ACT: case TID_NIT_OTH: case TID_NIT_ACT: case TID_NIT_OTH:
switch (GetDescriptorTag(Ptr)) switch (GetDescriptorTag(Ptr))
{ {
case DESCR_NW_NAME:
case DESCR_SERVICE_LIST:
case DESCR_STUFFING:
case DESCR_SAT_DEL_SYS: case DESCR_SAT_DEL_SYS:
case DESCR_CABLE_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_LINKAGE:
case DESCR_TERR_DEL_SYS: case DESCR_TERR_DEL_SYS:
case DESCR_ML_NW_NAME: case DESCR_ML_NW_NAME:
case DESCR_PRIV_DATA_SPEC:
case DESCR_CELL_LIST: case DESCR_CELL_LIST:
case DESCR_CELL_FREQ_LINK: case DESCR_CELL_FREQ_LINK:
case DESCR_ANNOUNCEMENT_SUPPORT: case DESCR_ANNOUNCEMENT_SUPPORT:
@ -378,8 +541,7 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
break; break;
default: default:
/* fprintf (stderr, "forbidden descriptor 0x%x in NIT\n", // fprintf (stderr, "forbidden descriptor 0x%x in NIT\n", GetDescriptorTag(Ptr));
GetDescriptorTag(Ptr));*/
break; break;
} }
break; break;
@ -396,12 +558,12 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
case DESCR_CA_IDENT: case DESCR_CA_IDENT:
case DESCR_ML_BQ_NAME: case DESCR_ML_BQ_NAME:
case DESCR_PRIV_DATA_SPEC: case DESCR_PRIV_DATA_SPEC:
// fprintf (stderr, "Got descriptor with tag = 0x%X\n", GetDescriptorTag(Ptr));
siParseDescriptor (Descriptors, Ptr); siParseDescriptor (Descriptors, Ptr);
break; break;
default: default:
/*fprintf (stderr, "forbidden descriptor 0x%x in BAT\n", // fprintf (stderr, "forbidden descriptor 0x%x in BAT\n", GetDescriptorTag(Ptr));
GetDescriptorTag(Ptr));*/
break; break;
} }
break; break;
@ -426,8 +588,7 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
break; break;
default: default:
/* fprintf (stderr, "forbidden descriptor 0x%x in SDT\n", // fprintf (stderr, "forbidden descriptor 0x%x in SDT\n", GetDescriptorTag(Ptr));
GetDescriptorTag(Ptr)); */
break; break;
} }
break; break;
@ -470,8 +631,7 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
break; break;
default: default:
/*fprintf (stderr, "forbidden descriptor 0x%x in EIT\n", // fprintf (stderr, "forbidden descriptor 0x%x in EIT\n", GetDescriptorTag(Ptr));
GetDescriptorTag(Ptr));*/
break; break;
} }
break; break;
@ -484,8 +644,7 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
break; break;
default: default:
/*fprintf (stderr, "forbidden descriptor 0x%x in TOT\n", // fprintf (stderr, "forbidden descriptor 0x%x in TOT\n", GetDescriptorTag(Ptr));
GetDescriptorTag(Ptr));*/
break; break;
} }
break; break;
@ -522,15 +681,28 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer,
break; break;
default: default:
/* fprintf (stderr, "forbidden descriptor 0x%x in PMT\n", // fprintf (stderr, "forbidden descriptor 0x%x in PMT\n", GetDescriptorTag(Ptr));
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;
} }
break; break;
default: default:
fprintf (stderr, "descriptor 0x%x in unsupported table 0x%x\n", // fprintf (stderr, "descriptor 0x%x in unsupported table 0x%x\n", GetDescriptorTag(Ptr), TableID);
GetDescriptorTag(Ptr), TableID);
break; break;
} }
DescriptorLength += GetDescriptorLength (Ptr); DescriptorLength += GetDescriptorLength (Ptr);
@ -550,6 +722,7 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
if (!Descriptors || !Buffer) return; if (!Descriptors || !Buffer) return;
Ptr = Buffer; Ptr = Buffer;
// fprintf (stderr, "Got descriptor with tag = 0x%X\n", GetDescriptorTag(Buffer));
switch (GetDescriptorTag(Buffer)) switch (GetDescriptorTag(Buffer))
{ {
@ -558,10 +731,12 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
CastAncillaryDataDescriptor(Buffer)->ancillary_data_identifier); CastAncillaryDataDescriptor(Buffer)->ancillary_data_identifier);
break; break;
case DESCR_NW_NAME:
case DESCR_BOUQUET_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); 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; break;
case DESCR_COMPONENT: case DESCR_COMPONENT:
@ -577,9 +752,9 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
break; break;
case DESCR_SERVICE: case DESCR_SERVICE:
Text = siGetDescriptorText (Buffer + DESCR_SERVICE_LEN, Text = siGetDescriptorName (Buffer + DESCR_SERVICE_LEN,
CastServiceDescriptor(Buffer)->provider_name_length); CastServiceDescriptor(Buffer)->provider_name_length);
Text2 = siGetDescriptorText (Buffer + DESCR_SERVICE_LEN + Text2 = siGetDescriptorName (Buffer + DESCR_SERVICE_LEN +
CastServiceDescriptor(Buffer)->provider_name_length + 1, CastServiceDescriptor(Buffer)->provider_name_length + 1,
*((u_char *)(Buffer + DESCR_SERVICE_LEN + *((u_char *)(Buffer + DESCR_SERVICE_LEN +
CastServiceDescriptor(Buffer)->provider_name_length))); CastServiceDescriptor(Buffer)->provider_name_length)));
@ -598,7 +773,7 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
break; break;
case DESCR_SHORT_EVENT: case DESCR_SHORT_EVENT:
Text = siGetDescriptorText (Buffer + DESCR_SHORT_EVENT_LEN, Text = siGetDescriptorName (Buffer + DESCR_SHORT_EVENT_LEN,
CastShortEventDescriptor(Buffer)->event_name_length); CastShortEventDescriptor(Buffer)->event_name_length);
Text2 = siGetDescriptorText (Buffer + DESCR_SHORT_EVENT_LEN + Text2 = siGetDescriptorText (Buffer + DESCR_SHORT_EVENT_LEN +
CastShortEventDescriptor(Buffer)->event_name_length + 1, CastShortEventDescriptor(Buffer)->event_name_length + 1,
@ -623,6 +798,7 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
CastExtendedEventDescriptor(Buffer)->lang_code3, Text); CastExtendedEventDescriptor(Buffer)->lang_code3, Text);
Length = CastExtendedEventDescriptor(Buffer)->length_of_items; Length = CastExtendedEventDescriptor(Buffer)->length_of_items;
Ptr += DESCR_EXTENDED_EVENT_LEN; Ptr += DESCR_EXTENDED_EVENT_LEN;
// printf ("EEDesc #%d, %s\n", CastExtendedEventDescriptor(Buffer)->descriptor_number, Text);
while ((Length > 0) && (Length < GetDescriptorLength (Buffer))) while ((Length > 0) && (Length < GetDescriptorLength (Buffer)))
{ {
Text = siGetDescriptorText (Ptr + ITEM_EXTENDED_EVENT_LEN, 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, CastExtendedEventItem(Ptr)->item_description_length + 1,
*((u_char *)(Ptr + ITEM_EXTENDED_EVENT_LEN + *((u_char *)(Ptr + ITEM_EXTENDED_EVENT_LEN +
CastExtendedEventItem(Ptr)->item_description_length))); CastExtendedEventItem(Ptr)->item_description_length)));
// printf ("EEItem #%d, %s, %s\n", CastExtendedEventDescriptor(Buffer)->descriptor_number, Text, Text2);
AddExtendedEventItem (Descriptor, Text2, Text); AddExtendedEventItem (Descriptor, Text2, Text);
Length -= ITEM_EXTENDED_EVENT_LEN + CastExtendedEventItem(Ptr)->item_description_length + Length -= ITEM_EXTENDED_EVENT_LEN + CastExtendedEventItem(Ptr)->item_description_length +
*((u_char *)(Ptr + ITEM_EXTENDED_EVENT_LEN + *((u_char *)(Ptr + ITEM_EXTENDED_EVENT_LEN +
@ -642,15 +819,85 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
break; break;
case DESCR_CA_IDENT: case DESCR_CA_IDENT:
CreateCaIdentifierDescriptor (Descriptor,
(GetDescriptorLength(Buffer) - DESCR_CA_IDENTIFIER_LEN) / 2);
Length = GetDescriptorLength (Buffer) - DESCR_CA_IDENTIFIER_LEN; Length = GetDescriptorLength (Buffer) - DESCR_CA_IDENTIFIER_LEN;
CreateCaIdentifierDescriptor (Descriptor, Length / 2);
Ptr += DESCR_CA_IDENTIFIER_LEN; i = 0; Ptr += DESCR_CA_IDENTIFIER_LEN; i = 0;
while (Length > 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++; } Length -= 2; Ptr += 2; i++; }
break; 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: case DESCR_CONTENT:
CreateContentDescriptor (Descriptor, CreateContentDescriptor (Descriptor,
(GetDescriptorLength(Buffer) - DESCR_CONTENT_LEN) / 2); (GetDescriptorLength(Buffer) - DESCR_CONTENT_LEN) / 2);
@ -705,12 +952,6 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
HILO (CastTimeShiftedEventDescriptor(Ptr)->reference_event_id)); HILO (CastTimeShiftedEventDescriptor(Ptr)->reference_event_id));
break; break;
case DESCR_CA:
CreateConditionalAccessDescriptor (Descriptor,
*(Ptr + 1) + 2, // we'll need the entire raw data!
Ptr);
break;
case DESCR_ISO_639_LANGUAGE: case DESCR_ISO_639_LANGUAGE:
CreateIso639LanguageDescriptor (Descriptor, CreateIso639LanguageDescriptor (Descriptor,
CastIso639LanguageDescriptor(Buffer)->lang_code1, CastIso639LanguageDescriptor(Buffer)->lang_code1,
@ -789,6 +1030,80 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
} }
break; 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_VIDEO_STREAM:
case DESCR_AUDIO_STREAM: case DESCR_AUDIO_STREAM:
case DESCR_HIERARCHY: case DESCR_HIERARCHY:
@ -804,15 +1119,11 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
case DESCR_SMOOTHING_BUFFER: case DESCR_SMOOTHING_BUFFER:
case DESCR_STD: case DESCR_STD:
case DESCR_IBP: case DESCR_IBP:
case DESCR_NW_NAME:
case DESCR_SERVICE_LIST:
case DESCR_SAT_DEL_SYS:
case DESCR_CABLE_DEL_SYS: case DESCR_CABLE_DEL_SYS:
case DESCR_VBI_DATA: case DESCR_VBI_DATA:
case DESCR_VBI_TELETEXT: case DESCR_VBI_TELETEXT:
case DESCR_MOSAIC: case DESCR_MOSAIC:
case DESCR_TELEPHONE: case DESCR_TELEPHONE:
case DESCR_LOCAL_TIME_OFF:
case DESCR_TERR_DEL_SYS: case DESCR_TERR_DEL_SYS:
case DESCR_ML_NW_NAME: case DESCR_ML_NW_NAME:
case DESCR_ML_BQ_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_CELL_FREQ_LINK:
case DESCR_ANNOUNCEMENT_SUPPORT: case DESCR_ANNOUNCEMENT_SUPPORT:
default: default:
// fprintf (stderr, "Unsupported descriptor with tag = 0x%02X\n", GetDescriptorTag(Ptr));
// siDumpDescriptor (Buffer);
/* fprintf (stderr, "unsupported descriptor 0x%x\n", /* fprintf (stderr, "unsupported descriptor 0x%x\n",
GetDescriptorTag(Buffer)); */ GetDescriptorTag(Buffer)); */
break; break;
@ -845,14 +1158,19 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer)
/* /*
* ToDo: ETSI conformal text definition * 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; char *tmp, *result;
int i; int i;
if ((Length < 0) || (Length > 4095)) if ((Length < 0) || (Length > 4095))
return (xSetText ("text error")); 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); xMemAlloc (Length+1, &result);
tmp = result; tmp = result;
@ -860,15 +1178,16 @@ char *siGetDescriptorText (u_char *Buffer, int Length)
{ {
if (*Buffer == 0) break; if (*Buffer == 0) break;
if ((*Buffer >= ' ' && *Buffer <= '~') || if ((*Buffer >= ' ' && *Buffer <= '~') || (*Buffer == '\n') ||
(*Buffer >= 0xa0 && *Buffer <= 0xff)) *tmp++ = *Buffer; (*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) *tmp++ = ' ';
if ((*Buffer == 0x86 || *Buffer == 0x87) && !(GDT_NAME_DESCRIPTOR & type)) *tmp++ = ' ';
Buffer++; Buffer++;
} }
*tmp = '\0'; *tmp = '\0';
} }
else /* else
{ {
switch (*Buffer) switch (*Buffer)
{ {
@ -881,11 +1200,22 @@ char *siGetDescriptorText (u_char *Buffer, int Length)
case 0x12: result = xSetText ("Coding according to KSC 5601"); break; case 0x12: result = xSetText ("Coding according to KSC 5601"); break;
default: result = xSetText ("Unknown coding"); break; default: result = xSetText ("Unknown coding"); break;
} }
} } */
return (result); 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 // CRC32 lookup table for polynomial 0x04c11db7
static u_long crc_table[256] = { static u_long crc_table[256] = {