summaryrefslogtreecommitdiff
path: root/diseqc.c
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2002-10-06 10:25:42 +0200
committerKlaus Schmidinger <vdr@tvdr.de>2002-10-06 10:25:42 +0200
commit962596f4abc3790ac0f3f317079a3362210fff8f (patch)
treeb9428aea092f90731b389604fcc8540070dbf556 /diseqc.c
parentb7615a7ae144789da14d32019b2f86fc4bf6dcef (diff)
downloadvdr-962596f4abc3790ac0f3f317079a3362210fff8f.tar.gz
vdr-962596f4abc3790ac0f3f317079a3362210fff8f.tar.bz2
Modified channel handling; full DiSEqC support
Diffstat (limited to 'diseqc.c')
-rw-r--r--diseqc.c136
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;
+}