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 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

View File

@ -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).

51
eit.c
View File

@ -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) {

3
eit.h
View File

@ -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();

View File

@ -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,6 +342,23 @@ struct PidInfo {
#define STREAMTYPE_13818_D 13
#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 */
#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 */
struct 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
}

View File

@ -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;
u_char polarization :2;
u_char modulation :5;
#else
u_char west_east_flag :1;
u_char polarization :2;
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 */

View File

@ -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_SERVICE_LIST:
case DESCR_STUFFING:
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_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);
}

View File

@ -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

View File

@ -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] = {