diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2001-04-01 18:00:00 +0200 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2001-04-01 18:00:00 +0200 |
commit | 610c5600df98b35226536ffe92b1fd231128c7d4 (patch) | |
tree | f0df8ce83dd3e4829be7def61126871f425e2f23 /eit.c | |
parent | f2937af95ceaf3a52c327e96571367ef5475b3a1 (diff) | |
download | vdr-patch-lnbsharing-610c5600df98b35226536ffe92b1fd231128c7d4.tar.gz vdr-patch-lnbsharing-610c5600df98b35226536ffe92b1fd231128c7d4.tar.bz2 |
Version 0.72vdr-0.72
- Fixed SVDRP commands LSTC and LSTT to make them return an error message if
no channels or timers are defined.
- Enhanced 'channels.conf.cable' (thanks to Hans-Peter Raschke).
- Fixed switching to another channel via the EPG while a recording is being
replayed.
- Fixed a memory leak in the EIT processor that happened when the system time
was set.
- Removed some redundant code from the cListBase destructor.
- Fixed internationalization of some Main menu texts.
- Updated 'channels.conf' after the recent changes of Premiere World (thanks
to Axel Gruber).
- Redesigned the ring buffer to make it work with two separate threads for
input and output (also prepared for using a remultiplexer).
- Fixed setting system time from transponders.
- Fixed a segfault in the Schedule menu in case there is no EPG information.
- The 'runvdr' script now kills any leftover vdr threads before restarting it.
- Fixed a problem with Daylight Saving Time when displaying the times of
recordings.
- Added Dutch language texts (thanks to Arnold Niessen).
- The new command line option -t can be used to set the controlling terminal
(thanks to Jürgen Sauer). This is especially useful when starting VDR through
an entry in /etc/inittab (see INSTALL).
- Since the CAM module only works if it is installed in the "highest" DVB card,
recordings now search for a free DVB card from lowest to highest index (as
opposed to the previous "highest to lowest" search) in order to not use the
CAM card for FTA recordings unless necessary. This is only important for
systems with three or more DVB cards.
- Added the "statdvb2vdr" tool from Hans-Peter Raschke.
- Fixed a segfault that sometimes happened when killing VDR.
- VDR now returns an exit status of '2' in case of an error at startup, instead
of terminating with 'abort()' (which caused a core dump).
- SVDRP now also works with clients that don't do line buffering (like the
Windows 'telnet').
- Empty lines in config files no longer cause error messages.
- New SVDRP command LSTE to list the EPG data.
- The SVDRP HELP command now prints the topics in several columns.
Diffstat (limited to 'eit.c')
-rw-r--r-- | eit.c | 1452 |
1 files changed, 727 insertions, 725 deletions
@@ -13,7 +13,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: eit.c 1.12 2001/02/24 12:12:58 kls Exp $ + * $Id: eit.c 1.15 2001/04/01 15:36:09 kls Exp $ ***************************************************************************/ #include "eit.h" @@ -39,11 +39,11 @@ // --- cMJD ------------------------------------------------------------------ class cMJD { -public: - cMJD(); - cMJD(u_char date_hi, u_char date_lo); - cMJD(u_char date_hi, u_char date_lo, u_char timehr, u_char timemi, u_char timese); - ~cMJD(); +public: + cMJD(); + cMJD(u_char date_hi, u_char date_lo); + cMJD(u_char date_hi, u_char date_lo, u_char timehr, u_char timemi, u_char timese); + ~cMJD(); /** */ void ConvertToTime(); /** */ @@ -73,18 +73,18 @@ cMJD::cMJD() cMJD::cMJD(u_char date_hi, u_char date_lo) { - mjd = date_hi << 8 | date_lo; - time_hour = time_minute = time_second = 0; - ConvertToTime(); + mjd = date_hi << 8 | date_lo; + time_hour = time_minute = time_second = 0; + ConvertToTime(); } cMJD::cMJD(u_char date_hi, u_char date_lo, u_char timehr, u_char timemi, u_char timese) { - mjd = date_hi << 8 | date_lo; - time_hour = timehr; - time_minute = timemi; - time_second = timese; - ConvertToTime(); + mjd = date_hi << 8 | date_lo; + time_hour = timehr; + time_minute = timemi; + time_second = timese; + ConvertToTime(); } cMJD::~cMJD() @@ -94,103 +94,102 @@ cMJD::~cMJD() /** */ void cMJD::ConvertToTime() { - struct tm t; - - t.tm_sec = time_second; - t.tm_min = time_minute; - t.tm_hour = time_hour; - int k; - - t.tm_year = (int) ((mjd - 15078.2) / 365.25); - t.tm_mon = (int) ((mjd - 14956.1 - (int)(t.tm_year * 365.25)) / 30.6001); - t.tm_mday = (int) (mjd - 14956 - (int)(t.tm_year * 365.25) - (int)(t.tm_mon * 30.6001)); - k = (t.tm_mon == 14 || t.tm_mon == 15) ? 1 : 0; - t.tm_year = t.tm_year + k; - t.tm_mon = t.tm_mon - 1 - k * 12; - t.tm_mon--; - - t.tm_isdst = -1; - t.tm_gmtoff = 0; - - mjdtime = timegm(&t); - - //isyslog(LOG_INFO, "Time parsed = %s\n", ctime(&mjdtime)); + struct tm t; + + t.tm_sec = time_second; + t.tm_min = time_minute; + t.tm_hour = time_hour; + int k; + + t.tm_year = (int) ((mjd - 15078.2) / 365.25); + t.tm_mon = (int) ((mjd - 14956.1 - (int)(t.tm_year * 365.25)) / 30.6001); + t.tm_mday = (int) (mjd - 14956 - (int)(t.tm_year * 365.25) - (int)(t.tm_mon * 30.6001)); + k = (t.tm_mon == 14 || t.tm_mon == 15) ? 1 : 0; + t.tm_year = t.tm_year + k; + t.tm_mon = t.tm_mon - 1 - k * 12; + t.tm_mon--; + + t.tm_isdst = -1; + t.tm_gmtoff = 0; + + mjdtime = timegm(&t); + + //isyslog(LOG_INFO, "Time parsed = %s\n", ctime(&mjdtime)); } /** */ bool cMJD::SetSystemTime() { - struct tm *ptm; - time_t loctim; - - ptm = localtime(&mjdtime); - loctim = time(NULL); - - if (abs(mjdtime - loctim) > 2) - { - isyslog(LOG_INFO, "System Time = %s (%ld)\n", ctime(&loctim), loctim); - isyslog(LOG_INFO, "Local Time = %s (%ld)\n", ctime(&mjdtime), mjdtime); - if (stime(&mjdtime) < 0) + struct tm *ptm; + time_t loctim; + + ptm = localtime(&mjdtime); + loctim = time(NULL); + + if (abs(mjdtime - loctim) > 2) + { + isyslog(LOG_INFO, "System Time = %s (%ld)\n", ctime(&loctim), loctim); + isyslog(LOG_INFO, "Local Time = %s (%ld)\n", ctime(&mjdtime), mjdtime); + if (stime(&mjdtime) < 0) esyslog(LOG_ERR, "ERROR while setting system time: %m"); - return true; - } - - return false; + return true; + } + + return false; } /** */ time_t cMJD::GetTime_t() { - return mjdtime; + return mjdtime; } // --- cTDT ------------------------------------------------------------------ typedef struct { - u_char table_id : 8; + 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; + 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; + u_char section_length_hi : 4; + u_char : 3; + u_char section_syntax_indicator : 1; #endif - u_char section_length_lo : 8; + u_char section_length_lo : 8; - u_char utc_date_hi : 8; - u_char utc_date_lo : 8; - u_char utc_hour : 4; - u_char utc_hour_ten : 4; - u_char utc_min : 4; - u_char utc_min_ten : 4; - u_char utc_sec : 4; - u_char utc_sec_ten : 4; + u_char utc_date_hi : 8; + u_char utc_date_lo : 8; + u_char utc_hour : 4; + u_char utc_hour_ten : 4; + u_char utc_min : 4; + u_char utc_min_ten : 4; + u_char utc_sec : 4; + u_char utc_sec_ten : 4; } tdt_t; class cTDT { -public: - cTDT(tdt_t *ptdt); - ~cTDT(); +public: + cTDT(tdt_t *ptdt); + ~cTDT(); /** */ bool SetSystemTime(); protected: // Protected attributes /** */ tdt_t tdt; /** */ - cMJD * mjd; + cMJD mjd; // kls 2001-03-02: made this a member instead of a pointer (it wasn't deleted in the destructor!) }; cTDT::cTDT(tdt_t *ptdt) +:tdt(*ptdt) +,mjd(tdt.utc_date_hi, tdt.utc_date_lo, tdt.utc_hour_ten * 10 + tdt.utc_hour, + tdt.utc_min_ten * 10 + tdt.utc_min, + tdt.utc_sec_ten * 10 + tdt.utc_sec) { - tdt = *ptdt; - mjd = new cMJD(tdt.utc_date_hi, tdt.utc_date_lo, - tdt.utc_hour_ten * 10 + tdt.utc_hour, - tdt.utc_min_ten * 10 + tdt.utc_min, - tdt.utc_sec_ten * 10 + tdt.utc_sec); } cTDT::~cTDT() @@ -199,22 +198,22 @@ cTDT::~cTDT() /** */ bool cTDT::SetSystemTime() { - return mjd->SetSystemTime(); + return mjd.SetSystemTime(); } // --- cEventInfo ------------------------------------------------------------ cEventInfo::cEventInfo(unsigned short serviceid, unsigned short eventid) { - pTitle = NULL; - pSubtitle = NULL; - pExtendedDescription = NULL; - bIsPresent = bIsFollowing = false; - lDuration = 0; - tTime = 0; - uEventID = eventid; - uServiceID = serviceid; - cExtendedDescriptorNumber = 0; + pTitle = NULL; + pSubtitle = NULL; + pExtendedDescription = NULL; + bIsPresent = bIsFollowing = false; + lDuration = 0; + tTime = 0; + uEventID = eventid; + uServiceID = serviceid; + cExtendedDescriptorNumber = 0; nChannelNumber = 0; } @@ -228,165 +227,165 @@ cEventInfo::~cEventInfo() /** */ const char * cEventInfo::GetTitle() const { - return pTitle; + return pTitle; } /** */ const char * cEventInfo::GetSubtitle() const { - return pSubtitle; + return pSubtitle; } /** */ const char * cEventInfo::GetExtendedDescription() const { - return pExtendedDescription; + return pExtendedDescription; } /** */ bool cEventInfo::IsPresent() const { - return bIsPresent; + return bIsPresent; } /** */ void cEventInfo::SetPresent(bool pres) { - bIsPresent = pres; + bIsPresent = pres; } /** */ bool cEventInfo::IsFollowing() const { - return bIsFollowing; + return bIsFollowing; } /** */ void cEventInfo::SetFollowing(bool foll) { - bIsFollowing = foll; + bIsFollowing = foll; } /** */ const char * cEventInfo::GetDate() const { - static char szDate[25]; + static char szDate[25]; - strftime(szDate, sizeof(szDate), "%d.%m.%Y", localtime(&tTime)); + strftime(szDate, sizeof(szDate), "%d.%m.%Y", localtime(&tTime)); - return szDate; + return szDate; } /** */ const char * cEventInfo::GetTimeString() const { - static char szTime[25]; - - strftime(szTime, sizeof(szTime), "%R", localtime(&tTime)); - - return szTime; + static char szTime[25]; + + strftime(szTime, sizeof(szTime), "%R", localtime(&tTime)); + + return szTime; } /** */ const char * cEventInfo::GetEndTimeString() const { - static char szEndTime[25]; + static char szEndTime[25]; time_t tEndTime = tTime + lDuration; - - strftime(szEndTime, sizeof(szEndTime), "%R", localtime(&tEndTime)); - - return szEndTime; + + strftime(szEndTime, sizeof(szEndTime), "%R", localtime(&tEndTime)); + + return szEndTime; } /** */ time_t cEventInfo::GetTime() const { - return tTime; + return tTime; } /** */ long cEventInfo::GetDuration() const { - return lDuration; + return lDuration; } /** */ unsigned short cEventInfo::GetEventID() const { - return uEventID; + return uEventID; } /** */ bool cEventInfo::SetTitle(char *string) { - if (string == NULL) - return false; - - pTitle = strdup(string); - if (pTitle == NULL) - return false; - - return true; + if (string == NULL) + return false; + + pTitle = strdup(string); + if (pTitle == NULL) + return false; + + return true; } /** */ bool cEventInfo::SetSubtitle(char *string) { - if (string == NULL) - return false; - - pSubtitle = strdup(string); - if (pSubtitle == NULL) - return false; - - return true; + if (string == NULL) + return false; + + pSubtitle = strdup(string); + if (pSubtitle == NULL) + return false; + + return true; } /** */ bool cEventInfo::AddExtendedDescription(char *string) { - int size = 0; - bool first = true; - char *p; - - if (string == NULL) - return false; - - if (pExtendedDescription) - { - first = false; - size += strlen(pExtendedDescription); - } - - size += (strlen(string) + 1); - - p = (char *)realloc(pExtendedDescription, size); - if (p == NULL) - return false; - - if (first) - *p = 0; - - strcat(p, string); - - pExtendedDescription = p; - - return true; + int size = 0; + bool first = true; + char *p; + + if (string == NULL) + return false; + + if (pExtendedDescription) + { + first = false; + size += strlen(pExtendedDescription); + } + + size += (strlen(string) + 1); + + p = (char *)realloc(pExtendedDescription, size); + if (p == NULL) + return false; + + if (first) + *p = 0; + + strcat(p, string); + + pExtendedDescription = p; + + return true; } /** */ void cEventInfo::SetTime(time_t t) { - tTime = t; + tTime = t; } /** */ void cEventInfo::SetDuration(long l) { - lDuration = l; + lDuration = l; } /** */ void cEventInfo::SetEventID(unsigned short evid) { - uEventID = evid; + uEventID = evid; } /** */ void cEventInfo::SetServiceID(unsigned short servid) { - uServiceID = servid; + uServiceID = servid; } /** */ u_char cEventInfo::GetExtendedDescriptorNumber() const { - return cExtendedDescriptorNumber; + return cExtendedDescriptorNumber; } /** */ void cEventInfo::IncreaseExtendedDescriptorNumber() { - cExtendedDescriptorNumber++; + cExtendedDescriptorNumber++; } /** */ @@ -396,17 +395,17 @@ unsigned short cEventInfo::GetServiceID() const } /** */ -void cEventInfo::Dump(FILE *f) const +void cEventInfo::Dump(FILE *f, const char *Prefix) const { if (tTime + lDuration >= time(NULL)) { - fprintf(f, "E %u %ld %ld\n", uEventID, tTime, lDuration); + fprintf(f, "%sE %u %ld %ld\n", Prefix, uEventID, tTime, lDuration); if (!isempty(pTitle)) - fprintf(f, "T %s\n", pTitle); + fprintf(f, "%sT %s\n", Prefix, pTitle); if (!isempty(pSubtitle)) - fprintf(f, "S %s\n", pSubtitle); + fprintf(f, "%sS %s\n", Prefix, pSubtitle); if (!isempty(pExtendedDescription)) - fprintf(f, "D %s\n", pExtendedDescription); - fprintf(f, "e\n"); + fprintf(f, "%sD %s\n", Prefix, pExtendedDescription); + fprintf(f, "%se\n", Prefix); } } @@ -414,8 +413,8 @@ void cEventInfo::Dump(FILE *f) const cSchedule::cSchedule(unsigned short servid) { - pPresent = pFollowing = NULL; - uServiceID = servid; + pPresent = pFollowing = NULL; + uServiceID = servid; } @@ -429,15 +428,15 @@ const cEventInfo * cSchedule::GetPresentEvent() const time_t now = time(NULL); if (pPresent && !(pPresent->GetTime() <= now && now <= pPresent->GetTime() + pPresent->GetDuration())) { - cEventInfo *pe = Events.First(); - while (pe != NULL) - { - if (pe->GetTime() <= now && now <= pe->GetTime() + pe->GetDuration()) + cEventInfo *pe = Events.First(); + while (pe != NULL) + { + if (pe->GetTime() <= now && now <= pe->GetTime() + pe->GetDuration()) return pe; pe = Events.Next(pe); - } + } } - return pPresent; + return pPresent; } /** */ const cEventInfo * cSchedule::GetFollowingEvent() const @@ -451,111 +450,111 @@ const cEventInfo * cSchedule::GetFollowingEvent() const cEventInfo *pe = Events.First(), *pf = NULL; while (pe != NULL) { - int dt = pe->GetTime() - now; - if (dt > 0 && dt < minDt) + int dt = pe->GetTime() - now; + if (dt > 0 && dt < minDt) { minDt = dt; pf = pe; } - pe = Events.Next(pe); + pe = Events.Next(pe); } return pf; } - return pFollowing; + return pFollowing; } /** */ void cSchedule::SetServiceID(unsigned short servid) { - uServiceID = servid; + uServiceID = servid; } /** */ unsigned short cSchedule::GetServiceID() const { - return uServiceID; + return uServiceID; } /** */ const cEventInfo * cSchedule::GetEvent(unsigned short uEventID) const { - cEventInfo *pe = Events.First(); - while (pe != NULL) - { - if (pe->GetEventID() == uEventID) - return pe; - - pe = Events.Next(pe); - } - - return NULL; + cEventInfo *pe = Events.First(); + while (pe != NULL) + { + if (pe->GetEventID() == uEventID) + return pe; + + pe = Events.Next(pe); + } + + return NULL; } /** */ const cEventInfo * cSchedule::GetEvent(time_t tTime) const { - cEventInfo *pe = Events.First(); - while (pe != NULL) - { - if (pe->GetTime() == tTime) - return pe; - - pe = Events.Next(pe); - } - - return NULL; + cEventInfo *pe = Events.First(); + while (pe != NULL) + { + if (pe->GetTime() == tTime) + return pe; + + pe = Events.Next(pe); + } + + return NULL; } /** */ bool cSchedule::SetPresentEvent(cEventInfo *pEvent) { - if (pPresent != NULL) - pPresent->SetPresent(false); - pPresent = pEvent; - pPresent->SetPresent(true); - - return true; + if (pPresent != NULL) + pPresent->SetPresent(false); + pPresent = pEvent; + pPresent->SetPresent(true); + + return true; } /** */ bool cSchedule::SetFollowingEvent(cEventInfo *pEvent) { - if (pFollowing != NULL) - pFollowing->SetFollowing(false); - pFollowing = pEvent; - pFollowing->SetFollowing(true); - - return true; + if (pFollowing != NULL) + pFollowing->SetFollowing(false); + pFollowing = pEvent; + pFollowing->SetFollowing(true); + + return true; } /** */ void cSchedule::Cleanup() { - Cleanup(time(NULL)); + Cleanup(time(NULL)); } /** */ void cSchedule::Cleanup(time_t tTime) { - cEventInfo *pEvent; - for (int a = 0; true ; a++) - { - pEvent = Events.Get(a); - if (pEvent == NULL) - break; - if (pEvent->GetTime() + pEvent->GetDuration() < tTime) - { - Events.Del(pEvent); - a--; - } - } + cEventInfo *pEvent; + for (int a = 0; true ; a++) + { + pEvent = Events.Get(a); + if (pEvent == NULL) + break; + if (pEvent->GetTime() + pEvent->GetDuration() < tTime) + { + Events.Del(pEvent); + a--; + } + } } /** */ -void cSchedule::Dump(FILE *f) const +void cSchedule::Dump(FILE *f, const char *Prefix) const { cChannel *channel = Channels.GetByServiceID(uServiceID); if (channel) { - fprintf(f, "C %u %s\n", uServiceID, channel->name); + fprintf(f, "%sC %u %s\n", Prefix, uServiceID, channel->name); for (cEventInfo *p = Events.First(); p; p = Events.Next(p)) - p->Dump(f); - fprintf(f, "c\n"); + p->Dump(f, Prefix); + fprintf(f, "%sc\n", Prefix); } } @@ -563,8 +562,8 @@ void cSchedule::Dump(FILE *f) const cSchedules::cSchedules() { - pCurrentSchedule = NULL; - uCurrentServiceID = 0; + pCurrentSchedule = NULL; + uCurrentServiceID = 0; } cSchedules::~cSchedules() @@ -573,58 +572,58 @@ cSchedules::~cSchedules() /** */ bool cSchedules::SetCurrentServiceID(unsigned short servid) { - pCurrentSchedule = GetSchedule(servid); - if (pCurrentSchedule == NULL) - { - Add(new cSchedule(servid)); - pCurrentSchedule = GetSchedule(servid); - if (pCurrentSchedule == NULL) - return false; - } - - uCurrentServiceID = servid; - - return true; + pCurrentSchedule = GetSchedule(servid); + if (pCurrentSchedule == NULL) + { + Add(new cSchedule(servid)); + pCurrentSchedule = GetSchedule(servid); + if (pCurrentSchedule == NULL) + return false; + } + + uCurrentServiceID = servid; + + return true; } /** */ const cSchedule * cSchedules::GetSchedule() const { - return pCurrentSchedule; + return pCurrentSchedule; } /** */ const cSchedule * cSchedules::GetSchedule(unsigned short servid) const { - cSchedule *p; - - p = First(); - while (p != NULL) - { - if (p->GetServiceID() == servid) - return p; - p = Next(p); - } - - return NULL; + cSchedule *p; + + p = First(); + while (p != NULL) + { + if (p->GetServiceID() == servid) + return p; + p = Next(p); + } + + return NULL; } /** */ void cSchedules::Cleanup() { - cSchedule *p; - - p = First(); - while (p != NULL) - { - p->Cleanup(time(NULL)); - p = Next(p); - } + cSchedule *p; + + p = First(); + while (p != NULL) + { + p->Cleanup(time(NULL)); + p = Next(p); + } } /** */ -void cSchedules::Dump(FILE *f) const +void cSchedules::Dump(FILE *f, const char *Prefix) const { for (cSchedule *p = First(); p; p = Next(p)) - p->Dump(f); + p->Dump(f, Prefix); } // --- cEIT ------------------------------------------------------------------ @@ -632,136 +631,136 @@ void cSchedules::Dump(FILE *f) const #define DEC(N) dec << setw(N) << setfill(int('0')) #define HEX(N) hex << setw(N) << setfill(int('0')) -#define EIT_STUFFING_DESCRIPTOR 0x42 -#define EIT_LINKAGE_DESCRIPTOR 0x4a -#define EIT_SHORT_EVENT_DESCRIPTOR 0x4d -#define EIT_EXTENDED_EVENT_DESCRIPTOR 0x4e -#define EIT_TIME_SHIFTED_EVENT_DESCRIPTOR 0x4f -#define EIT_COMPONENT_DESCRIPTOR 0x50 -#define EIT_CA_IDENTIFIER_DESCRIPTOR 0x53 -#define EIT_CONTENT_DESCRIPTOR 0x54 -#define EIT_PARENTAL_RATING_DESCRIPTOR 0x55 -#define EIT_TELEPHONE_DESCRIPTOR 0x57 -#define EIT_MULTILINGUAL_COMPONENT_DESCRIPTOR 0x5e -#define EIT_PRIVATE_DATE_SPECIFIER_DESCRIPTOR 0x5f -#define EIT_SHORT_SMOOTHING_BUFFER_DESCRIPTOR 0x61 -#define EIT_DATA_BROADCAST_DESCRIPTOR 0x64 -#define EIT_PDC_DESCRIPTOR 0x69 +#define EIT_STUFFING_DESCRIPTOR 0x42 +#define EIT_LINKAGE_DESCRIPTOR 0x4a +#define EIT_SHORT_EVENT_DESCRIPTOR 0x4d +#define EIT_EXTENDED_EVENT_DESCRIPTOR 0x4e +#define EIT_TIME_SHIFTED_EVENT_DESCRIPTOR 0x4f +#define EIT_COMPONENT_DESCRIPTOR 0x50 +#define EIT_CA_IDENTIFIER_DESCRIPTOR 0x53 +#define EIT_CONTENT_DESCRIPTOR 0x54 +#define EIT_PARENTAL_RATING_DESCRIPTOR 0x55 +#define EIT_TELEPHONE_DESCRIPTOR 0x57 +#define EIT_MULTILINGUAL_COMPONENT_DESCRIPTOR 0x5e +#define EIT_PRIVATE_DATE_SPECIFIER_DESCRIPTOR 0x5f +#define EIT_SHORT_SMOOTHING_BUFFER_DESCRIPTOR 0x61 +#define EIT_DATA_BROADCAST_DESCRIPTOR 0x64 +#define EIT_PDC_DESCRIPTOR 0x69 typedef struct eit_struct { - u_char table_id : 8; + 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; + 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; + u_char section_length_hi : 4; + u_char : 3; + u_char section_syntax_indicator : 1; #endif - u_char section_length_lo : 8; + u_char section_length_lo : 8; - u_char service_id_hi : 8; - u_char service_id_lo : 8; + u_char service_id_hi : 8; + u_char service_id_lo : 8; #if BYTE_ORDER == BIG_ENDIAN - u_char : 2; - u_char version_number : 5; - u_char current_next_indicator : 1; + 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; + 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; - u_char transport_stream_id_hi : 8; - u_char transport_stream_id_lo : 8; - u_char original_network_id_hi : 8; - u_char original_network_id_lo : 8; - u_char segment_last_section_number : 8; - u_char segment_last_table_id : 8; + u_char section_number : 8; + u_char last_section_number : 8; + u_char transport_stream_id_hi : 8; + u_char transport_stream_id_lo : 8; + u_char original_network_id_hi : 8; + u_char original_network_id_lo : 8; + u_char segment_last_section_number : 8; + u_char segment_last_table_id : 8; } eit_t; typedef struct eit_loop_struct { - u_char event_id_hi : 8; - u_char event_id_lo : 8; - - u_char date_hi : 8; - u_char date_lo : 8; - u_char time_hour : 4; - u_char time_hour_ten : 4; - u_char time_minute : 4; - u_char time_minute_ten : 4; - u_char time_second : 4; - u_char time_second_ten : 4; - - u_char dur_hour : 4; - u_char dur_hour_ten : 4; - u_char dur_minute : 4; - u_char dur_minute_ten : 4; - u_char dur_second : 4; - u_char dur_second_ten : 4; + u_char event_id_hi : 8; + u_char event_id_lo : 8; + + u_char date_hi : 8; + u_char date_lo : 8; + u_char time_hour : 4; + u_char time_hour_ten : 4; + u_char time_minute : 4; + u_char time_minute_ten : 4; + u_char time_second : 4; + u_char time_second_ten : 4; + + u_char dur_hour : 4; + u_char dur_hour_ten : 4; + u_char dur_minute : 4; + u_char dur_minute_ten : 4; + u_char dur_second : 4; + u_char dur_second_ten : 4; #if BYTE_ORDER == BIG_ENDIAN - u_char running_status : 3; - u_char free_ca_mode : 1; - u_char descriptors_loop_length_hi : 4; + u_char running_status : 3; + u_char free_ca_mode : 1; + u_char descriptors_loop_length_hi : 4; #else - u_char descriptors_loop_length_hi : 4; - u_char free_ca_mode : 1; - u_char running_status : 3; + u_char descriptors_loop_length_hi : 4; + u_char free_ca_mode : 1; + u_char running_status : 3; #endif - u_char descriptors_loop_length_lo : 8; + u_char descriptors_loop_length_lo : 8; } eit_loop_t; typedef struct eit_short_event_struct { - u_char descriptor_tag : 8; - u_char descriptor_length : 8; + u_char descriptor_tag : 8; + u_char descriptor_length : 8; - u_char language_code_1 : 8; - u_char language_code_2 : 8; - u_char language_code_3 : 8; + u_char language_code_1 : 8; + u_char language_code_2 : 8; + u_char language_code_3 : 8; - u_char event_name_length : 8; + u_char event_name_length : 8; } eit_short_event_t; typedef struct eit_extended_event_struct { - u_char descriptor_tag : 8; - u_char descriptor_length : 8; + u_char descriptor_tag : 8; + u_char descriptor_length : 8; - u_char last_descriptor_number : 4; - u_char descriptor_number : 4; + u_char last_descriptor_number : 4; + u_char descriptor_number : 4; - u_char language_code_1 : 8; - u_char language_code_2 : 8; - u_char language_code_3 : 8; + u_char language_code_1 : 8; + u_char language_code_2 : 8; + u_char language_code_3 : 8; - u_char length_of_items : 8; + u_char length_of_items : 8; } eit_extended_event_t; typedef struct eit_content_descriptor { - u_char descriptor_tag : 8; - u_char descriptor_length : 8; + u_char descriptor_tag : 8; + u_char descriptor_length : 8; } eit_content_descriptor_t; typedef struct eit_content_loop { - u_char content_nibble_level_2 : 4; - u_char content_nibble_level_1 : 4; - u_char user_nibble_2 : 4; - u_char user_nibble_1 : 4; + u_char content_nibble_level_2 : 4; + u_char content_nibble_level_1 : 4; + u_char user_nibble_2 : 4; + u_char user_nibble_1 : 4; } eit_content_loop_t; class cEIT { private: cSchedules *schedules; -public: - cEIT(void *buf, int length, cSchedules *Schedules); - ~cEIT(); +public: + cEIT(void *buf, int length, cSchedules *Schedules); + ~cEIT(); /** */ int ProcessEIT(); @@ -789,10 +788,10 @@ protected: // Protected attributes cEIT::cEIT(void * buf, int length, cSchedules *Schedules) { - buflen = length < int(sizeof(buffer)) ? length : sizeof(buffer); - memset(buffer, 0, sizeof(buffer)); - memcpy(buffer, buf, buflen); - tid = buffer[0]; + buflen = length < int(sizeof(buffer)) ? length : sizeof(buffer); + memset(buffer, 0, sizeof(buffer)); + memcpy(buffer, buf, buflen); + tid = buffer[0]; schedules = Schedules; } @@ -803,114 +802,114 @@ cEIT::~cEIT() /** */ int cEIT::ProcessEIT() { - int bufact = 0; - eit_t *eit; - eit_loop_t *eitloop; - u_char tmp[256]; - - if (bufact + (int)sizeof(eit_t) > buflen) - return 0; - eit = (eit_t *)buffer; - bufact += sizeof(eit_t); - - unsigned int service = (eit->service_id_hi << 8) | eit->service_id_lo; - - while(bufact + (int)sizeof(eit_loop_t) <= buflen) - { - eitloop = (eit_loop_t *)&buffer[bufact]; - bufact += sizeof(eit_loop_t); - - int descdatalen = (eitloop->descriptors_loop_length_hi << 8) + eitloop->descriptors_loop_length_lo; - int descdataact = 0; - - while (descdataact < descdatalen && bufact < buflen) - { - switch (buffer[bufact]) - { - eit_content_descriptor_t *cont; - eit_content_loop_t *contloop; - - case EIT_STUFFING_DESCRIPTOR : - //dsyslog(LOG_INFO, "Found EIT_STUFFING_DESCRIPTOR"); - break; - - case EIT_LINKAGE_DESCRIPTOR : - //dsyslog(LOG_INFO, "Found EIT_LINKAGE_DESCRIPTOR"); - break; - - case EIT_SHORT_EVENT_DESCRIPTOR: - WriteShortEventDescriptor(service, eitloop, &buffer[bufact]); - break; - - case EIT_EXTENDED_EVENT_DESCRIPTOR: - WriteExtEventDescriptor(service, eitloop, &buffer[bufact]); - break; - - case EIT_TIME_SHIFTED_EVENT_DESCRIPTOR : - //dsyslog(LOG_INFO, "Found EIT_TIME_SHIFTED_EVENT_DESCRIPTOR"); - break; - - case EIT_COMPONENT_DESCRIPTOR : + int bufact = 0; + eit_t *eit; + eit_loop_t *eitloop; + u_char tmp[256]; + + if (bufact + (int)sizeof(eit_t) > buflen) + return 0; + eit = (eit_t *)buffer; + bufact += sizeof(eit_t); + + unsigned int service = (eit->service_id_hi << 8) | eit->service_id_lo; + + while(bufact + (int)sizeof(eit_loop_t) <= buflen) + { + eitloop = (eit_loop_t *)&buffer[bufact]; + bufact += sizeof(eit_loop_t); + + int descdatalen = (eitloop->descriptors_loop_length_hi << 8) + eitloop->descriptors_loop_length_lo; + int descdataact = 0; + + while (descdataact < descdatalen && bufact < buflen) + { + switch (buffer[bufact]) + { + eit_content_descriptor_t *cont; + eit_content_loop_t *contloop; + + case EIT_STUFFING_DESCRIPTOR : + //dsyslog(LOG_INFO, "Found EIT_STUFFING_DESCRIPTOR"); + break; + + case EIT_LINKAGE_DESCRIPTOR : + //dsyslog(LOG_INFO, "Found EIT_LINKAGE_DESCRIPTOR"); + break; + + case EIT_SHORT_EVENT_DESCRIPTOR: + WriteShortEventDescriptor(service, eitloop, &buffer[bufact]); + break; + + case EIT_EXTENDED_EVENT_DESCRIPTOR: + WriteExtEventDescriptor(service, eitloop, &buffer[bufact]); + break; + + case EIT_TIME_SHIFTED_EVENT_DESCRIPTOR : + //dsyslog(LOG_INFO, "Found EIT_TIME_SHIFTED_EVENT_DESCRIPTOR"); + break; + + case EIT_COMPONENT_DESCRIPTOR : if (buffer[bufact + 1] > 6) // kls 2001-02-24: otherwise strncpy() causes a segfault in strdvbcpy() - strdvbcpy(tmp, &buffer[bufact + 8], buffer[bufact + 1] - 6); - //dsyslog(LOG_INFO, "Found EIT_COMPONENT_DESCRIPTOR %c%c%c 0x%02x/0x%02x/0x%02x '%s'\n", buffer[bufact + 5], buffer[bufact + 6], buffer[bufact + 7], buffer[2], buffer[3], buffer[4], tmp); - break; - - case EIT_CA_IDENTIFIER_DESCRIPTOR : - //dsyslog(LOG_INFO, "Found EIT_CA_IDENTIFIER_DESCRIPTOR"); - break; - - case EIT_CONTENT_DESCRIPTOR : - cont = (eit_content_descriptor_t *)buffer; - contloop = (eit_content_loop_t *)&buffer[sizeof(eit_content_descriptor_t)]; - //dsyslog(LOG_INFO, "Found EIT_CONTENT_DESCRIPTOR 0x%02x/0x%02x\n", contloop->content_nibble_level_1, contloop->content_nibble_level_2); - break; - - case EIT_PARENTAL_RATING_DESCRIPTOR : - //dsyslog(LOG_INFO, "Found EIT_PARENTAL_RATING_DESCRIPTOR"); - break; - - case EIT_TELEPHONE_DESCRIPTOR : - //dsyslog(LOG_INFO, "Found EIT_TELEPHONE_DESCRIPTOR"); - break; - - case EIT_MULTILINGUAL_COMPONENT_DESCRIPTOR : - //dsyslog(LOG_INFO, "Found EIT_MULTILINGUAL_COMPONENT_DESCRIPTOR"); - break; - - case EIT_PRIVATE_DATE_SPECIFIER_DESCRIPTOR : - //dsyslog(LOG_INFO, "Found EIT_PRIVATE_DATE_SPECIFIER_DESCRIPTOR"); - break; - - case EIT_SHORT_SMOOTHING_BUFFER_DESCRIPTOR : - //dsyslog(LOG_INFO, "Found EIT_SHORT_SMOOTHING_BUFFER_DESCRIPTOR"); - break; - - case EIT_DATA_BROADCAST_DESCRIPTOR : - //dsyslog(LOG_INFO, "Found EIT_DATA_BROADCAST_DESCRIPTOR"); - break; - - case EIT_PDC_DESCRIPTOR : - //dsyslog(LOG_INFO, "Found EIT_PDC_DESCRIPTOR"); - break; - - default: - //dsyslog(LOG_INFO, "Found unhandled descriptor 0x%02x with length of %04d\n", (int)buffer[bufact], (int)buffer[bufact + 1]); - break; - } - descdataact += (buffer[bufact + 1] + 2); - bufact += (buffer[bufact + 1] + 2); - } - } - - return 0; + strdvbcpy(tmp, &buffer[bufact + 8], buffer[bufact + 1] - 6); + //dsyslog(LOG_INFO, "Found EIT_COMPONENT_DESCRIPTOR %c%c%c 0x%02x/0x%02x/0x%02x '%s'\n", buffer[bufact + 5], buffer[bufact + 6], buffer[bufact + 7], buffer[2], buffer[3], buffer[4], tmp); + break; + + case EIT_CA_IDENTIFIER_DESCRIPTOR : + //dsyslog(LOG_INFO, "Found EIT_CA_IDENTIFIER_DESCRIPTOR"); + break; + + case EIT_CONTENT_DESCRIPTOR : + cont = (eit_content_descriptor_t *)buffer; + contloop = (eit_content_loop_t *)&buffer[sizeof(eit_content_descriptor_t)]; + //dsyslog(LOG_INFO, "Found EIT_CONTENT_DESCRIPTOR 0x%02x/0x%02x\n", contloop->content_nibble_level_1, contloop->content_nibble_level_2); + break; + + case EIT_PARENTAL_RATING_DESCRIPTOR : + //dsyslog(LOG_INFO, "Found EIT_PARENTAL_RATING_DESCRIPTOR"); + break; + + case EIT_TELEPHONE_DESCRIPTOR : + //dsyslog(LOG_INFO, "Found EIT_TELEPHONE_DESCRIPTOR"); + break; + + case EIT_MULTILINGUAL_COMPONENT_DESCRIPTOR : + //dsyslog(LOG_INFO, "Found EIT_MULTILINGUAL_COMPONENT_DESCRIPTOR"); + break; + + case EIT_PRIVATE_DATE_SPECIFIER_DESCRIPTOR : + //dsyslog(LOG_INFO, "Found EIT_PRIVATE_DATE_SPECIFIER_DESCRIPTOR"); + break; + + case EIT_SHORT_SMOOTHING_BUFFER_DESCRIPTOR : + //dsyslog(LOG_INFO, "Found EIT_SHORT_SMOOTHING_BUFFER_DESCRIPTOR"); + break; + + case EIT_DATA_BROADCAST_DESCRIPTOR : + //dsyslog(LOG_INFO, "Found EIT_DATA_BROADCAST_DESCRIPTOR"); + break; + + case EIT_PDC_DESCRIPTOR : + //dsyslog(LOG_INFO, "Found EIT_PDC_DESCRIPTOR"); + break; + + default: + //dsyslog(LOG_INFO, "Found unhandled descriptor 0x%02x with length of %04d\n", (int)buffer[bufact], (int)buffer[bufact + 1]); + break; + } + descdataact += (buffer[bufact + 1] + 2); + bufact += (buffer[bufact + 1] + 2); + } + } + + return 0; } /** */ int cEIT::strdvbcpy(unsigned char *dst, unsigned char *src, int max) { - int a = 0; - + int a = 0; + // kls 2001-02-24: if we come in with negative values, the caller must // have done something wrong and the strncpy() below will cause a segfault if (max <= 0) @@ -919,42 +918,42 @@ int cEIT::strdvbcpy(unsigned char *dst, unsigned char *src, int max) return 0; } - if (*src == 0x05 || (*src >= 0x20 && *src <= 0xff)) - { - for (a = 0; a < max; a++) - { - if (*src == 0) - break; - - if ((*src >= ' ' && *src <= '~') || (*src >= 0xa0 && *src <= 0xff)) - *dst++ = *src++; - else - { - // if ((*src > '~' && *src < 0xa0) || *src == 0xff) - // cerr << "found special character 0x" << HEX(2) << (int)*src << endl; - src++; - } - } - *dst = 0; - } - else - { - const char *ret; - - switch (*src) - { - case 0x01: ret = "Coding according to character table 1"; break; - case 0x02: ret = "Coding according to character table 2"; break; - case 0x03: ret = "Coding according to character table 3"; break; - case 0x04: ret = "Coding according to character table 4"; break; - case 0x10: ret = "Coding according to ISO/IEC 8859"; break; - case 0x11: ret = "Coding according to ISO/IEC 10646"; break; - case 0x12: ret = "Coding according to KSC 5601"; break; - default: ret = "Unknown coding"; break; - } - strncpy((char *)dst, ret, max); - } - return a; + if (*src == 0x05 || (*src >= 0x20 && *src <= 0xff)) + { + for (a = 0; a < max; a++) + { + if (*src == 0) + break; + + if ((*src >= ' ' && *src <= '~') || (*src >= 0xa0 && *src <= 0xff)) + *dst++ = *src++; + else + { + // if ((*src > '~' && *src < 0xa0) || *src == 0xff) + // cerr << "found special character 0x" << HEX(2) << (int)*src << endl; + src++; + } + } + *dst = 0; + } + else + { + const char *ret; + + switch (*src) + { + case 0x01: ret = "Coding according to character table 1"; break; + case 0x02: ret = "Coding according to character table 2"; break; + case 0x03: ret = "Coding according to character table 3"; break; + case 0x04: ret = "Coding according to character table 4"; break; + case 0x10: ret = "Coding according to ISO/IEC 8859"; break; + case 0x11: ret = "Coding according to ISO/IEC 10646"; break; + case 0x12: ret = "Coding according to KSC 5601"; break; + default: ret = "Unknown coding"; break; + } + strncpy((char *)dst, ret, max); + } + return a; } /** returns true if this EIT covers a @@ -962,140 +961,140 @@ present/following information, false if it's schedule information */ bool cEIT::IsPresentFollowing() { - if (tid == 0x4e || tid == 0x4f) - return true; + if (tid == 0x4e || tid == 0x4f) + return true; - return false; + return false; } /** */ bool cEIT::WriteShortEventDescriptor(unsigned short service, eit_loop_t *eitloop, u_char *buf) { - u_char tmp[256]; - eit_short_event_t *evt = (eit_short_event_t *)buf; - unsigned short eventid = (unsigned short)((eitloop->event_id_hi << 8) | eitloop->event_id_lo); - cEventInfo *pEvent; - - //isyslog(LOG_INFO, "Found Short Event Descriptor"); - - cSchedule *pSchedule = (cSchedule *)schedules->GetSchedule(service); - if (pSchedule == NULL) - { - schedules->Add(new cSchedule(service)); - pSchedule = (cSchedule *)schedules->GetSchedule(service); - if (pSchedule == NULL) - return false; - } + u_char tmp[256]; + eit_short_event_t *evt = (eit_short_event_t *)buf; + unsigned short eventid = (unsigned short)((eitloop->event_id_hi << 8) | eitloop->event_id_lo); + cEventInfo *pEvent; + + //isyslog(LOG_INFO, "Found Short Event Descriptor"); + + cSchedule *pSchedule = (cSchedule *)schedules->GetSchedule(service); + if (pSchedule == NULL) + { + schedules->Add(new cSchedule(service)); + pSchedule = (cSchedule *)schedules->GetSchedule(service); + if (pSchedule == NULL) + return false; + } /* cSchedule::GetPresentEvent() and cSchedule::GetFollowingEvent() verify the temporal sanity of these events, so calling them here appears to be a bad idea... (kls 2000-11-01) - // - // if we are working on a present/following info, let's see whether - // we already have present/following info for this service and if yes - // check whether it's the same eventid, if yes, just return, nothing - // left to do. - // - if (IsPresentFollowing()) - { - if (eitloop->running_status == 4 || eitloop->running_status == 3) - pEvent = (cEventInfo *)pSchedule->GetPresentEvent(); - else - pEvent = (cEventInfo *)pSchedule->GetFollowingEvent(); - - if (pEvent != NULL) - if (pEvent->GetEventID() == eventid) - return true; - } + // + // if we are working on a present/following info, let's see whether + // we already have present/following info for this service and if yes + // check whether it's the same eventid, if yes, just return, nothing + // left to do. + // + if (IsPresentFollowing()) + { + if (eitloop->running_status == 4 || eitloop->running_status == 3) + pEvent = (cEventInfo *)pSchedule->GetPresentEvent(); + else + pEvent = (cEventInfo *)pSchedule->GetFollowingEvent(); + + if (pEvent != NULL) + if (pEvent->GetEventID() == eventid) + return true; + } */ - // - // let's see whether we have that eventid already - // in case not, we have to create a new cEventInfo for it - // - pEvent = (cEventInfo *)pSchedule->GetEvent(eventid); - if (pEvent == NULL) - { - pSchedule->Events.Add(new cEventInfo(service, eventid)); - pEvent = (cEventInfo *)pSchedule->GetEvent(eventid); - if (pEvent == NULL) - return false; - - strdvbcpy(tmp, &buf[sizeof(eit_short_event_t)], evt->event_name_length); - pEvent->SetTitle((char *)tmp); - strdvbcpy(tmp, &buf[sizeof(eit_short_event_t) + evt->event_name_length + 1], - (int)buf[sizeof(eit_short_event_t) + evt->event_name_length]); - pEvent->SetSubtitle((char *)tmp); - cMJD mjd(eitloop->date_hi, eitloop->date_lo, - eitloop->time_hour_ten * 10 + eitloop->time_hour, - eitloop->time_minute_ten * 10 + eitloop->time_minute, - eitloop->time_second_ten * 10 + eitloop->time_second); - pEvent->SetTime(mjd.GetTime_t()); - pEvent->SetDuration((long)((long)((eitloop->dur_hour_ten * 10 + eitloop->dur_hour) * 60l * 60l) + - (long)((eitloop->dur_minute_ten * 10 + eitloop->dur_minute) * 60l) + - (long)(eitloop->dur_second_ten * 10 + eitloop->dur_second))); - } - - if (IsPresentFollowing()) - { - if (eitloop->running_status == 4 || eitloop->running_status == 3) - pSchedule->SetPresentEvent(pEvent); - else if (eitloop->running_status == 1 || eitloop->running_status == 2 || eitloop->running_status == 0) - pSchedule->SetFollowingEvent(pEvent); - } - - return true; + // + // let's see whether we have that eventid already + // in case not, we have to create a new cEventInfo for it + // + pEvent = (cEventInfo *)pSchedule->GetEvent(eventid); + if (pEvent == NULL) + { + pSchedule->Events.Add(new cEventInfo(service, eventid)); + pEvent = (cEventInfo *)pSchedule->GetEvent(eventid); + if (pEvent == NULL) + return false; + + strdvbcpy(tmp, &buf[sizeof(eit_short_event_t)], evt->event_name_length); + pEvent->SetTitle((char *)tmp); + strdvbcpy(tmp, &buf[sizeof(eit_short_event_t) + evt->event_name_length + 1], + (int)buf[sizeof(eit_short_event_t) + evt->event_name_length]); + pEvent->SetSubtitle((char *)tmp); + cMJD mjd(eitloop->date_hi, eitloop->date_lo, + eitloop->time_hour_ten * 10 + eitloop->time_hour, + eitloop->time_minute_ten * 10 + eitloop->time_minute, + eitloop->time_second_ten * 10 + eitloop->time_second); + pEvent->SetTime(mjd.GetTime_t()); + pEvent->SetDuration((long)((long)((eitloop->dur_hour_ten * 10 + eitloop->dur_hour) * 60l * 60l) + + (long)((eitloop->dur_minute_ten * 10 + eitloop->dur_minute) * 60l) + + (long)(eitloop->dur_second_ten * 10 + eitloop->dur_second))); + } + + if (IsPresentFollowing()) + { + if (eitloop->running_status == 4 || eitloop->running_status == 3) + pSchedule->SetPresentEvent(pEvent); + else if (eitloop->running_status == 1 || eitloop->running_status == 2 || eitloop->running_status == 0) + pSchedule->SetFollowingEvent(pEvent); + } + + return true; } /** */ bool cEIT::WriteExtEventDescriptor(unsigned short service, eit_loop_t *eitloop, u_char *buf) { - u_char tmp[256]; - eit_extended_event_t *evt = (eit_extended_event_t *)buf; - int bufact, buflen; - unsigned short eventid = (unsigned short)((eitloop->event_id_hi << 8) | eitloop->event_id_lo); - cEventInfo *pEvent; - - //isyslog(LOG_INFO, "Found Extended Event Descriptor"); - - cSchedule *pSchedule = (cSchedule *)schedules->GetSchedule(service); - if (pSchedule == NULL) - { - schedules->Add(new cSchedule(service)); - pSchedule = (cSchedule *)schedules->GetSchedule(service); - if (pSchedule == NULL) - return false; - } - - pEvent = (cEventInfo *)pSchedule->GetEvent(eventid); - if (pEvent == NULL) - return false; - - if (evt->descriptor_number != pEvent->GetExtendedDescriptorNumber()) - return false; - - bufact = sizeof(eit_extended_event_t); - buflen = buf[1] + 2; - - if (evt->length_of_items > 0) - { - while (bufact - sizeof(eit_extended_event_t) < evt->length_of_items) - { - strdvbcpy(tmp, &buf[bufact + 1], (int)buf[bufact]); - // could use value in tmp now to do something, - // haven't seen any items as of yet transmitted from satellite - bufact += (buf[bufact] + 1); - } - } - - strdvbcpy(tmp, &buf[bufact + 1], (int)buf[bufact]); - if (pEvent->AddExtendedDescription((char *)tmp)) - { - pEvent->IncreaseExtendedDescriptorNumber(); - return true; - } - - return false; + u_char tmp[256]; + eit_extended_event_t *evt = (eit_extended_event_t *)buf; + int bufact, buflen; + unsigned short eventid = (unsigned short)((eitloop->event_id_hi << 8) | eitloop->event_id_lo); + cEventInfo *pEvent; + + //isyslog(LOG_INFO, "Found Extended Event Descriptor"); + + cSchedule *pSchedule = (cSchedule *)schedules->GetSchedule(service); + if (pSchedule == NULL) + { + schedules->Add(new cSchedule(service)); + pSchedule = (cSchedule *)schedules->GetSchedule(service); + if (pSchedule == NULL) + return false; + } + + pEvent = (cEventInfo *)pSchedule->GetEvent(eventid); + if (pEvent == NULL) + return false; + + if (evt->descriptor_number != pEvent->GetExtendedDescriptorNumber()) + return false; + + bufact = sizeof(eit_extended_event_t); + buflen = buf[1] + 2; + + if (evt->length_of_items > 0) + { + while (bufact - sizeof(eit_extended_event_t) < evt->length_of_items) + { + strdvbcpy(tmp, &buf[bufact + 1], (int)buf[bufact]); + // could use value in tmp now to do something, + // haven't seen any items as of yet transmitted from satellite + bufact += (buf[bufact] + 1); + } + } + + strdvbcpy(tmp, &buf[bufact + 1], (int)buf[bufact]); + if (pEvent->AddExtendedDescription((char *)tmp)) + { + pEvent->IncreaseExtendedDescriptorNumber(); + return true; + } + + return false; } // --- cSIProcessor ---------------------------------------------------------- @@ -1110,13 +1109,13 @@ cMutex cSIProcessor::schedulesMutex; cSIProcessor::cSIProcessor(const char *FileName) { masterSIProcessor = numSIProcessors == 0; // the first one becomes the 'master' - useTStime = false; + useTStime = false; filters = NULL; if ((fsvbi = open(FileName, O_RDONLY)) >= 0) { if (!numSIProcessors++) // the first one creates it schedules = new cSchedules; - filters = (SIP_FILTER *)calloc(MAX_FILTERS, sizeof(SIP_FILTER)); + filters = (SIP_FILTER *)calloc(MAX_FILTERS, sizeof(SIP_FILTER)); } else LOG_ERROR_STR(FileName); @@ -1126,8 +1125,9 @@ cSIProcessor::~cSIProcessor() { if (fsvbi >= 0) { - Cancel(); - ShutDownFilters(); + active = false; + Cancel(3); + ShutDownFilters(); delete filters; if (!--numSIProcessors) // the last one deletes it delete schedules; @@ -1146,16 +1146,18 @@ void cSIProcessor::Action() } dsyslog(LOG_INFO, "EIT processing thread started (pid=%d)%s", getpid(), masterSIProcessor ? " - master" : ""); - + unsigned char buf[4096+1]; // max. allowed size for any EIT section (+1 for safety ;-) - unsigned int seclen; - unsigned int pid; + unsigned int seclen; + unsigned int pid; time_t lastCleanup = time(NULL); time_t lastDump = time(NULL); - struct pollfd pfd; - - while(true) - { + struct pollfd pfd; + + active = true; + + while(active) + { if (masterSIProcessor) { time_t now = time(NULL); @@ -1185,65 +1187,65 @@ void cSIProcessor::Action() } } - /* wait data become ready from the bitfilter */ - pfd.fd = fsvbi; - pfd.events = POLLIN; - if(poll(&pfd, 1, 1000) != 0) /* timeout is 5 secs */ - { - // fprintf(stderr, "<data>\n"); - /* read section */ - read(fsvbi, buf, 8); - seclen = (buf[6] << 8) | buf[7]; - pid = (buf[4] << 8) | buf[5]; - read(fsvbi, buf, seclen); - - //dsyslog(LOG_INFO, "Received pid 0x%02x with table ID 0x%02x and length of %04d\n", pid, buf[0], seclen); - - switch (pid) - { - case 0x14: - if (buf[0] == 0x70) - { - if (useTStime) + /* wait data become ready from the bitfilter */ + pfd.fd = fsvbi; + pfd.events = POLLIN; + if(poll(&pfd, 1, 1000) != 0) /* timeout is 5 secs */ + { + // fprintf(stderr, "<data>\n"); + /* read section */ + read(fsvbi, buf, 8); + seclen = (buf[6] << 8) | buf[7]; + pid = (buf[4] << 8) | buf[5]; + read(fsvbi, buf, seclen); + + //dsyslog(LOG_INFO, "Received pid 0x%02x with table ID 0x%02x and length of %04d\n", pid, buf[0], seclen); + + switch (pid) + { + case 0x14: + if (buf[0] == 0x70) + { + if (useTStime) { cTDT ctdt((tdt_t *)buf); - ctdt.SetSystemTime(); + ctdt.SetSystemTime(); } - } + } /*XXX this comes pretty often: - else - dsyslog(LOG_INFO, "Time packet was not 0x70 but 0x%02x\n", (int)buf[0]); + else + dsyslog(LOG_INFO, "Time packet was not 0x70 but 0x%02x\n", (int)buf[0]); XXX*/ - break; - - case 0x12: - if (buf[0] != 0x72) - { + break; + + case 0x12: + if (buf[0] != 0x72) + { LOCK_THREAD; schedulesMutex.Lock(); - cEIT ceit(buf, seclen, schedules); - ceit.ProcessEIT(); + cEIT ceit(buf, seclen, schedules); + ceit.ProcessEIT(); schedulesMutex.Unlock(); - } - else - dsyslog(LOG_INFO, "Received stuffing section in EIT\n"); - break; - - default: - break; - } - } - else - { + } + else + dsyslog(LOG_INFO, "Received stuffing section in EIT\n"); + break; + + default: + break; + } + } + else + { LOCK_THREAD; //XXX this comes pretty often - //isyslog(LOG_INFO, "Received timeout from poll, refreshing filters\n"); - RefreshFilters(); - } -// WakeUp(); - } + //isyslog(LOG_INFO, "Received timeout from poll, refreshing filters\n"); + RefreshFilters(); + } +// WakeUp(); + } } /** Add a filter with packet identifier pid and @@ -1253,42 +1255,42 @@ bool cSIProcessor::AddFilter(u_char pid, u_char tid) if (fsvbi < 0) return false; - int section = ((int)tid << 8) | 0x00ff; - - struct bitfilter filt = { - pid, - { section, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, - SECTION_CONTINUOS, 0, - FILTER_MEM, - {}, - }; - - if (ioctl(fsvbi, VIDIOCSBITFILTER, &filt) < 0) - return false; - - for (int a = 0; a < MAX_FILTERS; a++) - { - if (filters[a].inuse == false) - { - filters[a].pid = pid; - filters[a].tid = tid; - filters[a].handle = filt.handle; - filters[a].inuse = true; - // dsyslog(LOG_INFO, " Registered filter handle %04x, pid = %02d, tid = %02d", filters[a].handle, filters[a].pid, filters[a].tid); - return true; - } - } - - return false; + int section = ((int)tid << 8) | 0x00ff; + + struct bitfilter filt = { + pid, + { section, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + SECTION_CONTINUOS, 0, + FILTER_MEM, + {}, + }; + + if (ioctl(fsvbi, VIDIOCSBITFILTER, &filt) < 0) + return false; + + for (int a = 0; a < MAX_FILTERS; a++) + { + if (filters[a].inuse == false) + { + filters[a].pid = pid; + filters[a].tid = tid; + filters[a].handle = filt.handle; + filters[a].inuse = true; + // dsyslog(LOG_INFO, " Registered filter handle %04x, pid = %02d, tid = %02d", filters[a].handle, filters[a].pid, filters[a].tid); + return true; + } + } + + return false; } /** set whether local systems time should be set by the received TDT or TOT packets */ bool cSIProcessor::SetUseTSTime(bool use) { - useTStime = use; - return useTStime; + useTStime = use; + return useTStime; } /** */ @@ -1297,22 +1299,22 @@ bool cSIProcessor::ShutDownFilters() if (fsvbi < 0) return false; - bool ret = true; - - for (int a = 0; a < MAX_FILTERS; a++) - { - if (filters[a].inuse == true) - { - if (ioctl(fsvbi, VIDIOCSSHUTDOWNFILTER, &filters[a].handle) < 0) - ret = false; + bool ret = true; + + for (int a = 0; a < MAX_FILTERS; a++) + { + if (filters[a].inuse == true) + { + if (ioctl(fsvbi, VIDIOCSSHUTDOWNFILTER, &filters[a].handle) < 0) + ret = false; + + // dsyslog(LOG_INFO, "Deregistered filter handle %04x, pid = %02d, tid = %02d", filters[a].handle, filters[a].pid, filters[a].tid); - // dsyslog(LOG_INFO, "Deregistered filter handle %04x, pid = %02d, tid = %02d", filters[a].handle, filters[a].pid, filters[a].tid); - - filters[a].inuse = false; - } - } + filters[a].inuse = false; + } + } - return ret; + return ret; } /** */ @@ -1328,18 +1330,18 @@ bool cSIProcessor::RefreshFilters() if (fsvbi < 0) return false; - bool ret = true; - - ret = ShutDownFilters(); - - for (int a = 0; a < MAX_FILTERS; a++) - { - if (filters[a].inuse == false && filters[a].pid != 0 && filters[a].tid != 0) - { - if (!AddFilter(filters[a].pid, filters[a].tid)) - ret = false; - } - } - - return ret; + bool ret = true; + + ret = ShutDownFilters(); + + for (int a = 0; a < MAX_FILTERS; a++) + { + if (filters[a].inuse == false && filters[a].pid != 0 && filters[a].tid != 0) + { + if (!AddFilter(filters[a].pid, filters[a].tid)) + ret = false; + } + } + + return ret; } |