eitd/sectionsd.cpp: testing abstract classes and common thread code

This commit is contained in:
[CST] Focus
2012-02-29 19:48:38 +04:00
parent 4c6199eef5
commit 55dbf7f63e
2 changed files with 323 additions and 391 deletions

View File

@@ -44,6 +44,21 @@ typedef SIevent * SIeventPtr;
typedef SIservice * SIservicePtr;
#endif
/* period to restart EIT reading */
#define TIME_EIT_SCHEDULED_PAUSE 60 * 60
/* force EIT thread to change filter after, seconds */
#define TIME_EIT_SKIPPING 120 // 90 <- Canal diditaal 19.2e -> ~100 seconds for 0x5x
/* a little more time for freesat epg */
#define TIME_FSEIT_SKIPPING 240
/* 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! */
#define EIT_READ_TIMEOUT 100
/* Number of DMX read timeouts, after which we check if there is an EIT at all
for EIT and PPT threads... */
#define CHECK_RESTART_DMX_AFTER_TIMEOUTS (2000 / EIT_READ_TIMEOUT) // 2 seconds
struct OrderServiceUniqueKeyFirstStartTimeEventUniqueKey
{
bool operator()(const SIeventPtr &p1, const SIeventPtr &p2)
@@ -83,40 +98,64 @@ typedef std::map<t_channel_id, SIservicePtr, std::less<t_channel_id> > MySIservi
#define MAX_SECTION_LENGTH (0x0fff + 3)
/* abstract section reading class */
class CSectionThread : public OpenThreads::Thread, public DMX
{
protected:
uint8_t *static_buf;
int timeoutsDMX;
unsigned timeoutInMSeconds;
bool running;
//std::string name;
int event_count; // debug
/* section read timeout, msec */
unsigned timeoutInMSeconds;
/* read timeouts count to switch to next filter */
int skipTimeouts;
/* time to switch to next filter */
int skipTime;
bool sendToSleepNow;
virtual void run() {};
int Sleep(unsigned int timeout)
{
struct timespec abs_wait;
struct timeval now;
gettimeofday(&now, NULL);
TIMEVAL_TO_TIMESPEC(&now, &abs_wait);
abs_wait.tv_sec += timeout;
dprintf("%s: going to sleep for %d seconds...\n", name.c_str(), timeout);
pthread_mutex_lock(&start_stop_mutex);
int rs = pthread_cond_timedwait( &change_cond, &start_stop_mutex, &abs_wait );
pthread_mutex_unlock( &start_stop_mutex );
return rs;
}
bool addEvents();
/* should thread wait for time set before process loop */
bool wait_for_time;
/* time in seconds to sleep when requested, wait forever if 0 */
int sleep_time;
/* thread hooks */
/* add filters when thread started */
virtual void addFilters() {};
/* check if thread should go sleep */
virtual bool shouldSleep() { return false; };
/* check if thread should continue to sleep after wakeup or timeout */
virtual bool checkSleep() { return false; };
/* called before sleep loop */
virtual void beforeSleep() {};
/* called after sleep loop */
virtual void afterSleep() {};
/* called inside sleep loop, after lock, before wait */
virtual void beforeWait() {};
/* called inside sleep loop, before lock, after wait */
virtual void afterWait() {};
/* process section after getSection */
virtual void processSection(int rc) { if(rc < 0) return; };
/* cleanup before exit */
virtual void cleanup() {};
/* sleep for sleep_time, forever if sleep_time = 0 */
int Sleep();
/* main thread function */
void run();
public:
CSectionThread()
{
static_buf = new uint8_t[MAX_SECTION_LENGTH];
timeoutsDMX = 0;
running = false;
event_count = 0;
sendToSleepNow = 0;
}
~CSectionThread()
@@ -151,23 +190,69 @@ printf("%s::Stop: to close\n", name.c_str());
}
};
class CEitThread : public CSectionThread
/* abstract eit events reading class */
class CEventsThread : public CSectionThread
{
private:
void run();
protected:
/* default hooks */
bool shouldSleep();
bool checkSleep();
void processSection(int rc);
/* private */
bool addEvents();
public:
CEventsThread(std::string tname, unsigned short pid = 0x12)
{
name = tname;
pID = pid;
/* defaults for events threads, redefined if needed in derived */
timeoutInMSeconds = EIT_READ_TIMEOUT;
skipTimeouts = CHECK_RESTART_DMX_AFTER_TIMEOUTS;
skipTime = TIME_EIT_SKIPPING;
sleep_time = TIME_EIT_SCHEDULED_PAUSE;
wait_for_time = true;
};
};
class CCNThread : public CSectionThread
class CEitThread : public CEventsThread
{
private:
/* overloaded hooks */
void addFilters();
void beforeSleep();
public:
CEitThread();
};
class CFreeSatThread : public CEventsThread
{
private:
/* overloaded hooks */
void addFilters();
public:
CFreeSatThread();
};
class CCNThread : public CEventsThread
{
private:
/* private */
bool updating;
cDemux * eitDmx;
void sendCNEvent();
bool startUpdateFilter();
bool stopUpdateFilter();
void run();
/* overloaded hooks */
void beforeWait();
void afterWait();
void addFilters();
void beforeSleep();
void processSection(int rc);
void cleanup();
public:
CCNThread();
bool checkUpdate();
};

