diff options
author | Klaus Schmidinger <vdr@tvdr.de> | 2002-10-06 10:25:42 +0200 |
---|---|---|
committer | Klaus Schmidinger <vdr@tvdr.de> | 2002-10-06 10:25:42 +0200 |
commit | 962596f4abc3790ac0f3f317079a3362210fff8f (patch) | |
tree | b9428aea092f90731b389604fcc8540070dbf556 /diseqc.c | |
parent | b7615a7ae144789da14d32019b2f86fc4bf6dcef (diff) | |
download | vdr-962596f4abc3790ac0f3f317079a3362210fff8f.tar.gz vdr-962596f4abc3790ac0f3f317079a3362210fff8f.tar.bz2 |
Modified channel handling; full DiSEqC support
Diffstat (limited to 'diseqc.c')
-rw-r--r-- | diseqc.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/diseqc.c b/diseqc.c new file mode 100644 index 00000000..92b92cbb --- /dev/null +++ b/diseqc.c @@ -0,0 +1,136 @@ +/* + * diseqc.c: DiSEqC handling + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: diseqc.c 1.1 2002/10/05 13:54:32 kls Exp $ + */ + +#include "diseqc.h" +#include <ctype.h> +#include "sources.h" + +// -- cDiseqc ---------------------------------------------------------------- + +cDiseqc::cDiseqc(void) +{ + commands = NULL; + currentAction = NULL;; + parsing = false; + numCodes = 0; +} + +cDiseqc::~cDiseqc() +{ + free(commands); +} + +bool cDiseqc::Parse(const char *s) +{ + bool result = false; + char *sourcebuf = NULL; + int fields = sscanf(s, "%a[^ ] %d %c %d %a[^\n]", &sourcebuf, &slof, &polarization, &lof, &commands); + if (fields == 4) + commands = NULL; //XXX Apparently sscanf() doesn't work correctly if the last %a argument results in an empty string + if (4 <= fields && fields <= 5) { + source = cSource::FromString(sourcebuf); + if (Sources.Get(source)) { + polarization = toupper(polarization); + if (polarization == 'V' || polarization == 'H') { + parsing = true; + bool Start = true; + while (Execute(Start) != daNone) + Start = false; + parsing = false; + result = !commands || currentAction && !*currentAction; + } + else + esyslog("ERROR: unknown polarization '%c'", polarization); + } + else + esyslog("ERROR: unknown source '%s'", sourcebuf); + } + free(sourcebuf); + return result; +} + +char *cDiseqc::Wait(char *s) +{ + char *p = NULL; + errno = 0; + int n = strtol(s, &p, 10); + if (!errno && p != s && n >= 0) { + if (!parsing) + usleep(n * 1000); + return p; + } + esyslog("ERROR: illegal value for wait time in '%s'", s - 1); + return NULL; +} + +char *cDiseqc::Codes(char *s) +{ + char *e = strchr(s, ']'); + if (e) { + numCodes = 0; + char *t = s; + char *p = s; + while (t < e) { + if (numCodes < MaxDiseqcCodes) { + errno = 0; + int n = strtol(t, &p, 16); + if (!errno && p != t && 0 <= n && n <= 255) { + codes[numCodes++] = n; + t = skipspace(p); + } + else { + esyslog("ERROR: illegal code at '%s'", t); + return NULL; + } + } + else { + esyslog("ERROR: too many codes in code sequence '%s'", s - 1); + return NULL; + } + } + return e + 1; + } + else + esyslog("ERROR: missing closing ']' in code sequence '%s'", s - 1); + return NULL; +} + +cDiseqc::eDiseqcActions cDiseqc::Execute(bool Start) +{ + if (Start) + currentAction = commands; + while (currentAction && *currentAction) { + switch (*currentAction++) { + case ' ': break; + case 't': return daToneOff; + case 'T': return daToneOn; + case 'v': return daVoltage13; + case 'V': return daVoltage18; + case 'A': return daMiniA; + case 'B': return daMiniB; + case 'W': currentAction = Wait(currentAction); break; + case '[': currentAction = Codes(currentAction); return currentAction ? daCodes : daNone; + default: return daNone; + } + } + return daNone; +} + +// -- cDiseqcs --------------------------------------------------------------- + +cDiseqcs Diseqcs; + +cDiseqc *cDiseqcs::Get(int Source, int Frequency, char Polarization) +{ + for (cDiseqc *p = First(); p; p = Next(p)) { + if (p->Source() == Source && p->Slof() > Frequency && p->Polarization() == toupper(Polarization)) + return p; + } + return NULL; +} |