diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2003-04-13 18:00:00 +0200 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2003-04-13 18:00:00 +0200 |
commit | 9f919801465f49be6b2118f54bd54df846e2f865 (patch) | |
tree | 721f42c9fd88ab33b47ad9b945247353bac9bc4c /libdtv | |
parent | b60eda5a8e8a9b9b96a90016fd27c03cd3f1ec8b (diff) | |
download | vdr-patch-lnbsharing-9f919801465f49be6b2118f54bd54df846e2f865.tar.gz vdr-patch-lnbsharing-9f919801465f49be6b2118f54bd54df846e2f865.tar.bz2 |
Version 1.1.27vdr-1.1.27
- The CAM is now accessed only if the current channel actually has a non-zero Ca
value, and CAM access is completely suppressed during replay, which avoids
problems in case the CAM is attached to the primary DVB device.
- The "Left" and "Right" buttons now set the cursor to the first or last list item
even if the list consist only of a single page, like, for instance, the Main menu
(thanks to Oliver Endriss).
- Made the log message "OSD window width must be a multiple of 4..." a debug message
instead of an error message, so it can be avoided by using a log level less than 3.
- Updated Greek language texts (thanks to Dimitrios Dimitrakos).
- Fixed faulty behaviour of the "Mute" key in case the channel display is visible
(thanks to Florian Bartels for reporting this one and Sascha Volkenandt for
helping to fix it).
- Modified LOF handling to allow for C-band reception (thanks to Malcolm Caldwell).
- Added some missing cAudio handling calls (thanks to Werner Fink).
- Replaced the 'for' loops in StripAudioPackets() with memset() calls (thanks to
Werner Fink).
- Further increased the timeout until an index file is considerd no longer to be
written.
- Fixed a crash in case the index file can't be accessed any more during replay
(thanks to Stefan Huelswitt for reporting this one).
- Fixed displaying messages in the status line in case they exceed the OSD width
(thanks to Gerhard Steiner for reporting this one).
- Avoiding high CPU load in case the connection to LIRC gets lost (thanks to
Ludwig Nussel).
- Fixed handling repeat function with LIRC (thanks to Ludwig Nussel).
- Fixed handling min/max borders when entering integer values (thanks to Andy
Grobb for reporting this one).
- 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).
- If no device with an MPEG decoder can be found at startup, the first device
is now used as primary device (just to have some device).
- Adjusted some Premiere channels in 'channels.conf' (thanks to Thomas Koch).
- Updated 'channels.conf.cable' (thanks to Stefan HuÃfeldt).
- The 'epg.data' file is now read after all plugins have been started (thanks
to Sascha Volkenandt).
- The LIRC remote control no longer tries to learn keys if it can't connect to
the LIRC daemon (thanks to Ludwig Nussel for reporting this one). The same
applies to the RCU remote control in case of errors during startup.
- Fixed handling of Ca parameters with values <= MAXDEVICES, which don't indicate
an actual encrypted channel (thanks to Stefan Huelswitt for reporting this one).
Diffstat (limited to 'libdtv')
-rw-r--r-- | libdtv/libsi/include/libsi.h | 248 | ||||
-rw-r--r-- | libdtv/libsi/include/si_tables.h | 156 | ||||
-rw-r--r-- | libdtv/libsi/si_debug_services.c | 130 | ||||
-rw-r--r-- | libdtv/libsi/si_debug_services.h | 34 | ||||
-rw-r--r-- | libdtv/libsi/si_parser.c | 430 |
5 files changed, 889 insertions, 109 deletions
diff --git a/libdtv/libsi/include/libsi.h b/libdtv/libsi/include/libsi.h index 8e9e260..715d18b 100644 --- a/libdtv/libsi/include/libsi.h +++ b/libdtv/libsi/include/libsi.h @@ -4,11 +4,13 @@ /// /// ////////////////////////////////////////////////////////////// -// $Revision: 1.6 $ -// $Date: 2002/01/30 17:04:13 $ +// $Revision: 1.7 $ +// $Date: 2003/02/04 18:45:36 $ // $Author: hakenes $ // -// (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. +// (C) 2001-03 Rolf Hakenes <hakenes@hippomi.de>, under the +// GNU GPL with contribution of Oleg Assovski, +// www.satmania.com // // libsi is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -38,9 +40,9 @@ /* Program Identifier */ #define PID_PAT 0x00 /* Program Association Table */ -#define PID_BAT 0x01 /* Bouquet Association Table */ #define PID_CAT 0x01 /* Conditional Access Table */ #define PID_NIT 0x10 /* Network Information Table */ +#define PID_BAT 0x11 /* Bouquet Association Table */ #define PID_SDT 0x11 /* Service Description Table */ #define PID_EIT 0x12 /* Event Information Table */ #define PID_RST 0x13 /* Running Status Table */ @@ -75,12 +77,13 @@ #define TID_TOT 0x73 /* Time Offset Section */ #define TID_CA_ECM_0 0x80 #define TID_CA_ECM_1 0x81 +#define TID_CA_EMM 0x82 -#define TID_BAT 0x01 /* Bouquet Association Section */ +#define TID_BAT 0x4A /* Bouquet Association Section */ #define TID_EIT 0x12 /* Event Information Section */ -#define TID_RST 0x13 /* Running Status Section */ -#define TID_ST 0x14 /* Stuffung Section */ +#define TID_RST 0x71 /* Running Status Section */ +#define TID_ST 0x72 /* Stuffing Section */ /* 0xFF */ /* Reserved for future use */ /* Descriptor Identifier */ @@ -160,6 +163,40 @@ #define MAX_SECTION_BUFFER 4096 +/* NetworkInfo structure (used to store NIT/BAT information) */ + +struct NetworkInfo { + struct NODE Node; + unsigned short ID; // NetworkID / BouquetID + struct LIST *Descriptors; + struct LIST *TransportStreams; +}; + +#define CreateNetworkInfo(ni, id) \ + do { \ + xCreateNode (ni, NULL); \ + (ni)->ID = id; \ + (ni)->Descriptors = xNewList(NULL); \ + (ni)->TransportStreams = NULL; \ + } while(0) + +/* TransportStream structure (NIT/BAT TS loop member) */ + +struct TransportStream { + struct NODE Node; + int TransportStreamID; + unsigned short OriginalNetworkID; + struct LIST *Descriptors; +}; + +#define CreateTransportStream(ts, tsid, onid) \ + do { \ + xCreateNode (ts, NULL); \ + (ts)->TransportStreamID = tsid; \ + (ts)->OriginalNetworkID = onid; \ + (ts)->Descriptors = xNewList(NULL); \ + } while(0) + /* Strukturen zur Aufnahme der SDT und EIT Informationen */ struct Service { @@ -305,38 +342,32 @@ struct PidInfo { #define STREAMTYPE_13818_D 13 #define STREAMTYPE_13818_AUX 14 -/* Descriptors */ - -#define DescriptorTag(x) ((struct Descriptor *)(x))->Tag -struct Descriptor { - struct NODE Node; - unsigned short Tag; +struct Tot { + time_t UTC; + time_t Bias; + struct LIST *Descriptors; }; +#define CreateTot(tot, utc) \ + do \ + { \ + xMemAlloc(sizeof(struct Tot), &tot); \ + tot->UTC = utc; \ + tot->Bias = ((utc - time(NULL) + 1800)/3600)*3600; \ + tot->Descriptors = xNewList(NULL); \ + } while (0) -/* ConditionalAccessDescriptor */ -struct ConditionalAccessDescriptor { +/* Descriptors */ + +#define DescriptorTag(x) ((struct Descriptor *)(x))->Tag + +struct Descriptor { struct NODE Node; unsigned short Tag; - unsigned short Amount; /* Data */ - unsigned char *Data; }; -#define CreateConditionalAccessDescriptor(descr, amount, data) \ - do \ - { \ - unsigned char *tmpptr; \ - \ - xMemAlloc (amount, &tmpptr); \ - memcpy (tmpptr, data, amount); \ - xCreateNode (((struct ConditionalAccessDescriptor *)descr), NULL); \ - ((struct ConditionalAccessDescriptor *)descr)->Tag = DESCR_CA; \ - ((struct ConditionalAccessDescriptor *)descr)->Amount = amount; \ - ((struct ConditionalAccessDescriptor *)descr)->Data = tmpptr; \ - } while (0) - /* Iso639LanguageDescriptor */ @@ -434,19 +465,23 @@ struct AncillaryDataDescriptor { /* BouquetNameDescriptor */ +/* + the same used instead of NetworkNameDescriptor because their structures + are identical. We pass 'tag' parameter to distinguish between them later +*/ struct BouquetNameDescriptor { struct NODE Node; /* Node enthält Namen */ unsigned short Tag; }; -#define CreateBouquetNameDescriptor(descr, text) \ +#define CreateBouquetNameDescriptor(descr, text, tag) \ do \ { \ xCreateNode (((struct BouquetNameDescriptor *)descr), NULL); \ ((struct NODE *)descr)->Name = text; \ ((struct NODE *)descr)->HashKey = xHashKey (text); \ - ((struct BouquetNameDescriptor *)descr)->Tag = DESCR_BOUQUET_NAME; \ + ((struct BouquetNameDescriptor *)descr)->Tag = tag; \ } while (0) @@ -514,6 +549,33 @@ struct CaIdentifierDescriptor { ((struct CaIdentifierDescriptor *)descr)->SystemID[num] = id #define GetCaIdentifierID(descr, num) (((struct CaIdentifierDescriptor *)descr)->SystemID[num]) +/* CaDescriptor */ + +struct CaDescriptor { + struct NODE Node; + unsigned short Tag; + unsigned short CA_type; + unsigned short CA_PID; + unsigned int ProviderID; + unsigned short DataLength; + unsigned char *Data; +}; + +#define CreateCaDescriptor(descr, typ, capid, len) \ + do \ + { \ + xCreateNode (((struct CaDescriptor *)descr), NULL); \ + ((struct CaDescriptor *)descr)->Tag = DESCR_CA; \ + ((struct CaDescriptor *)descr)->CA_type = typ; \ + ((struct CaDescriptor *)descr)->CA_PID = capid; \ + ((struct CaDescriptor *)descr)->ProviderID = 0; \ + ((struct CaDescriptor *)descr)->DataLength = len; \ + xMemAlloc (len+1, &((struct CaDescriptor *)descr)->Data); \ + } while (0) + +#define SetCaData(descr, num, id) \ + ((struct CaDescriptor *)descr)->Data[num] = id +#define GetCaData(descr, num) (((struct CaDescriptor *)descr)->Data[num]) /* StreamIdentifierDescriptor */ @@ -968,6 +1030,122 @@ struct SubtitlingItem { xAddTail (((struct SubtitlingDescriptor *)desc)->Items, item); \ } while (0) +/* SatelliteDeliverySystemDescriptor */ + +struct SatelliteDeliverySystemDescriptor { + struct NODE Node; + unsigned short Tag; + long Frequency; + short OrbitalPosition; + char Polarization; + long SymbolRate; + char FEC; +}; + +#define CreateSatelliteDeliverySystemDescriptor(descr, freq, orb, polar, sr, fec) \ + do \ + { \ + xCreateNode (((struct SatelliteDeliverySystemDescriptor *)descr), NULL); \ + ((struct SatelliteDeliverySystemDescriptor *)descr)->Tag = DESCR_SAT_DEL_SYS; \ + ((struct SatelliteDeliverySystemDescriptor *)descr)->Frequency = freq; \ + ((struct SatelliteDeliverySystemDescriptor *)descr)->OrbitalPosition = orb; \ + ((struct SatelliteDeliverySystemDescriptor *)descr)->Polarization = polar; \ + ((struct SatelliteDeliverySystemDescriptor *)descr)->SymbolRate = sr; \ + ((struct SatelliteDeliverySystemDescriptor *)descr)->FEC = fec; \ + } while (0) + +/* ServiceListDescriptor */ + +struct ServiceListDescriptor { + struct NODE Node; + unsigned short Tag; + struct LIST *ServiceList; +}; + +#define CreateServiceListDescriptor(descr) \ + do \ + { \ + xCreateNode (((struct ServiceListDescriptor *)descr), NULL); \ + ((struct ServiceListDescriptor *)descr)->Tag = DESCR_SERVICE_LIST; \ + ((struct ServiceListDescriptor *)descr)->ServiceList = xNewList(NULL); \ + } while (0) + +struct ServiceListEntry { + struct NODE Node; + int ServiceID; + unsigned short ServiceType; +}; + +#define AddServiceListEntry(descr, id, typ) \ + do \ + { \ + struct ServiceListEntry *newent; \ + \ + xCreateNode (newent, NULL); \ + newent->ServiceID = id; \ + newent->ServiceType = typ; \ + xAddTail (((struct ServiceListDescriptor *)descr)->ServiceList, newent); \ + } while (0) + +/* LocalTimeOffsetDescriptor */ + +struct LocalTimeOffsetDescriptor { + struct NODE Node; + unsigned short Tag; + struct LIST *LocalTimeOffsets; +}; + +#define CreateLocalTimeOffsetDescriptor(descr) \ + do \ + { \ + xCreateNode (((struct LocalTimeOffsetDescriptor *)descr), NULL); \ + ((struct LocalTimeOffsetDescriptor *)descr)->Tag = DESCR_LOCAL_TIME_OFF; \ + ((struct LocalTimeOffsetDescriptor *)descr)->LocalTimeOffsets = xNewList(NULL); \ + } while (0) + +struct LocalTimeOffsetEntry { + struct NODE Node; + char CountryCode[4]; + char RegionID; + time_t CurrentOffset; + time_t ChangeTime; + time_t NextOffset; +}; + +#define CreateLocalTimeOffsetEntry(newent, code1, code2, code3, reg, co, ct, no) \ + do \ + { \ + xCreateNode (newent, NULL); \ + newent->CountryCode[0] = code1; \ + newent->CountryCode[1] = code2; \ + newent->CountryCode[2] = code3; \ + newent->CountryCode[3] = '\0'; \ + newent->RegionID = reg; \ + newent->CurrentOffset = co; \ + newent->ChangeTime = ct; \ + newent->NextOffset = no; \ + } while (0) + +#define AddLocalTimeOffsetEntry(descr, code1, code2, code3, reg, co, ct, no) \ + do \ + { \ + struct LocalTimeOffsetEntry *newent; \ + \ + xCreateNode (newent, NULL); \ + newent->CountryCode[0] = code1; \ + newent->CountryCode[1] = code2; \ + newent->CountryCode[2] = code3; \ + newent->CountryCode[3] = '\0'; \ + newent->RegionID = reg; \ + newent->CurrentOffset = co; \ + newent->ChangeTime = ct; \ + newent->NextOffset = no; \ + xAddTail (((struct LocalTimeOffsetDescriptor *)descr)->LocalTimeOffsets, newent); \ + } while (0) + +#define timezonecmp(ptoe,cod,reg) \ + (strncmp(ptoe->CountryCode, cod, 3) || (ptoe->RegionID != reg)) + /* Prototypes */ @@ -979,13 +1157,17 @@ extern "C" { /* si_parser.c */ struct LIST *siParsePAT (u_char *); +struct LIST *siParseCAT (u_char *); struct Pid *siParsePMT (u_char *); struct LIST *siParseSDT (u_char *); +struct LIST *siParseNIT (u_char *); struct LIST *siParseEIT (u_char *); time_t siParseTDT (u_char *); +struct Tot *siParseTOT (u_char *); void siParseDescriptors (struct LIST *, u_char *, int, u_char); void siParseDescriptor (struct LIST *, u_char *); char *siGetDescriptorText (u_char *, int); +char *siGetDescriptorName (u_char *, int); u_long crc32 (char *data, int len); /* si_debug_services.c */ @@ -999,6 +1181,8 @@ void siDebugPids (char *, struct LIST *); void siDebugDescriptors (char *, struct LIST *); void siDebugEitServices (struct LIST *); void siDebugEitEvents (char *, struct LIST *); +void siDumpDescriptor (void *); +void siDumpSection (void *); #ifdef __cplusplus } diff --git a/libdtv/libsi/include/si_tables.h b/libdtv/libsi/include/si_tables.h index dfda3bf..b7cfea2 100644 --- a/libdtv/libsi/include/si_tables.h +++ b/libdtv/libsi/include/si_tables.h @@ -5,11 +5,13 @@ /// /// ////////////////////////////////////////////////////////////// -// $Revision: 1.3 $ -// $Date: 2001/10/07 10:24:46 $ +// $Revision: 1.4 $ +// $Date: 2003/02/04 18:45:36 $ // $Author: hakenes $ // -// (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. +// (C) 2001-03 Rolf Hakenes <hakenes@hippomi.de>, under the +// GNU GPL with contribution of Oleg Assovski, +// www.satmania.com // // libsi is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -32,12 +34,22 @@ #define BcdTimeToSeconds(x) ((3600 * ((10*((x##_h & 0xF0)>>4)) + (x##_h & 0xF))) + \ (60 * ((10*((x##_m & 0xF0)>>4)) + (x##_m & 0xF))) + \ ((10*((x##_s & 0xF0)>>4)) + (x##_s & 0xF))) +#define BcdTimeToMinutes(x) ((60 * ((10*((x##_h & 0xF0)>>4)) + (x##_h & 0xF))) + \ + (((10*((x##_m & 0xF0)>>4)) + (x##_m & 0xF)))) +#define BcdCharToInt(x) (10*((x & 0xF0)>>4) + (x & 0xF)) +#define CheckBcdChar(x) ((((x & 0xF0)>>4) <= 9) && \ + ((x & 0x0F) <= 9)) +#define CheckBcdSignedChar(x) ((((x & 0xF0)>>4) >= 0) && (((x & 0xF0)>>4) <= 9) && \ + ((x & 0x0F) >= 0) && ((x & 0x0F) <= 9)) #define TableHasMoreSections(x) (((pat_t *)(x))->last_section_number > ((pat_t *)(x))->section_number) #define GetTableId(x) ((pat_t *)(x))->table_id #define GetSectionNumber(x) ((pat_t *)(x))->section_number #define GetLastSectionNumber(x) ((pat_t *)(x))->last_section_number #define GetServiceId(x) (((eit_t *)(x))->service_id_hi << 8) | ((eit_t *)(x))->service_id_lo +#define GetSegmentLastSectionNumber(x) ((eit_t *)(x))->segment_last_section_number +#define GetLastTableId(x) ((eit_t *)(x))->segment_last_table_id +#define GetSectionLength(x) HILO(((pat_t *)(x))->section_length) /* * @@ -113,7 +125,37 @@ typedef struct { * applicable. * */ - /* TO BE DONE */ +#define CAT_LEN 8 + +typedef struct { + u_char table_id :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char section_syntax_indicator :1; + u_char dummy :1; // has to be 0 + u_char :2; + u_char section_length_hi :4; +#else + u_char section_length_hi :4; + u_char :2; + u_char dummy :1; // has to be 0 + u_char section_syntax_indicator :1; +#endif + u_char section_length_lo :8; + u_char reserved_1 :8; + u_char reserved_2 :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char :2; + u_char version_number :5; + u_char current_next_indicator :1; +#else + u_char current_next_indicator :1; + u_char version_number :5; + u_char :2; +#endif + u_char section_number :8; + u_char last_section_number :8; +} cat_t; + /* * * 3) Program Map Table (PMT): @@ -297,7 +339,7 @@ typedef struct { * bouquet. * */ - /* TO BE DONE */ +/* SEE NIT (It has the same structure but has different allowed descriptors) */ /* * * 2) Service Description Table (SDT): @@ -339,6 +381,9 @@ typedef struct { u_char :8; } sdt_t; +#define GetSDTTransportStreamId(x) (HILO(((sdt_t *) x)->transport_stream_id)) +#define GetSDTOriginalNetworkId(x) (HILO(((sdt_t *) x)->original_network_id)) + #define SDT_DESCR_LEN 5 typedef struct { @@ -483,7 +528,36 @@ typedef struct { * to the frequent updating of the time information. * */ - /* TO BE DONE */ +#define TOT_LEN 10 + +typedef struct { + u_char table_id :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char section_syntax_indicator :1; + u_char :3; + u_char section_length_hi :4; +#else + u_char section_length_hi :4; + u_char :3; + u_char section_syntax_indicator :1; +#endif + u_char section_length_lo :8; + u_char utc_mjd_hi :8; + u_char utc_mjd_lo :8; + u_char utc_time_h :8; + u_char utc_time_m :8; + u_char utc_time_s :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char :4; + u_char descriptors_loop_length_hi :4; +#else + u_char descriptors_loop_length_hi :4; + u_char :4; +#endif + u_char descriptors_loop_length_lo :8; +} tot_t; + + /* * * 7) Stuffing Table (ST): @@ -545,6 +619,25 @@ typedef struct descr_gen_struct { #define GetDescriptorLength(x) (((descr_gen_t *) x)->descriptor_length+DESCR_GEN_LEN) +/* 0x09 ca_descriptor */ + +#define DESCR_CA_LEN 6 +typedef struct descr_ca_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + u_char CA_type_hi :8; + u_char CA_type_lo :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char reserved :3; + u_char CA_PID_hi :5; +#else + u_char CA_PID_hi :5; + u_char reserved :3; +#endif + u_char CA_PID_lo :8; +} descr_ca_t; +#define CastCaDescriptor(x) ((descr_ca_t *)(x)) + /* 0x0A iso_639_language_descriptor */ #define DESCR_ISO_639_LANGUAGE_LEN 5 @@ -560,25 +653,31 @@ typedef struct descr_iso_639_language_struct { /* 0x40 network_name_descriptor */ -#define DESCR_NETWORK_NAME_LEN XX +#define DESCR_NETWORK_NAME_LEN 2 typedef struct descr_network_name_struct { u_char descriptor_tag :8; u_char descriptor_length :8; - /* TBD */ } descr_network_name_t; #define CastNetworkNameDescriptor(x) ((descr_network_name_t *)(x)) /* 0x41 service_list_descriptor */ -#define DESCR_SERVICE_LIST_LEN XX +#define DESCR_SERVICE_LIST_LEN 2 typedef struct descr_service_list_struct { u_char descriptor_tag :8; u_char descriptor_length :8; - /* TBD */ } descr_service_list_t; #define CastServiceListDescriptor(x) ((descr_service_list_t *)(x)) +#define DESCR_SERVICE_LIST_LOOP_LEN 3 +typedef struct descr_service_list_loop_struct { + u_char service_id_hi :8; + u_char service_id_lo :8; + u_char service_type :8; +} descr_service_list_loop_t; +#define CastServiceListDescriptorLoop(x) ((descr_service_list_loop_t *)(x)) + /* 0x42 stuffing_descriptor */ @@ -604,13 +703,13 @@ typedef struct descr_satellite_delivery_system_struct { u_char orbital_position1 :8; u_char orbital_position2 :8; #if BYTE_ORDER == BIG_ENDIAN - u_char modulation :5; - u_char polarization :2; - u_char west_east_flag :1; -#else u_char west_east_flag :1; u_char polarization :2; u_char modulation :5; +#else + u_char modulation :5; + u_char polarization :2; + u_char west_east_flag :1; #endif u_char symbol_rate1 :8; u_char symbol_rate2 :8; @@ -964,14 +1063,39 @@ typedef struct descr_telephone_struct { /* 0x58 local_time_offset_descriptor */ -#define DESCR_LOCAL_TIME_OFFSET_LEN XX +#define DESCR_LOCAL_TIME_OFFSET_LEN 2 typedef struct descr_local_time_offset_struct { u_char descriptor_tag :8; u_char descriptor_length :8; - /* TBD */ } descr_local_time_offset_t; #define CastLocalTimeOffsetDescriptor(x) ((descr_local_time_offset_t *)(x)) +#define LOCAL_TIME_OFFSET_ENTRY_LEN 15 +typedef struct local_time_offset_entry_struct { + u_char country_code1 :8; + u_char country_code2 :8; + u_char country_code3 :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char country_region_id :6; + u_char :1; + u_char local_time_offset_polarity :1; +#else + u_char local_time_offset_polarity :1; + u_char :1; + u_char country_region_id :6; +#endif + u_char local_time_offset_h :8; + u_char local_time_offset_m :8; + u_char time_of_change_mjd_hi :8; + u_char time_of_change_mjd_lo :8; + u_char time_of_change_time_h :8; + u_char time_of_change_time_m :8; + u_char time_of_change_time_s :8; + u_char next_time_offset_h :8; + u_char next_time_offset_m :8; +} local_time_offset_entry_t ; +#define CastLocalTimeOffsetEntry(x) ((local_time_offset_entry_t *)(x)) + /* 0x59 subtitling_descriptor */ diff --git a/libdtv/libsi/si_debug_services.c b/libdtv/libsi/si_debug_services.c index ae2a92a..ac8de34 100644 --- a/libdtv/libsi/si_debug_services.c +++ b/libdtv/libsi/si_debug_services.c @@ -4,11 +4,13 @@ /// /// ////////////////////////////////////////////////////////////// -// $Revision: 1.4 $ -// $Date: 2001/10/07 10:24:46 $ +// $Revision: 1.5 $ +// $Date: 2003/02/04 18:45:35 $ // $Author: hakenes $ // -// (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. +// (C) 2001-03 Rolf Hakenes <hakenes@hippomi.de>, under the +// GNU GPL with contribution of Oleg Assovski, +// www.satmania.com // // libsi is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -26,11 +28,13 @@ // Boston, MA 02111-1307, USA. #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <time.h> #include "../liblx/liblx.h" #include "libsi.h" +#include "si_tables.h" #include "si_debug_services.h" @@ -208,6 +212,8 @@ void siDebugPids (char *Prepend, struct LIST *PidList) printf ("%s ProgramID: %d\n", Prepend, Pid->ProgramID); printf ("%s PcrPid: %d\n", Prepend, Pid->PcrPID); printf ("%s PmtVersion: %d\n", Prepend, Pid->PmtVersion); + sprintf (NewPrepend, "%s ", Prepend); + siDebugDescriptors (NewPrepend, Pid->Descriptors); xForeach (Pid->InfoList, PidInfo) { @@ -256,6 +262,11 @@ void siDebugDescriptors (char *Prepend, struct LIST *Descriptors) printf ("\n"); break; + case DESCR_NW_NAME: + printf ("%sDescriptor: Network Name\n", Prepend); + printf ("%s Name: %s\n", Prepend, xName (Descriptor)); + break; + case DESCR_BOUQUET_NAME: printf ("%sDescriptor: Bouquet Name\n", Prepend); printf ("%s Name: %s\n", Prepend, xName (Descriptor)); @@ -336,12 +347,38 @@ void siDebugDescriptors (char *Prepend, struct LIST *Descriptors) case DESCR_CA_IDENT: printf ("%sDescriptor: Conditional Access Identity\n", Prepend); { - int j; + int j,k; for (j = 0; j < ((struct CaIdentifierDescriptor *)Descriptor)->Amount; j++) - printf ("%s SystemID: 0x%04x\n", Prepend, GetCaIdentifierID (Descriptor, j)); + { + printf ("%s SystemID: 0x%04x", Prepend, GetCaIdentifierID (Descriptor, j)); + k = GetCaIdentifierID (Descriptor, j) >> 8; + if (k < 0 || k > MAX_CA_IDENT) printf (" (unknown)\n"); + else printf (" (%s)\n", CaIdents[k]); + } } break; + case DESCR_CA: + { + int j,k; + + printf ("%sDescriptor: Conditional Access\n", Prepend); + printf ("%s CA type: 0x%04x", Prepend, (((struct CaDescriptor *)Descriptor)->CA_type)); + k = (((struct CaDescriptor *)Descriptor)->CA_type) >> 8; + if (k < 0 || k > MAX_CA_IDENT) printf (" (unknown)\n"); + else printf (" (%s)\n", CaIdents[k]); + printf ("%s CA PID: %d\n", Prepend, (((struct CaDescriptor *)Descriptor)->CA_PID)); + printf ("%s ProviderID: 0x%04X\n", Prepend, (((struct CaDescriptor *)Descriptor)->ProviderID)); + if (((struct CaDescriptor *)Descriptor)->DataLength > 0) + { + printf ("%s CA data:", Prepend); + for (j = 0; j < ((struct CaDescriptor *)Descriptor)->DataLength; j++) + printf (" 0x%02x", GetCaData (Descriptor, j)); + printf ("\n"); + } + } + break; + case DESCR_CONTENT: printf ("%sDescriptor: Content\n", Prepend); { @@ -489,16 +526,57 @@ void siDebugDescriptors (char *Prepend, struct LIST *Descriptors) } break; - case DESCR_NW_NAME: + case DESCR_SAT_DEL_SYS: + { + struct SatelliteDeliverySystemDescriptor *sds = + (struct SatelliteDeliverySystemDescriptor *)Descriptor; + + printf ("%sDescriptor: Satellite Delivery System\n", Prepend); + printf ("%s Frequency: %ld\n", Prepend, sds->Frequency); + printf ("%s OrbitalPosition: %d\n", Prepend, sds->OrbitalPosition); + printf ("%s Polarization: %c\n", Prepend, sds->Polarization); + printf ("%s SymbolRate: %ld\n", Prepend, sds->SymbolRate); + printf ("%s FEC: %c\n", Prepend, sds->FEC); + } + break; + case DESCR_SERVICE_LIST: + { + struct ServiceListEntry *Entry; + + printf ("%sDescriptor: Service List\n", Prepend); + xForeach (((struct ServiceListDescriptor *)Descriptor)->ServiceList, Entry) + { + printf ("%s Entry:\n"); + printf ("%s ServiceID: %d\n", Prepend, Entry->ServiceID); + printf ("%s ServiceType: %04x\n", Prepend, Entry->ServiceType); + } + } + break; + + case DESCR_LOCAL_TIME_OFF: + { + struct LocalTimeOffsetEntry *Offset; + + printf ("%sDescriptor: Local Time Offset\n", Prepend); + xForeach (((struct LocalTimeOffsetDescriptor *)Descriptor)->LocalTimeOffsets, Offset) + { + printf ("%s Offset:\n"); + printf ("%s CountryCode: %s\n", Offset->CountryCode); + printf ("%s RegionID: %c\n", Offset->RegionID); + printf ("%s CurrentOffset: %ld\n", Offset->CurrentOffset); + printf ("%s ChangeTime: %ld\n", Offset->ChangeTime); + printf ("%s NextOffset: %ld\n", Offset->NextOffset); + } + } + break; + case DESCR_STUFFING: - case DESCR_SAT_DEL_SYS: case DESCR_CABLE_DEL_SYS: case DESCR_VBI_DATA: case DESCR_VBI_TELETEXT: case DESCR_MOSAIC: case DESCR_TELEPHONE: - case DESCR_LOCAL_TIME_OFF: case DESCR_TERR_DEL_SYS: case DESCR_ML_NW_NAME: case DESCR_ML_BQ_NAME: @@ -527,3 +605,39 @@ void siDebugDescriptors (char *Prepend, struct LIST *Descriptors) return; } +void siDumpDescriptor (void * Descriptor) +{ + int Length, i; + unsigned char *ptr; + + Length = GetDescriptorLength (Descriptor); + for (i = 0, ptr = (char*) Descriptor; i < Length; i++) { + if ((i % 8) == 0) + printf ("\n"); + printf ("0x%02X ", (unsigned int) ptr[i]); + } + printf ( "\n"); +} + +void siDumpSection (void *Section) +{ + int Length, i; + unsigned char *ptr; + char str[9]; + + Length = GetSectionLength (Section) + 3; + for (i = 0, ptr = (unsigned char*) Section, memset (str, 0, 9); i < Length; i++) { + if ((i % 8) == 0) + { + printf (" %s\n", str); + memset (str, 0, 8); + } + printf ("0x%02X ", (unsigned int) ptr[i]); + if (ptr[i] < 0x20 || (ptr[i] > 'z' && ptr[i] < ((unsigned char )'Ā')) ) + str[i % 8] = '.'; + else + str[i % 8] = ptr[i]; + } + printf (" %*s\n", (8 - ((abs(i - 1) % 8) ? (abs(i - 1) % 8) : 8)) * 5, str); +} + diff --git a/libdtv/libsi/si_debug_services.h b/libdtv/libsi/si_debug_services.h index cd4f196..404f3c7 100644 --- a/libdtv/libsi/si_debug_services.h +++ b/libdtv/libsi/si_debug_services.h @@ -4,8 +4,8 @@ /// /// ////////////////////////////////////////////////////////////// -// $Revision: 1.1 $ -// $Date: 2001/06/25 12:29:47 $ +// $Revision: 1.2 $ +// $Date: 2003/02/04 18:45:35 $ // $Author: hakenes $ // // (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. @@ -197,7 +197,7 @@ static struct content_type ContentTypes[] = { }; #define CONTENT_TYPE_NUMBER 79 -static char StreamTypes[][70] = { +static char *StreamTypes[] = { "ITU-T|ISO/IEC Reserved", "ISO/IEC Video", "13818-2 Video or 11172-2 constrained parameter video stream", @@ -215,3 +215,31 @@ static char StreamTypes[][70] = { "ITU-T Rec. H.222.0 | ISO 13818-1 Reserved", "User private" }; + +static char *CaIdents[] = { + "Standardized systems", + "Canal Plus", + "CCETT", + "Deutsche Telecom", + "Eurodec", + "France Telecom", + "Irdeto", + "Jerrold/GI", + "Matra Communication", + "News Datacom", + "Nokia", + "Norwegian Telekom", + "NTL", + "Philips", + "Scientific Atlanta", + "Sony", + "Tandberg Television", + "Thomson", + "TV/Com", + "HPT - Croatian Post and Telecommunications", + "HRT - Croatian Radio and Television", + "IBM", + "Nera", + "BetaTechnik" +}; +#define MAX_CA_IDENT 24 diff --git a/libdtv/libsi/si_parser.c b/libdtv/libsi/si_parser.c index ccca6e5..e8cf8b2 100644 --- a/libdtv/libsi/si_parser.c +++ b/libdtv/libsi/si_parser.c @@ -4,11 +4,13 @@ /// /// ////////////////////////////////////////////////////////////// -// $Revision: 1.6 $ -// $Date: 2002/01/30 17:04:13 $ +// $Revision: 1.8 $ +// $Date: 2003/02/04 18:45:35 $ // $Author: hakenes $ // -// (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. +// (C) 2001-03 Rolf Hakenes <hakenes@hippomi.de>, under the +// GNU GPL with contribution of Oleg Assovski, +// www.satmania.com // // libsi is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -52,7 +54,7 @@ struct LIST *siParsePAT (u_char *Buffer) Pat = (pat_t *) Buffer; Ptr = Buffer; if (Pat->table_id != TID_PAT) { -// fprintf (stderr, "PAT: wrong TID %d\n", Pat->table_id); + // fprintf (stderr, "PAT: wrong TID %d\n", Pat->table_id); return NULL; } @@ -83,6 +85,43 @@ struct LIST *siParsePAT (u_char *Buffer) } +struct LIST *siParseCAT (u_char *Buffer) +{ + cat_t *Cat; + u_char *Ptr; + int SectionLength; + int TransportStreamID; + int CatVersion; + struct Descriptor *Descriptor; + struct LIST *DescriptorList = NULL; + + if (!Buffer) return NULL; + + Cat = (cat_t *) Buffer; Ptr = Buffer; + + if (Cat->table_id != TID_CAT) { + // fprintf (stderr, "CAT: wrong TID %d\n", Cat->table_id); + return NULL; + } + + SectionLength = HILO (Cat->section_length) + 3 - CAT_LEN - 4; + + if (crc32 (Ptr, HILO (Cat->section_length) + 3)) return (NULL); + + CatVersion = Cat->version_number; + + Ptr += CAT_LEN; + + if (SectionLength >= 0) + { + DescriptorList = xNewList (NULL); + siParseDescriptors (DescriptorList, Ptr, SectionLength, Cat->table_id); + } + + return (DescriptorList); +} + + struct Pid *siParsePMT (u_char *Buffer) { pmt_t *Pmt; @@ -101,7 +140,7 @@ struct Pid *siParsePMT (u_char *Buffer) Pmt = (pmt_t *) Buffer; Ptr = Buffer; if (Pmt->table_id != TID_PMT) { -// fprintf (stderr, "PMT: wrong TID %d\n", Pmt->table_id); + // fprintf (stderr, "PMT: wrong TID %d\n", Pmt->table_id); return NULL; } @@ -147,6 +186,89 @@ struct Pid *siParsePMT (u_char *Buffer) } +struct LIST *siParseNIT (u_char *Buffer) +{ + nit_t *Nit; + nit_mid_t *NitMid; + nit_ts_t *TSDesc; + u_char *Ptr; + int SectionLength, LoopLength, Loop2Length; + int TransportStreamID; + int NitVersion; + int NetworkID; + struct TransportStream *TransportStream; + struct LIST *TSList = NULL; + struct LIST *Networks; + struct NetworkInfo *Network; + + if (!Buffer) return NULL; + + Nit = (nit_t *) Buffer; + Ptr = Buffer; + + if (Nit->table_id != TID_NIT_ACT && Nit->table_id != TID_NIT_OTH && Nit->table_id != TID_BAT) { + return NULL; + } + + SectionLength = HILO (Nit->section_length) + 3 - NIT_LEN - 4; + + if (crc32 (Ptr, HILO (Nit->section_length) + 3)) return (NULL); + + NitVersion = Nit->version_number; + NetworkID = HILO (Nit->network_id); + if (NetworkID == 65535) + NetworkID = 0; + CreateNetworkInfo (Network, NetworkID); + Networks = xNewList (NULL); + xAddTail (Networks, Network); + + Ptr += NIT_LEN; + + LoopLength = HILO (Nit->network_descriptor_length); +// fprintf (stderr, "table 0x%X, SectionLen = %d, LoopLen = %d\n", +// Nit->table_id, SectionLength, LoopLength); + if (LoopLength > SectionLength - SDT_DESCR_LEN) + return (Networks); + + if (LoopLength <= SectionLength) { + if (SectionLength >= 0) siParseDescriptors (Network->Descriptors, Ptr, LoopLength, Nit->table_id); + SectionLength -= LoopLength; + Ptr += LoopLength; + NitMid = (nit_mid_t *) Ptr; + LoopLength = HILO (NitMid->transport_stream_loop_length); +// fprintf (stderr, "table 0x%X, TS LoopLen = %d\n", +// Nit->table_id, LoopLength); + if ((SectionLength > 0) && (LoopLength <= SectionLength)) { + SectionLength -= SIZE_NIT_MID; + Ptr += SIZE_NIT_MID; + while (LoopLength > 0) { + TSDesc = (nit_ts_t *) Ptr; + CreateTransportStream (TransportStream, HILO(TSDesc->transport_stream_id), HILO(TSDesc->original_network_id)); + if (TransportStream->TransportStreamID == 65535) + TransportStream->TransportStreamID = 0; + if (TransportStream->OriginalNetworkID == 65535) + TransportStream->OriginalNetworkID = 0; + Loop2Length = HILO (TSDesc->transport_descriptors_length); +// fprintf (stderr, "table 0x%X, TSdesc LoopLen = %d\n", +// Nit->table_id, Loop2Length); + Ptr += NIT_TS_LEN; + if (Loop2Length <= LoopLength) { + if (LoopLength >= 0) siParseDescriptors (TransportStream->Descriptors, Ptr, Loop2Length, Nit->table_id); + } + if (!Network->TransportStreams) + Network->TransportStreams = xNewList (NULL); + xAddTail (Network->TransportStreams, TransportStream); + LoopLength -= Loop2Length + NIT_TS_LEN; + SectionLength -= Loop2Length + NIT_TS_LEN; + Ptr += Loop2Length; + } + } + } + + return (Networks); +} + + struct LIST *siParseSDT (u_char *Buffer) { sdt_t *Sdt; @@ -164,7 +286,7 @@ struct LIST *siParseSDT (u_char *Buffer) Sdt = (sdt_t *) Buffer; Ptr = Buffer; if (Sdt->table_id != TID_SDT_ACT && Sdt->table_id != TID_SDT_OTH) { -// fprintf (stderr, "SDT: wrong TID %d\n", Sdt->table_id); + // fprintf (stderr, "SDT: wrong TID %d\n", Sdt->table_id); return NULL; } @@ -250,7 +372,7 @@ struct LIST *siParseEIT (u_char *Buffer) Eit->table_id <= TID_EIT_ACT_SCH + 0x0F) && !(Eit->table_id >= TID_EIT_OTH_SCH && Eit->table_id <= TID_EIT_OTH_SCH + 0x0F)) { -// fprintf (stderr, "EIT: wrong TID %d\n", Eit->table_id); + // fprintf (stderr, "EIT: wrong TID %d\n", Eit->table_id); return NULL; } @@ -331,7 +453,7 @@ time_t siParseTDT (u_char *Buffer) Tdt = (tdt_t *) Buffer; Ptr = Buffer; if (Tdt->table_id != TID_TDT) { -// fprintf (stderr, "TDT: wrong TID %d\n", Tdt->table_id); + // fprintf (stderr, "TDT: wrong TID %d\n", Tdt->table_id); return 0; } @@ -344,6 +466,44 @@ time_t siParseTDT (u_char *Buffer) } +struct Tot *siParseTOT (u_char *Buffer) +{ + tot_t *Tot; + u_char *Ptr; + int SectionLength, LoopLength; + struct Tot *table; + time_t CurrentTime; + + if (!Buffer) return NULL; + + Tot = (tot_t *) Buffer; + Ptr = Buffer; + + if (Tot->table_id != TID_TOT) { + return NULL; + } + + if (crc32 (Ptr, HILO (Tot->section_length) + 3)) return (NULL); +// SectionLength = HILO (Tot->section_length) + 3 - TOT_LEN - 4; + + CurrentTime = MjdToEpochTime (Tot->utc_mjd) + + BcdTimeToSeconds (Tot->utc_time); + LoopLength = HILO (Tot->descriptors_loop_length); + if (!LoopLength) + return NULL; + + CreateTot (table, CurrentTime); + + Ptr += TOT_LEN; + + siParseDescriptors (table->Descriptors, Ptr, LoopLength, Tot->table_id); + + // fprintf (stderr, "TOT Bias: %d\n", table->Bias); + return (table); +} + +static u_char TempTableID = 0; + void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer, int Length, u_char TableID) { @@ -352,6 +512,7 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer, DescriptorLength = 0; Ptr = Buffer; + TempTableID = TableID; while (DescriptorLength < Length) { @@ -362,15 +523,17 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer, case TID_NIT_ACT: case TID_NIT_OTH: switch (GetDescriptorTag(Ptr)) { - case DESCR_NW_NAME: - case DESCR_SERVICE_LIST: - case DESCR_STUFFING: case DESCR_SAT_DEL_SYS: case DESCR_CABLE_DEL_SYS: + case DESCR_SERVICE_LIST: + case DESCR_PRIV_DATA_SPEC: +// fprintf (stderr, "Got descriptor with tag = 0x%X\n", GetDescriptorTag(Ptr)); +// siDumpDescriptor (Ptr); + case DESCR_NW_NAME: + case DESCR_STUFFING: case DESCR_LINKAGE: case DESCR_TERR_DEL_SYS: case DESCR_ML_NW_NAME: - case DESCR_PRIV_DATA_SPEC: case DESCR_CELL_LIST: case DESCR_CELL_FREQ_LINK: case DESCR_ANNOUNCEMENT_SUPPORT: @@ -378,8 +541,7 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer, break; default: - /* fprintf (stderr, "forbidden descriptor 0x%x in NIT\n", - GetDescriptorTag(Ptr));*/ + // fprintf (stderr, "forbidden descriptor 0x%x in NIT\n", GetDescriptorTag(Ptr)); break; } break; @@ -396,12 +558,12 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer, case DESCR_CA_IDENT: case DESCR_ML_BQ_NAME: case DESCR_PRIV_DATA_SPEC: + // fprintf (stderr, "Got descriptor with tag = 0x%X\n", GetDescriptorTag(Ptr)); siParseDescriptor (Descriptors, Ptr); break; default: - /*fprintf (stderr, "forbidden descriptor 0x%x in BAT\n", - GetDescriptorTag(Ptr));*/ + // fprintf (stderr, "forbidden descriptor 0x%x in BAT\n", GetDescriptorTag(Ptr)); break; } break; @@ -426,8 +588,7 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer, break; default: - /* fprintf (stderr, "forbidden descriptor 0x%x in SDT\n", - GetDescriptorTag(Ptr)); */ + // fprintf (stderr, "forbidden descriptor 0x%x in SDT\n", GetDescriptorTag(Ptr)); break; } break; @@ -470,8 +631,7 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer, break; default: - /*fprintf (stderr, "forbidden descriptor 0x%x in EIT\n", - GetDescriptorTag(Ptr));*/ + // fprintf (stderr, "forbidden descriptor 0x%x in EIT\n", GetDescriptorTag(Ptr)); break; } break; @@ -484,8 +644,7 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer, break; default: - /*fprintf (stderr, "forbidden descriptor 0x%x in TOT\n", - GetDescriptorTag(Ptr));*/ + // fprintf (stderr, "forbidden descriptor 0x%x in TOT\n", GetDescriptorTag(Ptr)); break; } break; @@ -522,15 +681,28 @@ void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer, break; default: - /* fprintf (stderr, "forbidden descriptor 0x%x in PMT\n", - GetDescriptorTag(Ptr)); */ + // fprintf (stderr, "forbidden descriptor 0x%x in PMT\n", GetDescriptorTag(Ptr)); + break; + } + break; + + case TID_CAT: + switch (GetDescriptorTag(Ptr)) + { + case DESCR_CA_SYSTEM: + case DESCR_CA: + case DESCR_CA_IDENT: + siParseDescriptor (Descriptors, Ptr); + break; + + default: + // fprintf (stderr, "forbidden descriptor 0x%x in CAT\n", GetDescriptorTag(Ptr)); break; } break; default: - fprintf (stderr, "descriptor 0x%x in unsupported table 0x%x\n", - GetDescriptorTag(Ptr), TableID); + // fprintf (stderr, "descriptor 0x%x in unsupported table 0x%x\n", GetDescriptorTag(Ptr), TableID); break; } DescriptorLength += GetDescriptorLength (Ptr); @@ -550,6 +722,7 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) if (!Descriptors || !Buffer) return; Ptr = Buffer; +// fprintf (stderr, "Got descriptor with tag = 0x%X\n", GetDescriptorTag(Buffer)); switch (GetDescriptorTag(Buffer)) { @@ -558,10 +731,12 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) CastAncillaryDataDescriptor(Buffer)->ancillary_data_identifier); break; + case DESCR_NW_NAME: case DESCR_BOUQUET_NAME: - Text = siGetDescriptorText (Buffer + DESCR_BOUQUET_NAME_LEN, + Text = siGetDescriptorName (Buffer + DESCR_BOUQUET_NAME_LEN, GetDescriptorLength (Buffer) - DESCR_BOUQUET_NAME_LEN); - CreateBouquetNameDescriptor (Descriptor, Text); +// fprintf (stderr, "Got descriptor with tag = 0x%X, text = '%s'\n", GetDescriptorTag(Buffer), Text); + CreateBouquetNameDescriptor (Descriptor, Text, GetDescriptorTag(Buffer)); break; case DESCR_COMPONENT: @@ -577,9 +752,9 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) break; case DESCR_SERVICE: - Text = siGetDescriptorText (Buffer + DESCR_SERVICE_LEN, + Text = siGetDescriptorName (Buffer + DESCR_SERVICE_LEN, CastServiceDescriptor(Buffer)->provider_name_length); - Text2 = siGetDescriptorText (Buffer + DESCR_SERVICE_LEN + + Text2 = siGetDescriptorName (Buffer + DESCR_SERVICE_LEN + CastServiceDescriptor(Buffer)->provider_name_length + 1, *((u_char *)(Buffer + DESCR_SERVICE_LEN + CastServiceDescriptor(Buffer)->provider_name_length))); @@ -598,7 +773,7 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) break; case DESCR_SHORT_EVENT: - Text = siGetDescriptorText (Buffer + DESCR_SHORT_EVENT_LEN, + Text = siGetDescriptorName (Buffer + DESCR_SHORT_EVENT_LEN, CastShortEventDescriptor(Buffer)->event_name_length); Text2 = siGetDescriptorText (Buffer + DESCR_SHORT_EVENT_LEN + CastShortEventDescriptor(Buffer)->event_name_length + 1, @@ -623,6 +798,7 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) CastExtendedEventDescriptor(Buffer)->lang_code3, Text); Length = CastExtendedEventDescriptor(Buffer)->length_of_items; Ptr += DESCR_EXTENDED_EVENT_LEN; +// printf ("EEDesc #%d, %s\n", CastExtendedEventDescriptor(Buffer)->descriptor_number, Text); while ((Length > 0) && (Length < GetDescriptorLength (Buffer))) { Text = siGetDescriptorText (Ptr + ITEM_EXTENDED_EVENT_LEN, @@ -631,6 +807,7 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) CastExtendedEventItem(Ptr)->item_description_length + 1, *((u_char *)(Ptr + ITEM_EXTENDED_EVENT_LEN + CastExtendedEventItem(Ptr)->item_description_length))); +// printf ("EEItem #%d, %s, %s\n", CastExtendedEventDescriptor(Buffer)->descriptor_number, Text, Text2); AddExtendedEventItem (Descriptor, Text2, Text); Length -= ITEM_EXTENDED_EVENT_LEN + CastExtendedEventItem(Ptr)->item_description_length + *((u_char *)(Ptr + ITEM_EXTENDED_EVENT_LEN + @@ -642,15 +819,85 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) break; case DESCR_CA_IDENT: - CreateCaIdentifierDescriptor (Descriptor, - (GetDescriptorLength(Buffer) - DESCR_CA_IDENTIFIER_LEN) / 2); Length = GetDescriptorLength (Buffer) - DESCR_CA_IDENTIFIER_LEN; + CreateCaIdentifierDescriptor (Descriptor, Length / 2); Ptr += DESCR_CA_IDENTIFIER_LEN; i = 0; while (Length > 0) - { SetCaIdentifierID(Descriptor, i, *((u_short *) Ptr)); + { SetCaIdentifierID(Descriptor, i, ((*((u_char *) Ptr)<<8) + *((u_char *) (Ptr+1)))); Length -= 2; Ptr += 2; i++; } break; + case DESCR_CA: + { + struct CaDescriptor *CD; + + Length = GetDescriptorLength (Buffer) - DESCR_CA_LEN; + CreateCaDescriptor (Descriptor, + HILO(CastCaDescriptor(Buffer)->CA_type), + HILO(CastCaDescriptor(Buffer)->CA_PID), Length); + Ptr += DESCR_CA_LEN; i = 0; + while (Length > 0) + { SetCaData(Descriptor, i, *Ptr); + Length --; Ptr ++; i++; } + + /* + * The following analyses are more or less directly copied from + * MultiDec 8.4b Sources. Thanx to Espresso for his great work !! + */ + CD = (struct CaDescriptor *) Descriptor; + + // fprintf (stderr, "TableID: %02x - CA - Type: 0x%04x, PID: %d\n", TempTableID, CD->CA_type, CD->CA_PID); + + if ((CD->CA_type >> 8) == 0x01) /* SECA */ + { + CD->ProviderID = (GetCaData (CD, 0) << 8) | GetCaData (CD, 1); + } + else if ((CD->CA_type >> 8) == 0x05) /* Viaccess ? (France Telecom) */ + { + i=0; + while (i < CD->DataLength) + { + if ((GetCaData (CD, i) == 0x14) && (GetCaData (CD, i+1) == 0x03)) + { + CD->ProviderID = (GetCaData (CD, i+2) << 16) | + (GetCaData (CD, i+3) << 8) | + (GetCaData (CD, i+4) & 0xf0); + i = CD->DataLength; + } + i++; + } + } + if (CD->CA_type==0x0100) /* SECA 1 */ + { + /* bptr=MyPtr+19; + + i=19; + while ( i+4 < ca_info->len ) { + if ( (*bptr&0xE0) == 0xE0 ) { + CA_ECM=(( *bptr&0x1f)<<8)+*(bptr+1); + Prov_Ident = ( *(bptr+2)<<8) | *(bptr+3); + j=0; + while ( j < ProgrammNeu[ProgrammNummer].CA_Anzahl ) { + if (( ProgrammNeu[ProgrammNummer].CA_System[j].CA_Typ == CA_Typ ) + && ( ProgrammNeu[ProgrammNummer].CA_System[j].ECM == CA_ECM )) break; + j++; + }; + + if ( j < MAX_CA_SYSTEMS ) { + if ( j >= ProgrammNeu[ProgrammNummer].CA_Anzahl ) + ProgrammNeu[ProgrammNummer].CA_Anzahl++; + ProgrammNeu[ProgrammNummer].CA_System[j].CA_Typ =CA_Typ; + ProgrammNeu[ProgrammNummer].CA_System[j].ECM =CA_ECM ; + ProgrammNeu[ProgrammNummer].CA_System[j].Provider_Id = Prov_Ident; + }; + } + i+=0x0f; + bptr+=0x0f; + }; */ + } + } + break; + case DESCR_CONTENT: CreateContentDescriptor (Descriptor, (GetDescriptorLength(Buffer) - DESCR_CONTENT_LEN) / 2); @@ -705,12 +952,6 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) HILO (CastTimeShiftedEventDescriptor(Ptr)->reference_event_id)); break; - case DESCR_CA: - CreateConditionalAccessDescriptor (Descriptor, - *(Ptr + 1) + 2, // we'll need the entire raw data! - Ptr); - break; - case DESCR_ISO_639_LANGUAGE: CreateIso639LanguageDescriptor (Descriptor, CastIso639LanguageDescriptor(Buffer)->lang_code1, @@ -789,6 +1030,80 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) } break; + case DESCR_SAT_DEL_SYS: +// fprintf (stderr, "got descriptor 0x%x\n", GetDescriptorTag(Buffer)); + { + descr_satellite_delivery_system_t *sds; + sds = (descr_satellite_delivery_system_t *) Ptr; + if (CheckBcdChar (sds->frequency1) && CheckBcdChar (sds->frequency2) && + CheckBcdChar (sds->frequency3) && CheckBcdChar (sds->frequency4) && + CheckBcdChar (sds->orbital_position1) && + CheckBcdChar (sds->orbital_position2) && + CheckBcdChar (sds->symbol_rate1) && CheckBcdChar (sds->symbol_rate1) && + CheckBcdChar (sds->symbol_rate3) && (sds->fec_inner != 0) && (sds->modulation == 1)) + { + CreateSatelliteDeliverySystemDescriptor (Descriptor, + BcdCharToInt (sds->frequency1) * 10 * 1000 * 1000 + + BcdCharToInt (sds->frequency2) * 100 * 1000 + + BcdCharToInt (sds->frequency3) * 1000 + + BcdCharToInt (sds->frequency4) * 10, + (sds->west_east_flag ? 1 : -1) * + (BcdCharToInt (sds->orbital_position1) * 100 + + BcdCharToInt (sds->orbital_position2)), + sds->polarization, + BcdCharToInt (sds->symbol_rate1) * 10 * 1000 + + BcdCharToInt (sds->symbol_rate2) * 100 + + BcdCharToInt (sds->symbol_rate3), + sds->fec_inner); + } + /* else + { + fprintf (stderr, "Illegal sds descriptor\n"); + siDumpDescriptor (Buffer); + } */ + } + break; + + case DESCR_SERVICE_LIST: +// fprintf (stderr, "got descriptor 0x%x\n", GetDescriptorTag(Buffer)); + CreateServiceListDescriptor (Descriptor); + Length = GetDescriptorLength (Buffer) - DESCR_SERVICE_LIST_LEN; + Ptr += DESCR_SERVICE_LIST_LEN; + while (Length > 0) + { + AddServiceListEntry (Descriptor, + HILO (CastServiceListDescriptorLoop(Ptr)->service_id), + CastServiceListDescriptorLoop(Ptr)->service_type); + Length -= DESCR_SERVICE_LIST_LEN; + Ptr += DESCR_SERVICE_LIST_LEN; + } + break; + + case DESCR_LOCAL_TIME_OFF: + CreateLocalTimeOffsetDescriptor (Descriptor); + Length = GetDescriptorLength (Buffer) - DESCR_LOCAL_TIME_OFFSET_LEN; + Ptr += DESCR_LOCAL_TIME_OFFSET_LEN; + while (Length > 0) + { + time_t ct, co, no; + ct = MjdToEpochTime (CastLocalTimeOffsetEntry(Ptr)->time_of_change_mjd) + + BcdTimeToSeconds (CastLocalTimeOffsetEntry(Ptr)->time_of_change_time); + co = (BcdCharToInt(CastLocalTimeOffsetEntry(Ptr)->local_time_offset_h) * 3600 + + BcdCharToInt(CastLocalTimeOffsetEntry(Ptr)->local_time_offset_m) * 60) * + ((CastLocalTimeOffsetEntry(Ptr)->local_time_offset_polarity) ? -1 : 1); + no = (BcdCharToInt(CastLocalTimeOffsetEntry(Ptr)->next_time_offset_h) * 3600 + + BcdCharToInt(CastLocalTimeOffsetEntry(Ptr)->next_time_offset_m) * 60) * + ((CastLocalTimeOffsetEntry(Ptr)->local_time_offset_polarity) ? -1 : 1); + AddLocalTimeOffsetEntry (Descriptor, + CastLocalTimeOffsetEntry(Ptr)->country_code1, + CastLocalTimeOffsetEntry(Ptr)->country_code2, + CastLocalTimeOffsetEntry(Ptr)->country_code3, + CastLocalTimeOffsetEntry(Ptr)->country_region_id, co, ct, no); + Length -= LOCAL_TIME_OFFSET_ENTRY_LEN; + Ptr += LOCAL_TIME_OFFSET_ENTRY_LEN; + } + break; + case DESCR_VIDEO_STREAM: case DESCR_AUDIO_STREAM: case DESCR_HIERARCHY: @@ -804,15 +1119,11 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) case DESCR_SMOOTHING_BUFFER: case DESCR_STD: case DESCR_IBP: - case DESCR_NW_NAME: - case DESCR_SERVICE_LIST: - case DESCR_SAT_DEL_SYS: case DESCR_CABLE_DEL_SYS: case DESCR_VBI_DATA: case DESCR_VBI_TELETEXT: case DESCR_MOSAIC: case DESCR_TELEPHONE: - case DESCR_LOCAL_TIME_OFF: case DESCR_TERR_DEL_SYS: case DESCR_ML_NW_NAME: case DESCR_ML_BQ_NAME: @@ -833,6 +1144,8 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) case DESCR_CELL_FREQ_LINK: case DESCR_ANNOUNCEMENT_SUPPORT: default: +// fprintf (stderr, "Unsupported descriptor with tag = 0x%02X\n", GetDescriptorTag(Ptr)); +// siDumpDescriptor (Buffer); /* fprintf (stderr, "unsupported descriptor 0x%x\n", GetDescriptorTag(Buffer)); */ break; @@ -845,14 +1158,19 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) /* * ToDo: ETSI conformal text definition */ -char *siGetDescriptorText (u_char *Buffer, int Length) +#define GDT_TEXT_DESCRIPTOR 0 +#define GDT_NAME_DESCRIPTOR 1 +char *siGetDescriptorTextHandler (u_char *, int , int ); + +char *siGetDescriptorTextHandler (u_char *Buffer, int Length, int type) { char *tmp, *result; int i; if ((Length < 0) || (Length > 4095)) return (xSetText ("text error")); - if (*Buffer == 0x05 || (*Buffer >= 0x20 && *Buffer <= 0xff)) +/* ASSENIZATION: removing coding detection - suppose they are all ANSI */ + // if (*Buffer == 0x05 || (*Buffer >= 0x20 && *Buffer <= 0xff)) { xMemAlloc (Length+1, &result); tmp = result; @@ -860,15 +1178,16 @@ char *siGetDescriptorText (u_char *Buffer, int Length) { if (*Buffer == 0) break; - if ((*Buffer >= ' ' && *Buffer <= '~') || + if ((*Buffer >= ' ' && *Buffer <= '~') || (*Buffer == '\n') || (*Buffer >= 0xa0 && *Buffer <= 0xff)) *tmp++ = *Buffer; - if (*Buffer == 0x8A || *Buffer == '\n') *tmp++ = '\n'; + if (*Buffer == 0x8A) *tmp++ = '\n'; if (*Buffer == 0x86 || *Buffer == 0x87) *tmp++ = ' '; + if ((*Buffer == 0x86 || *Buffer == 0x87) && !(GDT_NAME_DESCRIPTOR & type)) *tmp++ = ' '; Buffer++; } *tmp = '\0'; } - else + /* else { switch (*Buffer) { @@ -881,11 +1200,22 @@ char *siGetDescriptorText (u_char *Buffer, int Length) case 0x12: result = xSetText ("Coding according to KSC 5601"); break; default: result = xSetText ("Unknown coding"); break; } - } + } */ return (result); } +char *siGetDescriptorText (u_char *Buffer, int Length) +{ + return siGetDescriptorTextHandler (Buffer, Length, GDT_TEXT_DESCRIPTOR); +} + +char *siGetDescriptorName (u_char *Buffer, int Length) +{ + return siGetDescriptorTextHandler (Buffer, Length, GDT_NAME_DESCRIPTOR); +} + + // CRC32 lookup table for polynomial 0x04c11db7 static u_long crc_table[256] = { |