View File

@@ -67,13 +67,6 @@
#define DEBUG_EIT_THREAD
#define DEBUG_CN_THREAD
/* period to restart EIT reading */
#define TIME_EIT_SCHEDULED_PAUSE 60 * 60
/* force EIT thread to change filter after, seconds */
#define TIME_EIT_SKIPPING 120 // 90 <- Canal diditaal 19.2e -> ~100 seconds for 0x5x
// a little more time for freesat epg
#define TIME_FSEIT_SKIPPING 240
static bool sectionsd_ready = false;
/*static*/ bool reader_ready = true;
static unsigned int max_events;
@@ -88,13 +81,6 @@ static unsigned int max_events;
#define READ_TIMEOUT_IN_SECONDS 2
#define WRITE_TIMEOUT_IN_SECONDS 2
// 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!
#define EIT_READ_TIMEOUT 100
// Number of DMX read timeouts, after which we check if there is an EIT at all
// for EIT and PPT threads...
#define CHECK_RESTART_DMX_AFTER_TIMEOUTS (2000 / EIT_READ_TIMEOUT) // 2 seconds
// Time in seconds we are waiting for an EIT version number
//#define TIME_EIT_VERSION_WAIT 3 // old
#define TIME_EIT_VERSION_WAIT 10
@@ -152,14 +138,11 @@ static pthread_rwlock_t messagingLock = PTHREAD_RWLOCK_INITIALIZER;
static pthread_cond_t timeThreadSleepCond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t timeThreadSleepMutex = PTHREAD_MUTEX_INITIALIZER;
//static DMX dmxEIT(0x12, 3000 /*320*/);
static CEitThread threadEIT;
//static DMX dmxCN(0x12, 512, false, 1);
static CCNThread threadCN;
#ifdef ENABLE_FREESATEPG
static DMX dmxFSEIT(3842, 320);
static CFreeSatThread threadFSEIT;
#endif
#ifdef ENABLE_SDT
@@ -1454,152 +1437,121 @@ xprintf("timeThread: going to sleep for %d sec\n\n", seconds);
pthread_exit(NULL);
}
#ifdef ENABLE_FREESATEPG
//---------------------------------------------------------------------
// Freesat EIT-thread
// reads Freesat EPG-data
//---------------------------------------------------------------------
static void *fseitThread(void *)
/********************************************************************************/
/* abstract CSectionThread functions */
/********************************************************************************/
/* sleep for sleep_time seconds, forever if sleep_time = 0 */
int CSectionThread::Sleep()
{
/* we are holding the start_stop lock during this timeout, so don't
make it too long... */
unsigned timeoutInMSeconds = EIT_READ_TIMEOUT;
bool sendToSleepNow = false;
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
dmxFSEIT.addfilter(0x60, 0xfe); //other TS, scheduled, freesat epg is only broadcast using table_ids 0x60 (scheduled) and 0x61 (scheduled later)
if (sections_debug)
dump_sched_info("freesatEitThread");
dprintf("[%sThread] pid %d (%lu) start\n", "fseit", getpid(), pthread_self());
int timeoutsDMX = 0;
uint8_t *static_buf = new uint8_t[MAX_SECTION_LENGTH];
int rc;
dmxFSEIT.start(); // -> unlock
if (!scanning)
dmxFSEIT.request_pause();
waitForTimeset();
dmxFSEIT.lastChanged = time_monotonic();
while(!sectionsd_stop) {
while (!scanning) {
if(sectionsd_stop)
break;
sleep(1);
}
if(sectionsd_stop)
break;
time_t zeit = time_monotonic();
rc = dmxFSEIT.getSection(static_buf, timeoutInMSeconds, timeoutsDMX);
if (rc < 0)
continue;
if (timeoutsDMX < 0)
{
if ( dmxFSEIT.filter_index + 1 < (signed) dmxFSEIT.filters.size() )
{
if (timeoutsDMX == -1)
dprintf("[freesatEitThread] skipping to next filter(%d) (> DMX_HAS_ALL_SECTIONS_SKIPPING)\n", dmxFSEIT.filter_index+1 );
if (timeoutsDMX == -2)
dprintf("[freesatEitThread] skipping to next filter(%d) (> DMX_HAS_ALL_CURRENT_SECTIONS_SKIPPING)\n", dmxFSEIT.filter_index+1 );
timeoutsDMX = 0;
dmxFSEIT.change(dmxFSEIT.filter_index + 1);
}
else {
sendToSleepNow = true;
timeoutsDMX = 0;
}
}
if (timeoutsDMX >= CHECK_RESTART_DMX_AFTER_TIMEOUTS && scanning)
{
if ( dmxFSEIT.filter_index + 1 < (signed) dmxFSEIT.filters.size() )
{
dprintf("[freesatEitThread] skipping to next filter(%d) (> DMX_TIMEOUT_SKIPPING)\n", dmxFSEIT.filter_index+1 );
dmxFSEIT.change(dmxFSEIT.filter_index + 1);
}
else
sendToSleepNow = true;
timeoutsDMX = 0;
}
if (sendToSleepNow)
{
sendToSleepNow = false;
if(sectionsd_stop)
break;
dmxFSEIT.real_pause();
pthread_mutex_lock( &dmxFSEIT.start_stop_mutex );
writeLockMessaging();
messaging_zap_detected = false;
unlockMessaging();
int rs;
struct timespec abs_wait;
struct timeval now;
if(sleep_time) {
gettimeofday(&now, NULL);
TIMEVAL_TO_TIMESPEC(&now, &abs_wait);
abs_wait.tv_sec += TIME_EIT_SCHEDULED_PAUSE;
dprintf("dmxFSEIT: going to sleep for %d seconds...\n", TIME_EIT_SCHEDULED_PAUSE);
abs_wait.tv_sec += sleep_time;
}
xprintf("%s: going to sleep for %d seconds...\n", name.c_str(), sleep_time);
pthread_mutex_lock(&start_stop_mutex);
int rs = pthread_cond_timedwait( &dmxFSEIT.change_cond, &dmxFSEIT.start_stop_mutex, &abs_wait );
beforeWait();
if(sleep_time)
rs = pthread_cond_timedwait( &change_cond, &start_stop_mutex, &abs_wait );
else
rs = pthread_cond_wait(&change_cond, &start_stop_mutex);
pthread_mutex_unlock( &dmxFSEIT.start_stop_mutex );
afterWait();
pthread_mutex_unlock( &start_stop_mutex );
return rs;
}
/* common thread main function */
void CSectionThread::run()
{
xprintf("%s::run:: starting, pid %d (%lu)\n", name.c_str(), getpid(), pthread_self());
if (sections_debug)
dump_sched_info(name.c_str());
addFilters();
if (wait_for_time) {
waitForTimeset();
xprintf("%s::run:: time set.\n", name.c_str());
}
DMX::start();
while (running) {
if (shouldSleep()) {
#ifdef DEBUG_EIT_THREAD
xprintf("%s: going to sleep %d seconds, running %d scanning %d blacklisted %d events %d\n",
name.c_str(), sleep_time, running, scanning, channel_is_blacklisted, event_count);
#endif
event_count = 0;
beforeSleep();
int rs = 0;
do {
real_pause();
rs = Sleep();
#ifdef DEBUG_EIT_THREAD
xprintf("%s: wakeup, running %d scanning %d blacklisted %d reason %d\n\n",
name.c_str(), running, scanning, channel_is_blacklisted, rs);
#endif
} while (checkSleep());
if(!running)
break;
afterSleep();
if (rs == ETIMEDOUT)
{
dprintf("dmxFSEIT: waking up again - timed out\n");
// must call dmxFSEIT.change after! unpause otherwise dev is not open,
// dmxFSEIT.lastChanged will not be set, and filter is advanced the next iteration
// maybe .change should imply .real_unpause()? -- seife
dprintf("New Filterindex: %d (ges. %d)\n", 2, (signed) dmxFSEIT.filters.size() );
dmxFSEIT.change(1); // -> restart
change(0); // -> restart, FIXME
sendToSleepNow = false;
}
else if (rs == 0)
{
dprintf("dmxFSEIT: waking up again - requested from .change()\n");
int rc = getSection(static_buf, timeoutInMSeconds, timeoutsDMX);
processSection(rc);
time_t zeit = time_monotonic();
bool need_change = false;
if(timeoutsDMX < 0 || timeoutsDMX >= skipTimeouts) {
#ifdef DEBUG_EIT_THREAD
xprintf("%s: skipping to next filter %d from %d (timeouts %d)\n",
name.c_str(), filter_index+1, filters.size(), timeoutsDMX);
#endif
timeoutsDMX = 0;
need_change = true;
}
else
{
dprintf("dmxFSEIT: waking up again - unknown reason %d\n",rs);
if (zeit > lastChanged + skipTime) {
#ifdef DEBUG_EIT_THREAD
xprintf("%s: skipping to next filter %d from %d (seconds %d)\n",
name.c_str(), filter_index+1, filters.size(), (int) (zeit - lastChanged));
#endif
need_change = true;
}
// update zeit after sleep
zeit = time_monotonic();
}
else if (zeit > dmxFSEIT.lastChanged + TIME_FSEIT_SKIPPING )
{
if(running && need_change && scanning) {
readLockMessaging();
if ( dmxFSEIT.filter_index + 1 < (signed) dmxFSEIT.filters.size() )
{
dprintf("[freesatEitThread] skipping to next filter(%d) (> TIME_FSEIT_SKIPPING)\n", dmxFSEIT.filter_index+1 );
dmxFSEIT.change(dmxFSEIT.filter_index + 1);
}
else
if (!next_filter())
sendToSleepNow = true;
unlockMessaging();
}
addEvents();
//dprintf("[eitThread] added %d events (end)\n", eit.events().size());
} // for
} // while running
delete[] static_buf;
dputs("[freesatEitThread] end");
cleanup();
printf("[sectionsd] %s ended\n", name.c_str());
pthread_exit(NULL);
}
#endif
bool CSectionThread::addEvents()
/********************************************************************************/
/* abstract CEventsThread functions */
/********************************************************************************/
bool CEventsThread::addEvents()
{
SIsectionEIT eit(static_buf);
@@ -1638,21 +1590,37 @@ bool CSectionThread::addEvents()
return true;
}
//---------------------------------------------------------------------
// EIT-thread
// reads EPG-datas
//---------------------------------------------------------------------
void CEitThread::run()
/* default check if thread should go to sleep */
bool CEventsThread::shouldSleep()
{
name = "eitThread";
xprintf("%s::run:: starting, pid %d (%lu)\n", name.c_str(), getpid(), pthread_self());
return (sendToSleepNow || !scanning || channel_is_blacklisted);
}
pID = 0x12;
timeoutInMSeconds = EIT_READ_TIMEOUT;
/* default check if thread should continue to sleep */
bool CEventsThread::checkSleep()
{
return (running && (!scanning || channel_is_blacklisted));
}
bool sendToSleepNow = false;
/* default section process */
void CEventsThread::processSection(int rc)
{
if(rc <= 0)
return;
addEvents();
}
/********************************************************************************/
/* EIT thread to read other TS CN + all scheduled events */
/********************************************************************************/
CEitThread::CEitThread()
: CEventsThread("eitThread")
{
}
/* EIT thread hooks */
void CEitThread::addFilters()
{
/* These filters are a bit tricky (index numbers):
- 0 Dummy filter, to make this thread sleep for some seconds
- 1 then get other TS's current/next (this TS's cur/next are
@@ -1670,89 +1638,51 @@ void CEitThread::run()
#else
addfilter(0x60, 0xf0); //3 other TS, scheduled
#endif
}
if (sections_debug)
dump_sched_info("eitThread");
waitForTimeset();
xprintf("%s::run:: time set.\n", name.c_str());
DMX::start(); // -> unlock
while (running) {
if(sendToSleepNow || !scanning || channel_is_blacklisted) {
#ifdef DEBUG_EIT_THREAD
xprintf("%s: going to sleep %d seconds, running %d scanning %d blacklisted %d events %d\n",
name.c_str(), TIME_EIT_SCHEDULED_PAUSE, running, scanning, channel_is_blacklisted, event_count);
#endif
event_count = 0;
void CEitThread::beforeSleep()
{
xprintf("%s: CScheduledThread::beforeSleep()\n", name.c_str());
writeLockMessaging();
messaging_zap_detected = false;
unlockMessaging();
int rs = 0;
do {
real_pause();
rs = Sleep(TIME_EIT_SCHEDULED_PAUSE);
#ifdef DEBUG_EIT_THREAD
xprintf("%s: wakeup, running %d scanning %d blacklisted %d reason %d\n\n", name.c_str(), running, scanning, channel_is_blacklisted, rs);
#endif
} while(running && (!scanning || channel_is_blacklisted));
if(!running)
break;
if (rs == ETIMEDOUT)
change(1); // -> restart
sendToSleepNow = false;
}
int rc = getSection(static_buf, timeoutInMSeconds, timeoutsDMX);
if (rc > 0)
addEvents();
time_t zeit = time_monotonic();
bool need_change = false;
if(timeoutsDMX < 0 || timeoutsDMX >= CHECK_RESTART_DMX_AFTER_TIMEOUTS) {
#ifdef DEBUG_EIT_THREAD
xprintf("%s: skipping to next filter %d from %d (timeouts %d)\n", name.c_str(), filter_index+1, filters.size(), timeoutsDMX);
#endif
timeoutsDMX = 0;
need_change = true;
}
if (zeit > lastChanged + TIME_EIT_SKIPPING) {
#ifdef DEBUG_EIT_THREAD
xprintf("%s: skipping to next filter %d from %d (TIME_EIT_SKIPPING)\n", name.c_str(), filter_index+1, filters.size());
#endif
need_change = true;
}
/* FIXME without dummy filter, there is race between service change and need_change */
if(running && need_change && scanning && !channel_is_blacklisted) {
readLockMessaging();
if (!next_filter())
sendToSleepNow = true;
unlockMessaging();
}
} // while running
delete[] static_buf;
printf("[sectionsd] %s ended\n", name.c_str());
pthread_exit(NULL);
}
//---------------------------------------------------------------------
// CN-thread: eit thread, but only current/next
//---------------------------------------------------------------------
bool CCNThread::startUpdateFilter()
/********************************************************************************/
/* CN thread to read current TS CN events */
/********************************************************************************/
CCNThread::CCNThread()
: CEventsThread("cnThread")
{
sleep_time = 0;
cache = false;
skipTimeouts = 5000 / timeoutInMSeconds; // 5 seconds
skipTime = TIME_EIT_VERSION_WAIT;
updating = false;
eitDmx = new cDemux(0);
eitDmx->Open(DMX_PSI_CHANNEL);
}
/* CN thread hooks */
void CCNThread::cleanup()
{
delete eitDmx;
}
void CCNThread::addFilters()
{
addfilter(0x4e, 0xff); //0 current TS, current/next
}
void CCNThread::beforeWait()
{
xprintf("%s: set eit update filter, service = 0x%016llx, current version 0x%x got events %d (%s)\n",
name.c_str(), messaging_current_servicekey, eit_version, messaging_have_CN,
updating ? "active" : "not active");
if (updating || eit_version == 0xff)
return false;
return;
updating = true;
@@ -1775,21 +1705,51 @@ bool CCNThread::startUpdateFilter()
mask[3] = (0x1F << 1) | 0x01;
mode[3] = 0x1F << 1;
eitDmx->sectionFilter(0x12, filter, mask, 4, 0 /*timeout*/, mode);
return true;
}
bool CCNThread::stopUpdateFilter()
void CCNThread::afterWait()
{
xprintf("%s: stop eit update filter (%s)\n", name.c_str(), updating ? "active" : "not active");
if(updating) {
updating = false;
eitDmx->Stop();
return true;
}
return false;
}
void CCNThread::beforeSleep()
{
if (sendToSleepNow && messaging_have_CN == 0x00) {
/* send a "no epg" event anyway before going to sleep */
sendCNEvent();
}
}
void CCNThread::processSection(int rc)
{
if(rc <= 0)
return;
addEvents();
readLockMessaging();
if (messaging_got_CN != messaging_have_CN) {
unlockMessaging();
writeLockMessaging();
messaging_have_CN = messaging_got_CN;
unlockMessaging();
#ifdef DEBUG_CN_THREAD
xprintf("%s: have CN: timeoutsDMX %d messaging_have_CN %x messaging_got_CN %x\n\n",
name.c_str(), timeoutsDMX, messaging_have_CN, messaging_got_CN);
#endif
dprintf("[cnThread] got current_next (0x%x) - sending event!\n", messaging_have_CN);
sendCNEvent();
lastChanged = time_monotonic();
}
else
unlockMessaging();
}
/* CN private functions */
bool CCNThread::checkUpdate()
{
if(!updating)
@@ -1801,7 +1761,8 @@ bool CCNThread::checkUpdate()
if (ret > 0) {
LongSection section(buf);
printdate_ms(stdout);
xprintf("%s: eit update filter: ### new version 0x%02x ###, Activate thread\n", name.c_str(), section.getVersionNumber());
xprintf("%s: eit update filter: ### new version 0x%02x ###, Activate thread\n",
name.c_str(), section.getVersionNumber());
writeLockMessaging();
messaging_have_CN = 0x00;
@@ -1820,110 +1781,23 @@ void CCNThread::sendCNEvent()
sizeof(messaging_current_servicekey));
}
void CCNThread::run()
#ifdef ENABLE_FREESATEPG
/********************************************************************************/
/* Freesat EIT thread */
/********************************************************************************/
CFreeSatThread()
: CEventsThread("freeSatThread", 3842)
{
name = "cnThread";
xprintf("%s::run:: starting, pid %d (%lu)\n", name.c_str(), getpid(), pthread_self());
pID = 0x12;
dmx_num = 0;
cache = false;
skipTime = TIME_FSEIT_SKIPPING;
};
timeoutInMSeconds = EIT_READ_TIMEOUT;
bool sendToSleepNow = false;
updating = false;
eitDmx = new cDemux(0);
eitDmx->Open(DMX_PSI_CHANNEL);
// -- set EIT filter 0x4e
addfilter(0x4e, 0xff); //0 current TS, current/next
waitForTimeset();
#ifdef DEBUG_CN_THREAD
xprintf("CCNThread::run:: time set..\n");
#endif
DMX::start(); // -> unlock
while(running)
{
if(sendToSleepNow || !scanning || channel_is_blacklisted) {
#ifdef DEBUG_CN_THREAD
xprintf("%s: going to sleep, running %d scanning %d blacklisted %d events %d\n", name.c_str(), running, scanning, channel_is_blacklisted, event_count);
#endif
int rs = 0;
do {
real_pause();
pthread_mutex_lock( &start_stop_mutex );
if (!channel_is_blacklisted)
startUpdateFilter();
rs = pthread_cond_wait(&change_cond, &start_stop_mutex);
stopUpdateFilter();
pthread_mutex_unlock(&start_stop_mutex);
#ifdef DEBUG_CN_THREAD
xprintf("%s: wakeup, running %d scanning %d blacklisted %d reason %d\n\n", name.c_str(), running, scanning, channel_is_blacklisted, rs);
#endif
} while(running && (!scanning || channel_is_blacklisted));
if(!running)
break;
sendToSleepNow = false;
#if HAVE_IPBOX_HARDWARE
if (rs == 0)
change(0);
#endif
}
int rc = getSection(static_buf, timeoutInMSeconds, timeoutsDMX);
if (rc > 0)
addEvents();
time_t zeit = time_monotonic();
readLockMessaging();
if (messaging_got_CN != messaging_have_CN)
{
unlockMessaging();
writeLockMessaging();
messaging_have_CN = messaging_got_CN;
unlockMessaging();
#ifdef DEBUG_CN_THREAD
xprintf("%s: have CN: timeoutsDMX %d messaging_have_CN %x messaging_got_CN %x\n\n",
name.c_str(), timeoutsDMX, messaging_have_CN, messaging_got_CN);
#endif
dprintf("[cnThread] got current_next (0x%x) - sending event!\n", messaging_have_CN);
sendCNEvent();
lastChanged = zeit; /* this is ugly - needs somehting better */
}
else
unlockMessaging();
if(timeoutsDMX < 0) {
#ifdef DEBUG_CN_THREAD
xprintf("%s: timeoutsDMX %d messaging_got_CN %x messaging_have_CN %x sid %016llx\n\n",
name.c_str(), timeoutsDMX, messaging_got_CN, messaging_have_CN, messaging_current_servicekey);
#endif
timeoutsDMX = 0;
sendToSleepNow = true;
}
if (zeit > lastChanged + TIME_EIT_VERSION_WAIT) {
#ifdef DEBUG_CN_THREAD
xprintf("%s: zeit > lastChanged + TIME_EIT_VERSION_WAIT\n", name.c_str());
#endif
sendToSleepNow = true;
}
if (sendToSleepNow && messaging_have_CN == 0x00) {
/* send a "no epg" event anyway before going to sleep */
sendCNEvent();
}
} // for
delete[] static_buf;
stopUpdateFilter();
delete eitDmx;
printf("[sectionsd] %s ended\n", name.c_str());
pthread_exit(NULL);
/* Freesat hooks */
void CFreeSatThread::addFilters()
{
//other TS, scheduled, freesat epg is only broadcast using table_ids 0x60 (scheduled) and 0x61 (scheduled later)
addfilter(0x60, 0xfe);
}
#endif
#ifdef ENABLE_SDT
static bool addService(const SIservice &s, const int is_actual)
@@ -1954,16 +1828,6 @@ static bool addService(const SIservice &s, const int is_actual)
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();
@@ -2176,9 +2040,6 @@ extern cDemux * dmxUTC;
void sectionsd_main_thread(void * /*data*/)
{
pthread_t threadTOT, threadHouseKeeping;
#ifdef ENABLE_FREESATEPG
pthread_t threadFSEIT;
#endif
int rc;
printf("$Id: sectionsd.cpp,v 1.305 2009/07/30 12:41:39 seife Exp $\n");
@@ -2249,13 +2110,7 @@ printf("SIevent size: %d\n", sizeof(SIevent));
threadCN.Start();
#ifdef ENABLE_FREESATEPG
// EIT-Thread3 starten
rc = pthread_create(&threadFSEIT, 0, fseitThread, 0);
if (rc) {
fprintf(stderr, "[sectionsd] failed to create fseit-thread (rc=%d)\n", rc);
return;
}
threadFSEIT.Start();
#endif
#ifdef ENABLE_SDT
threadSDT.Start();
@@ -2301,16 +2156,7 @@ printf("SIevent size: %d\n", sizeof(SIevent));
pthread_mutex_unlock(&timeThreadSleepMutex);
printf("pausing...\n");
#if 0
dmxEIT.request_pause();
dmxCN.request_pause();
#endif
#ifdef ENABLE_FREESATEPG
dmxFSEIT.request_pause();
#endif
#ifdef ENABLE_SDT
//dmxSDT.request_pause();
#endif
pthread_cancel(threadHouseKeeping);
if(dmxUTC) dmxUTC->Stop();
@@ -2331,7 +2177,8 @@ printf("SIevent size: %d\n", sizeof(SIevent));
threadSDT.Stop();
#endif
#ifdef ENABLE_FREESATEPG
dmxFSEIT.close();
printf("join FSEIT\n");
threadFSEIT.Stop();
#endif
printf("[sectionsd] ended\n");
}