12 #include <linux/dvb/frontend.h> 13 #include <sys/ioctl.h> 17 #define ALL_DEVICES (~0) // all bits set to '1' 18 #define MAX_DEVICES 32 // each bit in a 32-bit integer represents one device 24 return *s && s[strlen(s) - 1] ==
':';
32 while (*p && *p !=
':') {
34 int d = strtol(p, &t, 10);
39 esyslog(
"ERROR: invalid device number %d in '%s'", d, s);
68 struct dvb_diseqc_master_cmd cmd;
69 NumCodes =
min(NumCodes,
int(
sizeof(cmd.msg) - 2));
71 cmd.msg[cmd.msg_len++] = 0xE0;
72 cmd.msg[cmd.msg_len++] = 0x31;
73 for (
int i = 0; i < NumCodes; i++)
74 cmd.msg[cmd.msg_len++] = Codes[i];
80 uint8_t Code[] = { uint8_t(Direction ==
pdLeft ? 0x68 : 0x69), 0x00 };
88 uint8_t Code[] = { uint8_t(Direction ==
pdLeft ? 0x68 : 0x69), 0xFF };
89 Code[1] -=
min(Steps, uint(0x7F)) - 1;
95 uint8_t Code[] = { 0x60 };
101 uint8_t Code[] = { uint8_t(Direction ==
pdLeft ? 0x66 : 0x67) };
107 uint8_t Code[] = { 0x63 };
113 uint8_t Code[] = { 0x6A, 0x00 };
119 uint8_t Code[] = { 0x6A, uint8_t(Number) };
125 uint8_t Code[] = { 0x6F, uint8_t(Number), 0x00, 0x00 };
131 uint8_t Code[] = { 0x6B, uint8_t(Number) };
138 uint8_t Code[] = { 0x6E, 0x00, 0x00 };
141 Code[1] = a / 10 / 16;
142 Code[2] = a / 10 % 16 * 16 + a % 10 * 16 / 10;
143 Code[1] |= (Angle < 0) ? 0xE0 : 0xD0;
165 int fields = sscanf(s,
"%d %u %d", &channel, &userBand, &pin);
166 if (fields == 2 || fields == 3) {
167 if (channel >= 0 && channel < 32) {
169 if (fields == 3 && (pin < 0 || pin > 255)) {
170 esyslog(
"Error: invalid SCR pin '%d'", pin);
175 esyslog(
"Error: invalid SCR channel '%d'", channel);
184 bool cScrs::Load(
const char *FileName,
bool AllowComments,
bool MustExist)
193 for (
cScr *p = First(); p; p = Next(p)) {
194 if (!
IsBitSet(p->Devices(), Device - 1))
230 char *sourcebuf = NULL;
231 int fields = sscanf(s,
"%m[^ ] %d %c %d %m[^\n]", &sourcebuf, &slof, &polarization, &lof, &commands);
234 if (4 <= fields && fields <= 5) {
237 polarization = char(toupper(polarization));
238 if (polarization ==
'V' || polarization ==
'H' || polarization ==
'L' || polarization ==
'R') {
240 const char *CurrentAction = NULL;
241 while (Execute(&CurrentAction, NULL, NULL, NULL, NULL) != daNone)
244 result = !commands || !*CurrentAction;
247 esyslog(
"ERROR: unknown polarization '%c'", polarization);
250 esyslog(
"ERROR: unknown source '%s'", sourcebuf);
258 if ((Codes[0] & 0xF0) == 0x70 ) {
259 uint t = SatFrequency == 0 ? 0 : (SatFrequency - 100);
260 if (t < 2048 && Scr->Channel() >= 0 && Scr->
Channel() < 32) {
261 Codes[1] = t >> 8 | Scr->
Channel() << 3;
263 Codes[3] = (t == 0 ? 0 : scrBank);
269 uint t = SatFrequency == 0 ? 0 : (SatFrequency + Scr->
UserBand() + 2) / 4 - 350;
270 if (t < 1024 && Scr->Channel() >= 0 && Scr->
Channel() < 8) {
271 Codes[3] = t >> 8 | (t == 0 ? 0 : scrBank << 2) | Scr->
Channel() << 5;
274 return (t + 350) * 4 - SatFrequency;
277 esyslog(
"ERROR: invalid SCR channel number %d or frequency %d", Scr->
Channel(),SatFrequency);
283 if ((Codes[0] & 0xF0) == 0x70 ) {
284 if (Scr->
Pin() >= 0 && Scr->
Pin() <= 255) {
286 Codes[4] = Scr->
Pin();
295 if (Scr->
Pin() >= 0 && Scr->
Pin() <= 255) {
297 Codes[5] = Scr->
Pin();
311 int n = strtol(s, &p, 10);
312 if (!errno && p != s && n >= 0) {
317 esyslog(
"ERROR: invalid value for wait time in '%s'", s - 1);
323 if (!*s || !isdigit(*s)) {
329 int n = strtol(s, &p, 10);
330 if (!errno && p != s && n >= 0 && n < 0xFF) {
335 esyslog(
"ERROR: more than one position in '%s'", s - 1);
339 esyslog(
"ERROR: invalid satellite position in '%s'", s - 1);
347 int n = strtol(s, &p, 10);
348 if (!errno && p != s && n >= 0 && n < 256) {
353 esyslog(
"ERROR: more than one scr bank in '%s'", s - 1);
357 esyslog(
"ERROR: invalid value for scr bank in '%s'", s - 1);
363 const char *e = strchr(s,
']');
368 if (NumCodes < MaxDiseqcCodes) {
371 int n = strtol(t, &p, 16);
372 if (!errno && p != t && 0 <= n && n <= 255) {
374 if (NumCodes < *MaxCodes)
375 Codes[NumCodes++] =
uchar(n);
377 esyslog(
"ERROR: too many codes in code sequence '%s'", s - 1);
384 esyslog(
"ERROR: invalid code at '%s'", t);
389 esyslog(
"ERROR: too many codes in code sequence '%s'", s - 1);
394 *MaxCodes = NumCodes;
398 esyslog(
"ERROR: missing closing ']' in code sequence '%s'", s - 1);
405 *CurrentAction = commands;
406 while (*CurrentAction && **CurrentAction) {
407 switch (*(*CurrentAction)++) {
409 case 't':
return daToneOff;
410 case 'T':
return daToneOn;
411 case 'v':
return daVoltage13;
412 case 'V':
return daVoltage18;
413 case 'A':
return daMiniA;
414 case 'B':
return daMiniB;
415 case 'W': *CurrentAction = Wait(*CurrentAction);
return daWait;
416 case 'P': *CurrentAction = GetPosition(*CurrentAction);
418 return position ? daPositionN : daPositionA;
420 case 'S': *CurrentAction = GetScrBank(*CurrentAction);
return daScr;
421 case '[': *CurrentAction = GetCodes(*CurrentAction, Codes, MaxCodes);
422 if (*CurrentAction) {
423 if (Scr && Frequency) {
424 *Frequency = SetScrFrequency(*Frequency, Scr, Codes);
425 *MaxCodes = SetScrPin(Scr, Codes);
430 default:
esyslog(
"ERROR: unknown diseqc code '%c'", *(*CurrentAction - 1));
449 for (
const cDiseqc *p = First(); p; p = Next(p)) {
450 if (!
IsBitSet(p->Devices(), Device - 1))
452 if (
cSource::Matches(p->Source(), Source) && p->Slof() > Frequency && p->Polarization() == toupper(Polarization)) {
453 if (p->IsScr() && Scr && !*Scr) {
456 dsyslog(
"SCR %d assigned to device %d", (*Scr)->Channel(), Device);
458 esyslog(
"ERROR: no free SCR entry available for device %d", Device);
virtual void DisableLimits(void)
Disables the soft limits for the dish movement.
static int CalcHourAngle(int Longitude)
Takes the longitude and latitude of the dish location from the system setup and the given Longitude t...
const char * Wait(const char *s) const
uint UserBand(void) const
bool Parse(const char *s)
virtual void GotoPosition(uint Number, int Longitude)
Move the dish to the satellite position stored under the given Number.
virtual void EnableLimits(void)
Enables the soft limits for the dish movement.
eDiseqcActions Execute(const char **CurrentAction, uchar *Codes, uint8_t *MaxCodes, const cScr *Scr, uint *Frequency) const
Parses the DiSEqC commands and returns the appropriate action code with every call.
bool Load(const char *FileName=NULL, bool AllowComments=false, bool MustExist=false)
virtual void StorePosition(uint Number)
Store the current position as a satellite position with the given Number.
virtual void Drive(ePositionerDirection Direction)
Continuously move the dish to the given Direction until Halt() is called or it hits the soft or hard ...
virtual void Halt(void)
Stop any ongoing motion of the dish.
virtual void GotoAngle(int Longitude)
Move the dish to the given angular position.
virtual void SetLimit(ePositionerDirection Direction)
Set the soft limit of the dish movement in the given Direction to the current position.
virtual void GotoPosition(uint Number, int Longitude)
Move the dish to the satellite position stored under the given Number.
uint SetScrFrequency(uint SatFrequency, const cScr *Scr, uint8_t *Codes) const
static bool ParseDeviceNumbers(const char *s)
virtual void GotoAngle(int Longitude)
Move the dish to the given angular position.
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
const char * GetScrBank(const char *s) const
bool Load(const char *FileName, bool AllowComments=false, bool MustExist=false)
int Frontend(void) const
Returns the file descriptor of the DVB frontend the positioner is connected to.
void SetCapabilities(int Capabilities)
A derived class shall call this function in its constructor to set the capability flags it supports...
virtual void Step(ePositionerDirection Direction, uint Steps=1)
Move the dish the given number of Steps in the given Direction.
const char * GetCodes(const char *s, uchar *Codes=NULL, uint8_t *MaxCodes=NULL) const
cScr * GetUnused(int Device)
static int FromString(const char *s)
const cDiseqc * Get(int Device, int Source, int Frequency, char Polarization, const cScr **Scr) const
Selects a DiSEqC entry suitable for the given Device and tuning parameters.
static bool Matches(int Code1, int Code2)
Returns true if Code2 matches Code1.
int SetScrPin(const cScr *Scr, uint8_t *Codes) const
const char * GetPosition(const char *s) const
bool Load(const char *FileName, bool AllowComments=false, bool MustExist=false)
static int CurrentDevices
static bool IsDeviceNumbers(const char *s)
void SendDiseqc(uint8_t *Codes, int NumCodes)
bool Parse(const char *s)
virtual void RecalcPositions(uint Number)
Take the difference between the current actual position of the dish and the position stored with the ...