eitd: SDT thread re-added, as is but without BAT.

TODO: unify SDT thread algo with other threads
This commit is contained in:
[CST] Focus
2012-02-09 20:46:40 +04:00
parent 018c1c868a
commit b026b6b9a7
5 changed files with 380 additions and 155 deletions

View File

@@ -44,6 +44,8 @@
#endif #endif
#include <dvbsi++/descriptor_tag.h> #include <dvbsi++/descriptor_tag.h>
#include <dvbsi++/nvod_reference_descriptor.h>
#include <dvbsi++/service_descriptor.h>
struct descr_generic_header { struct descr_generic_header {
unsigned descriptor_tag : 8; unsigned descriptor_tag : 8;
@@ -61,12 +63,14 @@ struct descr_short_event_header {
} __attribute__ ((packed)) ; } __attribute__ ((packed)) ;
#endif #endif
#if 0
struct descr_service_header { struct descr_service_header {
unsigned descriptor_tag : 8; unsigned descriptor_tag : 8;
unsigned descriptor_length : 8; unsigned descriptor_length : 8;
unsigned service_typ : 8; unsigned service_typ : 8;
unsigned service_provider_name_length : 8; unsigned service_provider_name_length : 8;
} __attribute__ ((packed)) ; } __attribute__ ((packed)) ;
#endif
#if 0 #if 0
struct descr_extended_event_header { struct descr_extended_event_header {
@@ -81,6 +85,7 @@ struct descr_extended_event_header {
} __attribute__ ((packed)) ; } __attribute__ ((packed)) ;
#endif #endif
#if 0
struct service_list_entry { struct service_list_entry {
unsigned service_id_hi : 8; unsigned service_id_hi : 8;
unsigned service_id_lo : 8; unsigned service_id_lo : 8;
@@ -98,6 +103,7 @@ inline unsigned min(unsigned a, unsigned b)
{ {
return b < a ? b : a; return b < a ? b : a;
} }
#endif
void SIsectionEIT::parse(void) void SIsectionEIT::parse(void)
{ {
@@ -367,6 +373,7 @@ void SIsectionEIT::parseDescriptors(const uint8_t *des, unsigned len, SIevent &e
#endif #endif
/********************/ /********************/
#if 0
bool check_blacklisted(const t_original_network_id onid, const t_transport_stream_id tsid) bool check_blacklisted(const t_original_network_id onid, const t_transport_stream_id tsid)
{ {
if ( (onid == 0x0001) && if ( (onid == 0x0001) &&
@@ -451,9 +458,11 @@ void SIsectionSDT::parseDescriptors(const uint8_t *des, unsigned len, SIservice
} }
} }
#endif
// Die infos aus dem Puffer holen // Die infos aus dem Puffer holen
void SIsectionSDT::parse(void) void SIsectionSDT::parse(void)
{ {
#if 0
const uint8_t *actPos; const uint8_t *actPos;
const uint8_t *bufEnd; const uint8_t *bufEnd;
struct sdt_service *sv; struct sdt_service *sv;
@@ -481,114 +490,45 @@ void SIsectionSDT::parse(void)
svs.insert(s); svs.insert(s);
actPos += descriptors_loop_length; actPos += descriptors_loop_length;
} }
#endif
parsed = 1; 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;
#if 0 //def ENABLE_FREESATEPG SIservice s(service->getServiceId(), original_network_id, transport_stream_id);
std::string SIsectionEIT::freesatHuffmanDecode(std::string input)
{
const char *src = input.c_str();
uint size = input.length();
if (src[1] == 1 || src[1] == 2) s.flags.EIT_schedule_flag = service->getEitScheduleFlag();
{ s.flags.EIT_present_following_flag = service->getEitPresentFollowingFlag();
std::string uncompressed(size * 3, ' '); s.flags.running_status = service->getRunningStatus();
uint p = 0; s.flags.free_CA_mode = service->getFreeCaMode();
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 DescriptorConstIterator dit;
for (dit = service->getDescriptors()->begin(); dit != service->getDescriptors()->end(); ++dit) {
switch ((*dit)->getTag()) {
case SERVICE_DESCRIPTOR:
{ {
bool found = false; ServiceDescriptor * d = (ServiceDescriptor *) *dit;
unsigned bitShift = 0; s.serviceTyp = d->getServiceType();
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 break;
case NVOD_REFERENCE_DESCRIPTOR:
{ {
for (unsigned j = 0; j < table_length; j++) NvodReferenceDescriptor * d = (NvodReferenceDescriptor *) *dit;
{ NvodReferenceConstIterator it;
if (table[j].last == lastch) const NvodReferenceList* nlist = d->getNvodReferences();
{ for (it = nlist->begin(); it != nlist->end(); ++it) {
unsigned mask = 0, maskbit = 0x80000000; SInvodReference nvod((*it)->getTransportStreamId(), (*it)->getOriginalNetworkId(), (*it)->getServiceId());
for (short kk = 0; kk < table[j].bits; kk++) s.nvods.insert(nvod);
{
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; break;
lastch = nextCh; default:
break; break;
} }
} }
svs.insert(s);
} }
} }
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

View File

@@ -27,7 +27,9 @@
#include <endian.h> #include <endian.h>
#include <dvbsi++/event_information_section.h> #include <dvbsi++/event_information_section.h>
#include <dvbsi++/service_description_section.h>
#if 0
struct SI_section_SDT_header { struct SI_section_SDT_header {
unsigned table_id : 8; unsigned table_id : 8;
#if __BYTE_ORDER == __BIG_ENDIAN #if __BYTE_ORDER == __BIG_ENDIAN
@@ -59,6 +61,7 @@ struct SI_section_SDT_header {
unsigned original_network_id_lo : 8; unsigned original_network_id_lo : 8;
unsigned reserved_future_use2 : 8; unsigned reserved_future_use2 : 8;
} __attribute__ ((packed)) ; // 11 bytes } __attribute__ ((packed)) ; // 11 bytes
#endif
#if 0 #if 0
struct SI_section_EIT_header { 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: public:
#if 0
SIsectionSDT(const SIsection &s) : SIsection(s) { SIsectionSDT(const SIsection &s) : SIsection(s) {
parsed = 0; parsed = 0;
parse(); parse();
} }
#endif
#if 0 #if 0
// Std-Copy // Std-Copy
SIsectionSDT(const SIsectionSDT &s) : SIsection(s) { SIsectionSDT(const SIsectionSDT &s) : SIsection(s) {
@@ -228,11 +242,12 @@ public:
} }
#endif #endif
// Benutzt den uebergebenen Puffer (sollte mit new char[n] allokiert sein) // 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; parsed = 0;
parse(); parse();
} }
#if 0
t_transport_stream_id transport_stream_id(void) const { t_transport_stream_id transport_stream_id(void) const {
return buffer ? ((((struct SI_section_SDT_header *)buffer)->transport_stream_id_hi << 8) | return buffer ? ((((struct SI_section_SDT_header *)buffer)->transport_stream_id_hi << 8) |
((struct SI_section_SDT_header *)buffer)->transport_stream_id_lo) : 0; ((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) | return buffer ? ((((struct SI_section_SDT_header *)buffer)->original_network_id_hi << 8) |
((struct SI_section_SDT_header *)buffer)->original_network_id_lo) : 0; ((struct SI_section_SDT_header *)buffer)->original_network_id_lo) : 0;
} }
#endif
#if 0 #if 0
static void dump(const struct SI_section_SDT_header *header) { static void dump(const struct SI_section_SDT_header *header) {
if (!header) if (!header)
@@ -272,14 +288,6 @@ public:
return svs; 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 #endif // SISECTIONS_HPP

View File

@@ -37,6 +37,7 @@
class SIservice; class SIservice;
class SIevent; class SIevent;
#if 0
struct sdt_service { struct sdt_service {
unsigned service_id_hi : 8; unsigned service_id_hi : 8;
unsigned service_id_lo : 8; unsigned service_id_lo : 8;
@@ -57,7 +58,7 @@ struct sdt_service {
#endif #endif
unsigned descriptors_loop_length_lo : 8; unsigned descriptors_loop_length_lo : 8;
} __attribute__ ((packed)) ; // 5 Bytes } __attribute__ ((packed)) ; // 5 Bytes
#endif
class SInvodReference class SInvodReference
{ {
@@ -72,13 +73,14 @@ public:
original_network_id = new_original_network_id; original_network_id = new_original_network_id;
transport_stream_id = new_transport_stream_id; transport_stream_id = new_transport_stream_id;
} }
#if 0
SInvodReference(const SInvodReference &ref) SInvodReference(const SInvodReference &ref)
{ {
service_id = ref.service_id; service_id = ref.service_id;
original_network_id = ref.original_network_id; original_network_id = ref.original_network_id;
transport_stream_id = ref.transport_stream_id; transport_stream_id = ref.transport_stream_id;
} }
#endif
bool operator < (const SInvodReference& ref) const bool operator < (const SInvodReference& ref) const
{ {
@@ -117,8 +119,28 @@ struct printSInvodReference : public std::unary_function<class SInvodReference,
typedef std::set <SInvodReference, std::less<SInvodReference> > SInvodReferences; typedef std::set <SInvodReference, std::less<SInvodReference> > SInvodReferences;
class SIservice { class SIservice
{
//protected:
public: 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) { SIservice(const struct sdt_service *s) {
service_id = (s->service_id_hi << 8) | s->service_id_lo; service_id = (s->service_id_hi << 8) | s->service_id_lo;
original_network_id = 0; original_network_id = 0;
@@ -130,6 +152,7 @@ public:
flags.free_CA_mode = s->free_CA_mode; flags.free_CA_mode = s->free_CA_mode;
is_actual = false; is_actual = false;
} }
#endif
// Um einen service zum Suchen zu erstellen // 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) 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; serviceTyp=0;
memset(&flags, 0, sizeof(flags)); memset(&flags, 0, sizeof(flags));
} }
#if 0
// Std-Copy // Std-Copy
SIservice(const SIservice &s) { SIservice(const SIservice &s) {
service_id = s.service_id; service_id = s.service_id;
@@ -151,14 +176,7 @@ public:
nvods=s.nvods; nvods=s.nvods;
is_actual=s.is_actual; is_actual=s.is_actual;
} }
t_service_id service_id; #endif
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 eitScheduleFlag(void) { return (int)flags.EIT_schedule_flag; }
int eitPresentFollowingFlag(void) { return (int)flags.EIT_present_following_flag; } int eitPresentFollowingFlag(void) { return (int)flags.EIT_present_following_flag; }
int runningStatus(void) { return (int)flags.running_status; } int runningStatus(void) { return (int)flags.running_status; }
@@ -178,20 +196,15 @@ public:
printf("Original-Network-ID: %hu\n", original_network_id); printf("Original-Network-ID: %hu\n", original_network_id);
printf("Service-ID: %hu\n", service_id); printf("Service-ID: %hu\n", service_id);
printf("Service-Typ: %hhu\n", serviceTyp); printf("Service-Typ: %hhu\n", serviceTyp);
#if 0
if(providerName.length()) if(providerName.length())
printf("Provider-Name: %s\n", providerName.c_str()); printf("Provider-Name: %s\n", providerName.c_str());
if(serviceName.length()) if(serviceName.length())
printf("Service-Name: %s\n", serviceName.c_str()); printf("Service-Name: %s\n", serviceName.c_str());
#endif
for_each(nvods.begin(), nvods.end(), printSInvodReference()); for_each(nvods.begin(), nvods.end(), printSInvodReference());
printf("\n"); 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 // Fuer for_each

View File

@@ -53,7 +53,8 @@ int getCountryCodeDefaultMapping( const std::string &lang )
CountryCodeDefaultMapping.find(lang); CountryCodeDefaultMapping.find(lang);
if ( it != CountryCodeDefaultMapping.end() ) if ( it != CountryCodeDefaultMapping.end() )
return it->second; 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/ // 8859-x to ucs-16 coding tables. taken from www.unicode.org/Public/MAPPINGS/ISO8859/

View File

@@ -61,6 +61,8 @@
#include "eitd.h" #include "eitd.h"
#include "edvbstring.h" #include "edvbstring.h"
#define ENABLE_SDT //FIXME
// 60 Minuten Zyklus... // 60 Minuten Zyklus...
#define TIME_EIT_SCHEDULED_PAUSE 60 * 60 #define TIME_EIT_SCHEDULED_PAUSE 60 * 60
// -- 5 Minutes max. pause should improve behavior (rasc, 2005-05-02) // -- 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 // Zeit die fuer die gewartet wird, bevor der Filter weitergeschaltet wird, falls es automatisch nicht klappt
#define TIME_EIT_SKIPPING 90 #define TIME_EIT_SKIPPING 90
#define ENABLE_FREESATEPG // FIXME
#ifdef ENABLE_FREESATEPG #ifdef ENABLE_FREESATEPG
// a little more time for freesat epg
#define TIME_FSEIT_SKIPPING 240
#endif #endif
static bool sectionsd_ready = false; static bool sectionsd_ready = false;
@@ -86,9 +85,6 @@ static unsigned int max_events;
#define READ_TIMEOUT_IN_SECONDS 2 #define READ_TIMEOUT_IN_SECONDS 2
#define WRITE_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 // 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! // 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, /* 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 */ but those are not a big deal, so let's save some memory */
static DMX dmxEIT(0x12, 3000 /*320*/); static DMX dmxEIT(0x12, 3000 /*320*/);
static DMX dmxCN(0x12, 512, false, 1);
#ifdef ENABLE_FREESATEPG #ifdef ENABLE_FREESATEPG
// a little more time for freesat epg
#define TIME_FSEIT_SKIPPING 240
static DMX dmxFSEIT(3842, 320); static DMX dmxFSEIT(3842, 320);
#endif #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; int sectionsd_stop = 0;
static bool slow_addevent = true; static bool slow_addevent = true;
@@ -1081,6 +1087,9 @@ static void commandPauseScanning(int connfd, char *data, const unsigned dataLeng
dmxEIT.request_pause(); dmxEIT.request_pause();
#ifdef ENABLE_FREESATEPG #ifdef ENABLE_FREESATEPG
dmxFSEIT.request_pause(); dmxFSEIT.request_pause();
#endif
#ifdef ENABLE_SDT
dmxSDT.request_pause();
#endif #endif
scanning = 0; scanning = 0;
} }
@@ -1090,6 +1099,9 @@ static void commandPauseScanning(int connfd, char *data, const unsigned dataLeng
dmxEIT.request_unpause(); dmxEIT.request_unpause();
#ifdef ENABLE_FREESATEPG #ifdef ENABLE_FREESATEPG
dmxFSEIT.request_unpause(); dmxFSEIT.request_unpause();
#endif
#ifdef ENABLE_SDT
dmxSDT.request_unpause();
#endif #endif
writeLockEvents(); writeLockEvents();
if (myCurrentEvent) { if (myCurrentEvent) {
@@ -1118,6 +1130,9 @@ static void commandPauseScanning(int connfd, char *data, const unsigned dataLeng
dmxEIT.change(0); dmxEIT.change(0);
#ifdef ENABLE_FREESATEPG #ifdef ENABLE_FREESATEPG
dmxFSEIT.change(0); dmxFSEIT.change(0);
#endif
#ifdef ENABLE_SDT
dmxSDT.change(0);
#endif #endif
} }
@@ -1595,6 +1610,9 @@ static void commandserviceChanged(int connfd, char *data, const unsigned dataLen
channel_is_blacklisted = true; channel_is_blacklisted = true;
dmxCN.request_pause(); dmxCN.request_pause();
dmxEIT.request_pause(); dmxEIT.request_pause();
#ifdef ENABLE_SDT
dmxSDT.request_pause();
#endif
} }
xprintf("[sectionsd] commandserviceChanged: service is filtered!\n"); 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; channel_is_blacklisted = false;
dmxCN.request_unpause(); dmxCN.request_unpause();
dmxEIT.request_unpause(); dmxEIT.request_unpause();
#ifdef ENABLE_SDT
dmxSDT.request_unpause();
#endif
xprintf("[sectionsd] commandserviceChanged: service is no longer filtered!\n"); 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); dmxEIT.setCurrentService(messaging_current_servicekey & 0xffff);
#ifdef ENABLE_FREESATEPG #ifdef ENABLE_FREESATEPG
dmxFSEIT.setCurrentService(messaging_current_servicekey & 0xffff); dmxFSEIT.setCurrentService(messaging_current_servicekey & 0xffff);
#endif
#ifdef ENABLE_SDT
dmxSDT.setCurrentService(messaging_current_servicekey & 0xffff);
#endif #endif
} }
else else
@@ -2516,6 +2540,9 @@ static void deleteSIexceptEPG()
writeLockServices(); writeLockServices();
unlockServices(); unlockServices();
dmxEIT.dropCachedSectionIDs(); dmxEIT.dropCachedSectionIDs();
#ifdef ENABLE_SDT
dmxSDT.dropCachedSectionIDs();
#endif
} }
static void commandFreeMemory(int connfd, char * /*data*/, const unsigned /*dataLength*/) 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; return;
} }
#if 0
/* dummy1: do not send back anything */ /* dummy1: do not send back anything */
static void commandDummy1(int, char *, const unsigned) static void commandDummy1(int, char *, const unsigned)
{ {
return; return;
} }
#endif
/* dummy2: send back an empty response */ /* dummy2: send back an empty response */
static void commandDummy2(int connfd, char *, const unsigned) static void commandDummy2(int connfd, char *, const unsigned)
@@ -3534,6 +3563,212 @@ static void *cnThread(void *)
pthread_exit(NULL); 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 */ /* helper function for the housekeeping-thread */
static void print_meminfo(void) static void print_meminfo(void)
{ {
@@ -3697,6 +3932,9 @@ void sectionsd_main_thread(void */*data*/)
pthread_t threadTOT, threadEIT, threadCN, threadHouseKeeping; pthread_t threadTOT, threadEIT, threadCN, threadHouseKeeping;
#ifdef ENABLE_FREESATEPG #ifdef ENABLE_FREESATEPG
pthread_t threadFSEIT; pthread_t threadFSEIT;
#endif
#ifdef ENABLE_SDT
pthread_t threadSDT;
#endif #endif
int rc; 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("$Id: sectionsd.cpp,v 1.305 2009/07/30 12:41:39 seife Exp $\n");
printf("SIevent size: %d\n", sizeof(SIevent)); printf("SIevent size: %d\n", sizeof(SIevent));
/* "export NO_SLOW_ADDEVENT=true" to disable this */ /* "export NO_SLOW_ADDEVENT=true" to disable this */
slow_addevent = (getenv("NO_SLOW_ADDEVENT") == NULL); slow_addevent = (getenv("NO_SLOW_ADDEVENT") == NULL);
if (slow_addevent) if (slow_addevent)
@@ -3789,6 +4028,15 @@ printf("SIevent size: %d\n", sizeof(SIevent));
return; return;
} }
#endif #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 // housekeeping-Thread starten
rc = pthread_create(&threadHouseKeeping, 0, houseKeepingThread, 0); rc = pthread_create(&threadHouseKeeping, 0, houseKeepingThread, 0);
@@ -3816,14 +4064,13 @@ printf("SIevent size: %d\n", sizeof(SIevent));
printdate_ms(stdout); printdate_ms(stdout);
printf("EIT Update Filter: new version 0x%x, Activate cnThread\n", ((SI_section_header*)buf)->version_number); printf("EIT Update Filter: new version 0x%x, Activate cnThread\n", ((SI_section_header*)buf)->version_number);
writeLockMessaging(); writeLockMessaging();
// messaging_skipped_sections_ID[0].clear();
// messaging_sections_max_ID[0] = -1;
// messaging_sections_got_all[0] = false;
messaging_have_CN = 0x00; messaging_have_CN = 0x00;
messaging_got_CN = 0x00; messaging_got_CN = 0x00;
messaging_last_requested = time_monotonic(); messaging_last_requested = time_monotonic();
unlockMessaging(); unlockMessaging();
sched_yield(); sched_yield();
dmxCN.change(0); dmxCN.change(0);
sched_yield(); sched_yield();
@@ -3854,11 +4101,20 @@ printf("SIevent size: %d\n", sizeof(SIevent));
pthread_mutex_lock(&dmxCN.start_stop_mutex); pthread_mutex_lock(&dmxCN.start_stop_mutex);
pthread_cond_broadcast(&dmxCN.change_cond); pthread_cond_broadcast(&dmxCN.change_cond);
pthread_mutex_unlock(&dmxCN.start_stop_mutex); 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"); printf("pausing...\n");
dmxEIT.request_pause(); dmxEIT.request_pause();
dmxCN.request_pause(); dmxCN.request_pause();
#ifdef ENABLE_FREESATEPG #ifdef ENABLE_FREESATEPG
dmxFSEIT.request_pause(); dmxFSEIT.request_pause();
#endif
#ifdef ENABLE_SDT
dmxSDT.request_pause();
#endif #endif
pthread_cancel(threadHouseKeeping); pthread_cancel(threadHouseKeeping);
@@ -3873,6 +4129,10 @@ printf("SIevent size: %d\n", sizeof(SIevent));
pthread_join(threadEIT, NULL); pthread_join(threadEIT, NULL);
printf("join 3\n"); printf("join 3\n");
pthread_join(threadCN, NULL); pthread_join(threadCN, NULL);
#ifdef ENABLE_SDT
printf("join 4\n");
pthread_join(threadSDT, NULL);
#endif
eit_stop_update_filter(&eit_update_fd); eit_stop_update_filter(&eit_update_fd);
if(eitDmx) if(eitDmx)
@@ -3884,6 +4144,9 @@ printf("SIevent size: %d\n", sizeof(SIevent));
dmxCN.close(); dmxCN.close();
#ifdef ENABLE_FREESATEPG #ifdef ENABLE_FREESATEPG
dmxFSEIT.close(); dmxFSEIT.close();
#endif
#ifdef ENABLE_SDT
dmxSDT.close();
#endif #endif
printf("[sectionsd] ended\n"); printf("[sectionsd] ended\n");