diff --git a/src/eitd/SIsections.cpp b/src/eitd/SIsections.cpp index 736c2c8c6..e6c7cddec 100644 --- a/src/eitd/SIsections.cpp +++ b/src/eitd/SIsections.cpp @@ -44,6 +44,8 @@ #endif #include +#include +#include struct descr_generic_header { unsigned descriptor_tag : 8; @@ -61,12 +63,14 @@ struct descr_short_event_header { } __attribute__ ((packed)) ; #endif +#if 0 struct descr_service_header { unsigned descriptor_tag : 8; unsigned descriptor_length : 8; unsigned service_typ : 8; unsigned service_provider_name_length : 8; } __attribute__ ((packed)) ; +#endif #if 0 struct descr_extended_event_header { @@ -81,6 +85,7 @@ struct descr_extended_event_header { } __attribute__ ((packed)) ; #endif +#if 0 struct service_list_entry { unsigned service_id_hi : 8; unsigned service_id_lo : 8; @@ -98,6 +103,7 @@ inline unsigned min(unsigned a, unsigned b) { return b < a ? b : a; } +#endif void SIsectionEIT::parse(void) { @@ -367,6 +373,7 @@ void SIsectionEIT::parseDescriptors(const uint8_t *des, unsigned len, SIevent &e #endif /********************/ +#if 0 bool check_blacklisted(const t_original_network_id onid, const t_transport_stream_id tsid) { if ( (onid == 0x0001) && @@ -451,9 +458,11 @@ void SIsectionSDT::parseDescriptors(const uint8_t *des, unsigned len, SIservice } } +#endif // Die infos aus dem Puffer holen void SIsectionSDT::parse(void) { +#if 0 const uint8_t *actPos; const uint8_t *bufEnd; struct sdt_service *sv; @@ -481,114 +490,45 @@ void SIsectionSDT::parse(void) svs.insert(s); actPos += descriptors_loop_length; } - - parsed = 1; -} - -#if 0 //def ENABLE_FREESATEPG -std::string SIsectionEIT::freesatHuffmanDecode(std::string input) -{ - const char *src = input.c_str(); - uint size = input.length(); - - if (src[1] == 1 || src[1] == 2) - { - std::string uncompressed(size * 3, ' '); - uint p = 0; - struct hufftab *table; - unsigned table_length; - if (src[1] == 1) - { - table = fsat_huffman1; - table_length = sizeof(fsat_huffman1) / sizeof(fsat_huffman1[0]); - } - else - { - table = fsat_huffman2; - table_length = sizeof(fsat_huffman2) / sizeof(fsat_huffman2[0]); - } - unsigned value = 0, byte = 2, bit = 0; - while (byte < 6 && byte < size) - { - value |= src[byte] << ((5-byte) * 8); - byte++; - } - char lastch = START; - - do - { - bool found = false; - unsigned bitShift = 0; - if (lastch == ESCAPE) - { - found = true; - // Encoded in the next 8 bits. - // Terminated by the first ASCII character. - char nextCh = (value >> 24) & 0xff; - bitShift = 8; - if ((nextCh & 0x80) == 0) - lastch = nextCh; - if (p >= uncompressed.length()) - uncompressed.resize(p+10); - uncompressed[p++] = nextCh; - } - else - { - for (unsigned j = 0; j < table_length; j++) - { - if (table[j].last == lastch) - { - unsigned mask = 0, maskbit = 0x80000000; - for (short kk = 0; kk < table[j].bits; kk++) - { - mask |= maskbit; - maskbit >>= 1; - } - if ((value & mask) == table[j].value) - { - char nextCh = table[j].next; - bitShift = table[j].bits; - if (nextCh != STOP && nextCh != ESCAPE) - { - if (p >= uncompressed.length()) - uncompressed.resize(p+10); - uncompressed[p++] = nextCh; - } - found = true; - lastch = nextCh; - break; - } - } - } - } - if (found) - { - // Shift up by the number of bits. - for (unsigned b = 0; b < bitShift; b++) - { - value = (value << 1) & 0xfffffffe; - if (byte < size) - value |= (src[byte] >> (7-bit)) & 1; - if (bit == 7) - { - bit = 0; - byte++; - } - else bit++; - } - } - else - { - // Entry missing in table. - uncompressed.resize(p); - uncompressed.append("..."); - return uncompressed; - } - } while (lastch != STOP && value != 0); - - uncompressed.resize(p); - return uncompressed; - } - else return input; -} #endif + parsed = 1; + t_transport_stream_id transport_stream_id = getTransportStreamId(); + t_original_network_id original_network_id = getOriginalNetworkId(); + const ServiceDescriptionList &slist = *getDescriptions(); + for (ServiceDescriptionConstIterator sit = slist.begin(); sit != slist.end(); ++sit) { + ServiceDescription * service = *sit; + + SIservice s(service->getServiceId(), original_network_id, transport_stream_id); + + s.flags.EIT_schedule_flag = service->getEitScheduleFlag(); + s.flags.EIT_present_following_flag = service->getEitPresentFollowingFlag(); + s.flags.running_status = service->getRunningStatus(); + s.flags.free_CA_mode = service->getFreeCaMode(); + + DescriptorConstIterator dit; + for (dit = service->getDescriptors()->begin(); dit != service->getDescriptors()->end(); ++dit) { + switch ((*dit)->getTag()) { + case SERVICE_DESCRIPTOR: + { + ServiceDescriptor * d = (ServiceDescriptor *) *dit; + s.serviceTyp = d->getServiceType(); + } + break; + case NVOD_REFERENCE_DESCRIPTOR: + { + NvodReferenceDescriptor * d = (NvodReferenceDescriptor *) *dit; + NvodReferenceConstIterator it; + const NvodReferenceList* nlist = d->getNvodReferences(); + for (it = nlist->begin(); it != nlist->end(); ++it) { + SInvodReference nvod((*it)->getTransportStreamId(), (*it)->getOriginalNetworkId(), (*it)->getServiceId()); + s.nvods.insert(nvod); + } + } + break; + default: + break; + } + } + svs.insert(s); + } +} diff --git a/src/eitd/SIsections.hpp b/src/eitd/SIsections.hpp index ef7f67170..fe8fb1316 100644 --- a/src/eitd/SIsections.hpp +++ b/src/eitd/SIsections.hpp @@ -27,7 +27,9 @@ #include #include +#include +#if 0 struct SI_section_SDT_header { unsigned table_id : 8; #if __BYTE_ORDER == __BIG_ENDIAN @@ -59,6 +61,7 @@ struct SI_section_SDT_header { unsigned original_network_id_lo : 8; unsigned reserved_future_use2 : 8; } __attribute__ ((packed)) ; // 11 bytes +#endif #if 0 struct SI_section_EIT_header { @@ -212,14 +215,25 @@ public: }; -class SIsectionSDT : public SIsection +class SIsectionSDT : public ServiceDescriptionSection { +private: + SIservices svs; + int parsed; + void parse(void); +#if 0 + void parseDescriptors(const uint8_t *desc, unsigned len, SIservice &s); + void parseServiceDescriptor(const char *buf, SIservice &s); + void parsePrivateDataDescriptor(const char *buf, SIservice &s); + void parseNVODreferenceDescriptor(const char *buf, SIservice &s); +#endif public: +#if 0 SIsectionSDT(const SIsection &s) : SIsection(s) { parsed = 0; parse(); } - +#endif #if 0 // Std-Copy SIsectionSDT(const SIsectionSDT &s) : SIsection(s) { @@ -228,11 +242,12 @@ public: } #endif // Benutzt den uebergebenen Puffer (sollte mit new char[n] allokiert sein) - SIsectionSDT(uint8_t *buf) : SIsection(buf) { + SIsectionSDT(uint8_t *buf) : ServiceDescriptionSection(buf) { parsed = 0; parse(); } +#if 0 t_transport_stream_id transport_stream_id(void) const { return buffer ? ((((struct SI_section_SDT_header *)buffer)->transport_stream_id_hi << 8) | ((struct SI_section_SDT_header *)buffer)->transport_stream_id_lo) : 0; @@ -246,6 +261,7 @@ public: return buffer ? ((((struct SI_section_SDT_header *)buffer)->original_network_id_hi << 8) | ((struct SI_section_SDT_header *)buffer)->original_network_id_lo) : 0; } +#endif #if 0 static void dump(const struct SI_section_SDT_header *header) { if (!header) @@ -272,14 +288,6 @@ public: return svs; } -private: - SIservices svs; - int parsed; - void parse(void); - void parseDescriptors(const uint8_t *desc, unsigned len, SIservice &s); - void parseServiceDescriptor(const char *buf, SIservice &s); - void parsePrivateDataDescriptor(const char *buf, SIservice &s); - void parseNVODreferenceDescriptor(const char *buf, SIservice &s); }; #endif // SISECTIONS_HPP diff --git a/src/eitd/SIservices.hpp b/src/eitd/SIservices.hpp index 1baae63ab..509beab51 100644 --- a/src/eitd/SIservices.hpp +++ b/src/eitd/SIservices.hpp @@ -37,6 +37,7 @@ class SIservice; class SIevent; +#if 0 struct sdt_service { unsigned service_id_hi : 8; unsigned service_id_lo : 8; @@ -57,7 +58,7 @@ struct sdt_service { #endif unsigned descriptors_loop_length_lo : 8; } __attribute__ ((packed)) ; // 5 Bytes - +#endif class SInvodReference { @@ -72,13 +73,14 @@ public: original_network_id = new_original_network_id; transport_stream_id = new_transport_stream_id; } - +#if 0 SInvodReference(const SInvodReference &ref) { service_id = ref.service_id; original_network_id = ref.original_network_id; transport_stream_id = ref.transport_stream_id; } +#endif bool operator < (const SInvodReference& ref) const { @@ -117,8 +119,28 @@ struct printSInvodReference : public std::unary_function > SInvodReferences; -class SIservice { +class SIservice +{ +//protected: public: + struct { + unsigned char EIT_schedule_flag : 1; + unsigned char EIT_present_following_flag : 1; + unsigned char running_status : 3; + unsigned char free_CA_mode : 1; + } flags; + t_service_id service_id; + t_original_network_id original_network_id; // Ist innerhalb einer section unnoetig + t_transport_stream_id transport_stream_id; + unsigned char serviceTyp; + int is_actual; + SInvodReferences nvods; +#if 0 // unused + std::string serviceName; // Name aus dem Service-Descriptor + std::string providerName; // Name aus dem Service-Descriptor +#endif + +#if 0 SIservice(const struct sdt_service *s) { service_id = (s->service_id_hi << 8) | s->service_id_lo; original_network_id = 0; @@ -130,6 +152,7 @@ public: flags.free_CA_mode = s->free_CA_mode; is_actual = false; } +#endif // Um einen service zum Suchen zu erstellen SIservice(const t_service_id _service_id, const t_original_network_id _original_network_id, const t_transport_stream_id _transport_stream_id) { @@ -139,6 +162,8 @@ public: serviceTyp=0; memset(&flags, 0, sizeof(flags)); } + +#if 0 // Std-Copy SIservice(const SIservice &s) { service_id = s.service_id; @@ -151,18 +176,11 @@ public: nvods=s.nvods; is_actual=s.is_actual; } - t_service_id service_id; - t_original_network_id original_network_id; // Ist innerhalb einer section unnoetig - t_transport_stream_id transport_stream_id; - unsigned char serviceTyp; - int is_actual; - SInvodReferences nvods; - std::string serviceName; // Name aus dem Service-Descriptor - std::string providerName; // Name aus dem Service-Descriptor - int eitScheduleFlag(void) {return (int)flags.EIT_schedule_flag;} - int eitPresentFollowingFlag(void) {return (int)flags.EIT_present_following_flag;} - int runningStatus(void) {return (int)flags.running_status;} - int freeCAmode(void) {return (int)flags.free_CA_mode;} +#endif + int eitScheduleFlag(void) { return (int)flags.EIT_schedule_flag; } + int eitPresentFollowingFlag(void) { return (int)flags.EIT_present_following_flag; } + int runningStatus(void) { return (int)flags.running_status; } + int freeCAmode(void) { return (int)flags.free_CA_mode; } bool operator < (const SIservice& s) const { return uniqueKey() < s.uniqueKey(); @@ -178,20 +196,15 @@ public: printf("Original-Network-ID: %hu\n", original_network_id); printf("Service-ID: %hu\n", service_id); printf("Service-Typ: %hhu\n", serviceTyp); +#if 0 if(providerName.length()) printf("Provider-Name: %s\n", providerName.c_str()); if(serviceName.length()) printf("Service-Name: %s\n", serviceName.c_str()); +#endif for_each(nvods.begin(), nvods.end(), printSInvodReference()); printf("\n"); } -protected: - struct { - unsigned char EIT_schedule_flag : 1; - unsigned char EIT_present_following_flag : 1; - unsigned char running_status : 3; - unsigned char free_CA_mode : 1; - } flags; }; // Fuer for_each diff --git a/src/eitd/edvbstring.cpp b/src/eitd/edvbstring.cpp index f2f5b4958..bdf713626 100644 --- a/src/eitd/edvbstring.cpp +++ b/src/eitd/edvbstring.cpp @@ -53,7 +53,8 @@ int getCountryCodeDefaultMapping( const std::string &lang ) CountryCodeDefaultMapping.find(lang); if ( it != CountryCodeDefaultMapping.end() ) return it->second; - return 1; // ISO8859-1 / Latin1 + return 0; + //return 1; // ISO8859-1 / Latin1 } // 8859-x to ucs-16 coding tables. taken from www.unicode.org/Public/MAPPINGS/ISO8859/ diff --git a/src/eitd/sectionsd.cpp b/src/eitd/sectionsd.cpp index 7f8951bd3..2ae7a42d2 100644 --- a/src/eitd/sectionsd.cpp +++ b/src/eitd/sectionsd.cpp @@ -61,6 +61,8 @@ #include "eitd.h" #include "edvbstring.h" +#define ENABLE_SDT //FIXME + // 60 Minuten Zyklus... #define TIME_EIT_SCHEDULED_PAUSE 60 * 60 // -- 5 Minutes max. pause should improve behavior (rasc, 2005-05-02) @@ -68,10 +70,7 @@ // Zeit die fuer die gewartet wird, bevor der Filter weitergeschaltet wird, falls es automatisch nicht klappt #define TIME_EIT_SKIPPING 90 -#define ENABLE_FREESATEPG // FIXME #ifdef ENABLE_FREESATEPG -// a little more time for freesat epg -#define TIME_FSEIT_SKIPPING 240 #endif static bool sectionsd_ready = false; @@ -86,9 +85,6 @@ static unsigned int max_events; #define READ_TIMEOUT_IN_SECONDS 2 #define WRITE_TIMEOUT_IN_SECONDS 2 -// Gibt die Anzahl Timeouts an, nach der die Verbindung zum DMX neu gestartet wird (wegen evtl. buffer overflow) -// for NIT and SDT threads... -#define RESTART_DMX_AFTER_TIMEOUTS 5 // Timeout in ms for reading from dmx in EIT threads. Dont make this too long // since we are holding the start_stop lock during this read! @@ -154,10 +150,20 @@ static pthread_mutex_t timeThreadSleepMutex = PTHREAD_MUTEX_INITIALIZER; /* no matter how big the buffer, we will receive spurious POLLERR's in table 0x60, but those are not a big deal, so let's save some memory */ static DMX dmxEIT(0x12, 3000 /*320*/); +static DMX dmxCN(0x12, 512, false, 1); + #ifdef ENABLE_FREESATEPG +// a little more time for freesat epg +#define TIME_FSEIT_SKIPPING 240 static DMX dmxFSEIT(3842, 320); #endif -static DMX dmxCN(0x12, 512, false, 1); + +#ifdef ENABLE_SDT +#define TIME_SDT_NONEWDATA 5 +#define RESTART_DMX_AFTER_TIMEOUTS 5 +#define TIME_SDT_SCHEDULED_PAUSE 2* 60* 60 +static DMX dmxSDT(0x11, 512, true, 0); +#endif int sectionsd_stop = 0; static bool slow_addevent = true; @@ -1081,6 +1087,9 @@ static void commandPauseScanning(int connfd, char *data, const unsigned dataLeng dmxEIT.request_pause(); #ifdef ENABLE_FREESATEPG dmxFSEIT.request_pause(); +#endif +#ifdef ENABLE_SDT + dmxSDT.request_pause(); #endif scanning = 0; } @@ -1090,6 +1099,9 @@ static void commandPauseScanning(int connfd, char *data, const unsigned dataLeng dmxEIT.request_unpause(); #ifdef ENABLE_FREESATEPG dmxFSEIT.request_unpause(); +#endif +#ifdef ENABLE_SDT + dmxSDT.request_unpause(); #endif writeLockEvents(); if (myCurrentEvent) { @@ -1118,6 +1130,9 @@ static void commandPauseScanning(int connfd, char *data, const unsigned dataLeng dmxEIT.change(0); #ifdef ENABLE_FREESATEPG dmxFSEIT.change(0); +#endif +#ifdef ENABLE_SDT + dmxSDT.change(0); #endif } @@ -1595,6 +1610,9 @@ static void commandserviceChanged(int connfd, char *data, const unsigned dataLen channel_is_blacklisted = true; dmxCN.request_pause(); dmxEIT.request_pause(); +#ifdef ENABLE_SDT + dmxSDT.request_pause(); +#endif } xprintf("[sectionsd] commandserviceChanged: service is filtered!\n"); } @@ -1604,6 +1622,9 @@ static void commandserviceChanged(int connfd, char *data, const unsigned dataLen channel_is_blacklisted = false; dmxCN.request_unpause(); dmxEIT.request_unpause(); +#ifdef ENABLE_SDT + dmxSDT.request_unpause(); +#endif xprintf("[sectionsd] commandserviceChanged: service is no longer filtered!\n"); } } @@ -1648,6 +1669,9 @@ static void commandserviceChanged(int connfd, char *data, const unsigned dataLen dmxEIT.setCurrentService(messaging_current_servicekey & 0xffff); #ifdef ENABLE_FREESATEPG dmxFSEIT.setCurrentService(messaging_current_servicekey & 0xffff); +#endif +#ifdef ENABLE_SDT + dmxSDT.setCurrentService(messaging_current_servicekey & 0xffff); #endif } else @@ -2516,6 +2540,9 @@ static void deleteSIexceptEPG() writeLockServices(); unlockServices(); dmxEIT.dropCachedSectionIDs(); +#ifdef ENABLE_SDT + dmxSDT.dropCachedSectionIDs(); +#endif } static void commandFreeMemory(int connfd, char * /*data*/, const unsigned /*dataLength*/) @@ -2587,11 +2614,13 @@ static void commandWriteSI2XML(int connfd, char *data, const unsigned dataLength return; } +#if 0 /* dummy1: do not send back anything */ static void commandDummy1(int, char *, const unsigned) { return; } +#endif /* dummy2: send back an empty response */ static void commandDummy2(int connfd, char *, const unsigned) @@ -3534,6 +3563,212 @@ static void *cnThread(void *) pthread_exit(NULL); } +#ifdef ENABLE_SDT +static bool addService(const SIservice &s, const int is_actual) +{ + bool already_exists; + bool is_new = false; + + readLockServices(); + MySIservicesOrderUniqueKey::iterator si = mySIservicesOrderUniqueKey.find(s.uniqueKey()); + already_exists = (si != mySIservicesOrderUniqueKey.end()); + unlockServices(); + + if ( (!already_exists) || ((is_actual & 7) && (!si->second->is_actual)) ) { + + if (already_exists) + { + writeLockServices(); + mySIservicesOrderUniqueKey.erase(s.uniqueKey()); + unlockServices(); + } + + SIservice *sp = new SIservice(s); + + if (!sp) + { + printf("[sectionsd::addService] new SIservice failed.\n"); + return false; + } + + SIservicePtr sptr(sp); + +#if 0 +#define MAX_SIZE_SERVICENAME 50 + char servicename[MAX_SIZE_SERVICENAME]; + + if (sptr->serviceName.empty()) { + sprintf(servicename, "%04x", sptr->service_id); + servicename[sizeof(servicename) - 1] = 0; + sptr->serviceName = servicename; + } +#endif + sptr->is_actual = is_actual; + + writeLockServices(); + mySIservicesOrderUniqueKey.insert(std::make_pair(sptr->uniqueKey(), sptr)); + unlockServices(); + + if (sptr->nvods.size()) + { + writeLockServices(); + mySIservicesNVODorderUniqueKey.insert(std::make_pair(sptr->uniqueKey(), sptr)); + unlockServices(); + } + is_new = true; + } + + return is_new; +} + +static void *sdtThread(void *) +{ + const unsigned timeoutInMSeconds = 2500; + t_transponder_id tid = 0; + time_t lastData = 0; + time_t zeit = 0; + int rs = 0; + int is_actual = 0; + + //FIXME + dmxSDT.addfilter(0x42, 0xf3 ); //SDT actual = 0x42 + SDT other = 0x46 + BAT = 0x4A + + dprintf("[%sThread] pid %d (%lu) start\n", "sdt", getpid(), pthread_self()); + + int timeoutsDMX = 0; + uint8_t *static_buf = new uint8_t[MAX_SECTION_LENGTH]; + int rc; + + if (static_buf == NULL) + { + xprintf("%s: could not allocate static_buf\n", __FUNCTION__); + pthread_exit(NULL); + } + + dmxSDT.start(); // -> unlock + + if (!scanning) + dmxSDT.request_pause(); + + bool startup = true; + + waitForTimeset(); + + while (!sectionsd_stop) { + while (!scanning) { + if(sectionsd_stop) + break; + sleep(1); + } + zeit = time_monotonic(); + + if(sectionsd_stop) + break; + + readLockMessaging(); + if (messaging_zap_detected) + startup = true; + unlockMessaging(); + + if ((zeit > lastData + TIME_SDT_NONEWDATA) || (startup)) + { + struct timespec abs_wait; + struct timeval now; + + gettimeofday(&now, NULL); + TIMEVAL_TO_TIMESPEC(&now, &abs_wait); + abs_wait.tv_sec += (TIME_SDT_SCHEDULED_PAUSE); + + dmxSDT.real_pause(); + /* this is the "last" thread. Means: if this one goes to sleep, sectionsd + * sleeps mostly. Worth printing. */ + printdate_ms(stdout); + printf("sdtThread: going to sleep...\n"); + + writeLockMessaging(); + messaging_zap_detected = false; + unlockMessaging(); + + pthread_mutex_lock( &dmxSDT.start_stop_mutex ); + rs = pthread_cond_timedwait( &dmxSDT.change_cond, &dmxSDT.start_stop_mutex, &abs_wait ); + pthread_mutex_unlock( &dmxSDT.start_stop_mutex ); + + if(sectionsd_stop) + break; + + if (rs == ETIMEDOUT) + { + dprintf("dmxSDT: waking up again - looking for new services :)\n"); + dmxSDT.change( 0 ); // -> restart + } + else if (rs == 0) + { + dprintf("dmxSDT: waking up again - requested from .change()\n"); + } + else + { + dprintf("dmxSDT: waking up again - unknown reason?!\n"); + dmxSDT.real_unpause(); + } + // update zeit after sleep + + startup = false; + zeit = time_monotonic(); + timeoutsDMX = 0; + lastData = zeit; + } + + if (timeoutsDMX >= RESTART_DMX_AFTER_TIMEOUTS && scanning) + { + timeoutsDMX = 0; + dmxSDT.stop(); + dmxSDT.start(); // leaves unlocked + dputs("\n !!! dmxSDT restarted !!!\n"); + } + + rc = dmxSDT.getSection(static_buf, timeoutInMSeconds, timeoutsDMX); + + if (rc < 0) + continue; + + LongSection sec(static_buf); + uint8_t table_id = sec.getTableId(); + if ((table_id == 0x42) || (table_id == 0x46)) + { + SIsectionSDT sdt(static_buf); + + is_actual = (sdt.getTableId() == 0x42) ? 1 : 0; + + if (is_actual && !sdt.getLastSectionNumber()) + is_actual = 2; + + bool is_new = false; + is_actual = (is_actual | 8); + + for (SIservices::iterator s = sdt.services().begin(); s != sdt.services().end(); s++) { + if (addService(*s, is_actual)) { + is_new = true; + tid = CREATE_TRANSPONDER_ID_FROM_ORIGINALNETWORK_TRANSPORTSTREAM_ID(s->original_network_id, + s->transport_stream_id); + } + } + + if (is_new) { + lastData = time_monotonic(); + + dprintf("[sdtThread] added %d services [table 0x%x TID: %08x]\n", + sdt.services().size(), table_id, tid); + } + } + } // for + + delete[] static_buf; + printf("[sectionsd] sdt-thread ended\n"); + + pthread_exit(NULL); +} +#endif + /* helper function for the housekeeping-thread */ static void print_meminfo(void) { @@ -3692,11 +3927,14 @@ static void readDVBTimeFilter(void) extern cDemux * dmxUTC; -void sectionsd_main_thread(void */*data*/) +void sectionsd_main_thread(void * /*data*/) { pthread_t threadTOT, threadEIT, threadCN, threadHouseKeeping; #ifdef ENABLE_FREESATEPG pthread_t threadFSEIT; +#endif +#ifdef ENABLE_SDT + pthread_t threadSDT; #endif int rc; @@ -3704,6 +3942,7 @@ void sectionsd_main_thread(void */*data*/) printf("$Id: sectionsd.cpp,v 1.305 2009/07/30 12:41:39 seife Exp $\n"); printf("SIevent size: %d\n", sizeof(SIevent)); + /* "export NO_SLOW_ADDEVENT=true" to disable this */ slow_addevent = (getenv("NO_SLOW_ADDEVENT") == NULL); if (slow_addevent) @@ -3789,6 +4028,15 @@ printf("SIevent size: %d\n", sizeof(SIevent)); return; } #endif +#ifdef ENABLE_SDT + printf("\n\n\n[sectionsd] starting SDT thread\n"); + rc = pthread_create(&threadSDT, 0, sdtThread, 0); + + if (rc) { + fprintf(stderr, "[sectionsd] failed to create sdt-thread (rc=%d)\n", rc); + return; + } +#endif // housekeeping-Thread starten rc = pthread_create(&threadHouseKeeping, 0, houseKeepingThread, 0); @@ -3816,14 +4064,13 @@ printf("SIevent size: %d\n", sizeof(SIevent)); printdate_ms(stdout); printf("EIT Update Filter: new version 0x%x, Activate cnThread\n", ((SI_section_header*)buf)->version_number); + writeLockMessaging(); - // messaging_skipped_sections_ID[0].clear(); - // messaging_sections_max_ID[0] = -1; - // messaging_sections_got_all[0] = false; messaging_have_CN = 0x00; messaging_got_CN = 0x00; messaging_last_requested = time_monotonic(); unlockMessaging(); + sched_yield(); dmxCN.change(0); sched_yield(); @@ -3854,11 +4101,20 @@ printf("SIevent size: %d\n", sizeof(SIevent)); pthread_mutex_lock(&dmxCN.start_stop_mutex); pthread_cond_broadcast(&dmxCN.change_cond); pthread_mutex_unlock(&dmxCN.start_stop_mutex); +#ifdef ENABLE_SDT + pthread_mutex_lock(&dmxSDT.start_stop_mutex); + pthread_cond_broadcast(&dmxSDT.change_cond); + pthread_mutex_unlock(&dmxSDT.start_stop_mutex); +#endif + printf("pausing...\n"); dmxEIT.request_pause(); dmxCN.request_pause(); #ifdef ENABLE_FREESATEPG dmxFSEIT.request_pause(); +#endif +#ifdef ENABLE_SDT + dmxSDT.request_pause(); #endif pthread_cancel(threadHouseKeeping); @@ -3873,6 +4129,10 @@ printf("SIevent size: %d\n", sizeof(SIevent)); pthread_join(threadEIT, NULL); printf("join 3\n"); pthread_join(threadCN, NULL); +#ifdef ENABLE_SDT + printf("join 4\n"); + pthread_join(threadSDT, NULL); +#endif eit_stop_update_filter(&eit_update_fd); if(eitDmx) @@ -3884,6 +4144,9 @@ printf("SIevent size: %d\n", sizeof(SIevent)); dmxCN.close(); #ifdef ENABLE_FREESATEPG dmxFSEIT.close(); +#endif +#ifdef ENABLE_SDT + dmxSDT.close(); #endif printf("[sectionsd] ended\n");