@@ -147,6 +147,15 @@ bool cDvbTuner::Locked(int TimeoutMs)
return tunerStatus >= tsLocked;
}
+#include <sys/time.h>
+static double now() { int e = errno; timeval t; gettimeofday(&t, 0); errno = e; return t.tv_sec + t.tv_usec / 1e6; }
+static int check(int c, int r, char *a, double t) { int e = errno; fprintf(stderr, "t: %.3lf, c: %d, r: %d, a: %s\n", t, c, r, a); errno = e; return r; }
+static int check5(int status, int c, int r, char *a, double t) { int e = errno; fprintf(stderr, "t: %.3lf, c: %d, r: %d, a: %s => Status: %02x\n", t, c, r, a, status); errno = e; return r; }
+#define CHECK5(s) ::check5(Status, cardIndex, s, #s, ::now())
+#define CHECK4(s) ::check(cardIndex, 0, s, ::now())
+#define CHECK3(s) ::check(cardIndex, s, #s, ::now())
+#define CHECK2(s) CHECK(::check(cardIndex, s, #s, ::now()))
+
bool cDvbTuner::GetFrontendStatus(fe_status_t &Status, int TimeoutMs)
{
if (TimeoutMs) {
@@ -157,15 +166,16 @@ bool cDvbTuner::GetFrontendStatus(fe_sta
; // just to clear the event queue - we'll read the actual status below
}
}
- do {
- int stat = ioctl(fd_frontend, FE_READ_STATUS, &Status);
- if (stat == 0)
- return true;
- if (stat < 0) {
- if (errno == EINTR)
- continue;
+ while (1) {
+ int stat = CHECK5(ioctl(fd_frontend, FE_READ_STATUS, &Status));
+ if (stat == 0)
+ return true;
+ if (stat < 0) {
+ if (errno == EINTR)
+ continue;
+ }
+ break;
}
- } while (0);
return false;
}
@@ -195,12 +205,12 @@ bool cDvbTuner::SetFrontend(void)
for (char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) {
switch (da) {
case cDiseqc::daNone: break;
- case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
- case cDiseqc::daToneOn: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
- case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
- case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
- case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
- case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
+ case cDiseqc::daToneOff: CHECK2(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
+ case cDiseqc::daToneOn: CHECK2(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
+ case cDiseqc::daVoltage13: CHECK2(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
+ case cDiseqc::daVoltage18: CHECK2(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
+ case cDiseqc::daMiniA: CHECK2(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
+ case cDiseqc::daMiniB: CHECK2(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
case cDiseqc::daCodes: {
int n = 0;
uchar *codes = diseqc->Codes(n);
@@ -208,7 +218,7 @@ bool cDvbTuner::SetFrontend(void)
struct dvb_diseqc_master_cmd cmd;
memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg))));
cmd.msg_len = n;
- CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd));
+ CHECK2(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd));
}
}
break;
@@ -285,7 +295,7 @@ bool cDvbTuner::SetFrontend(void)
esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
return false;
}
- if (ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend) < 0) {
+ if (CHECK3(ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend)) < 0) {
esyslog("ERROR: frontend %d: %m", cardIndex);
return false;
}
@@ -306,11 +316,13 @@ void cDvbTuner::Action(void)
case tsIdle:
break;
case tsSet:
+CHECK4("----------------------------------------------");
tunerStatus = SetFrontend() ? tsTuned : tsIdle;
Timer.Set(tuneTimeout);
continue;
case tsTuned:
if (Timer.TimedOut()) {
+CHECK4("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
tunerStatus = tsSet;
diseqcCommands = NULL;
if (time(NULL) - lastTimeoutReport > 60) { // let's not get too many of these
@@ -328,6 +340,7 @@ void cDvbTuner::Action(void)
continue;
}
else if (Status & FE_HAS_LOCK) {
+if (tunerStatus != tsLocked) CHECK4("==============================================");
if (LostLock) {
isyslog("frontend %d regained lock on channel %d, tp %d", cardIndex, channel.Number(), channel.Transponder());
LostLock = false;