diff --git a/HISTORY b/HISTORY index 056a04ab..8c005b14 100644 --- a/HISTORY +++ b/HISTORY @@ -6747,3 +6747,4 @@ Video Disk Recorder Revision History - Fixed scaling subtitles in case the primary device's GetVideoSize() function doesn't return actual values (thanks to Luca Olivetti). +- The DiSEqC codes are now copied in the call to cDiseqc::Execute(). diff --git a/diseqc.c b/diseqc.c index d4462997..591d31d8 100644 --- a/diseqc.c +++ b/diseqc.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: diseqc.c 2.5 2011/08/06 10:32:18 kls Exp $ + * $Id: diseqc.c 2.6 2011/09/10 13:38:38 kls Exp $ */ #include "diseqc.h" @@ -23,7 +23,6 @@ cDiseqc::cDiseqc(void) lof = 0; commands = NULL; parsing = false; - numCodes = 0; } cDiseqc::~cDiseqc() @@ -60,7 +59,7 @@ bool cDiseqc::Parse(const char *s) if (polarization == 'V' || polarization == 'H' || polarization == 'L' || polarization == 'R') { parsing = true; const char *CurrentAction = NULL; - while (Execute(&CurrentAction) != daNone) + while (Execute(&CurrentAction, NULL, NULL) != daNone) ; parsing = false; result = !commands || !*CurrentAction; @@ -89,7 +88,7 @@ const char *cDiseqc::Wait(const char *s) const return NULL; } -const char *cDiseqc::Codes(const char *s) const +const char *cDiseqc::GetCodes(const char *s, uchar *Codes, uint8_t *MaxCodes) const { const char *e = strchr(s, ']'); if (e) { @@ -101,9 +100,13 @@ const char *cDiseqc::Codes(const char *s) const char *p; int n = strtol(t, &p, 16); if (!errno && p != t && 0 <= n && n <= 255) { - if (!parsing) { - codes[NumCodes++] = uchar(n); - numCodes = NumCodes; + if (Codes) { + if (NumCodes < *MaxCodes) + Codes[NumCodes++] = uchar(n); + else { + esyslog("ERROR: too many codes in code sequence '%s'", s - 1); + return NULL; + } } t = skipspace(p); } @@ -117,6 +120,8 @@ const char *cDiseqc::Codes(const char *s) const return NULL; } } + if (MaxCodes) + *MaxCodes = NumCodes; return e + 1; } else @@ -124,7 +129,7 @@ const char *cDiseqc::Codes(const char *s) const return NULL; } -cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction) const +cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction, uchar *Codes, uint8_t *MaxCodes) const { if (!*CurrentAction) *CurrentAction = commands; @@ -138,7 +143,7 @@ cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction) const case 'A': return daMiniA; case 'B': return daMiniB; case 'W': *CurrentAction = Wait(*CurrentAction); break; - case '[': *CurrentAction = Codes(*CurrentAction); return *CurrentAction ? daCodes : daNone; + case '[': *CurrentAction = GetCodes(*CurrentAction, Codes, MaxCodes); return *CurrentAction ? daCodes : daNone; default: return daNone; } } diff --git a/diseqc.h b/diseqc.h index 413ed4d9..6dbf04f8 100644 --- a/diseqc.h +++ b/diseqc.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: diseqc.h 2.2 2011/05/22 10:35:38 kls Exp $ + * $Id: diseqc.h 2.3 2011/09/10 13:36:50 kls Exp $ */ #ifndef __DISEQC_H @@ -33,15 +33,13 @@ private: int lof; char *commands; bool parsing; - mutable uchar codes[MaxDiseqcCodes]; - mutable int numCodes; const char *Wait(const char *s) const; - const char *Codes(const char *s) const; + const char *GetCodes(const char *s, uchar *Codes = NULL, uint8_t *MaxCodes = NULL) const; public: cDiseqc(void); ~cDiseqc(); bool Parse(const char *s); - eDiseqcActions Execute(const char **CurrentAction) const; + eDiseqcActions Execute(const char **CurrentAction, uchar *Codes, uint8_t *MaxCodes) const; // Parses the DiSEqC commands and returns the appropriate action code // with every call. CurrentAction must be the address of a character pointer, // which is initialized to NULL. This pointer is used internally while parsing @@ -49,13 +47,16 @@ public: // it. Call Execute() repeatedly (always providing the same CurrentAction pointer) // until it returns daNone. After a successful execution of all commands // *CurrentAction points to the value 0x00. + // If the current action consists of sending code bytes to the device, those + // bytes will be copied into Codes. MaxCodes must be initialized to the maximum + // number of bytes Codes can handle, and will be set to the actual number of + // bytes copied to Codes upon return. int Devices(void) const { return devices; } int Source(void) const { return source; } int Slof(void) const { return slof; } char Polarization(void) const { return polarization; } int Lof(void) const { return lof; } const char *Commands(void) const { return commands; } - const uchar *Codes(int &NumCodes) const { NumCodes = numCodes; return numCodes ? codes : NULL; } }; class cDiseqcs : public cConfig { diff --git a/dvbdevice.c b/dvbdevice.c index a97f2749..4aea70e5 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.c 2.43 2011/08/26 12:57:34 kls Exp $ + * $Id: dvbdevice.c 2.44 2011/09/10 13:34:02 kls Exp $ */ #include "dvbdevice.h" @@ -509,30 +509,24 @@ bool cDvbTuner::SetFrontend(void) if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) { unsigned int frequency = channel.Frequency(); if (Setup.DiSEqC) { - const cDiseqc *diseqc = Diseqcs.Get(device, channel.Source(), channel.Frequency(), dtp.Polarization()); + const cDiseqc *diseqc = Diseqcs.Get(device, channel.Source(), frequency, dtp.Polarization()); if (diseqc) { if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) { - cDiseqc::eDiseqcActions da; - for (const char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) { + struct dvb_diseqc_master_cmd cmd; + const char *CurrentAction = NULL; + for (;;) { + cmd.msg_len = sizeof(cmd.msg); + cDiseqc::eDiseqcActions da = diseqc->Execute(&CurrentAction, cmd.msg, &cmd.msg_len); + if (da == cDiseqc::daNone) + break; 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::daCodes: { - int n = 0; - const uchar *codes = diseqc->Codes(n); - if (codes) { - struct dvb_diseqc_master_cmd cmd; - cmd.msg_len = min(n, int(sizeof(cmd.msg))); - memcpy(cmd.msg, codes, cmd.msg_len); - CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); - } - } - break; + case cDiseqc::daCodes: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); break; default: esyslog("ERROR: unknown diseqc command %d", da); } }