12#include <linux/dvb/frontend.h>
17#define ALL_DEVICES (~0)
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;
166 if (fields == 2 || fields == 3) {
184bool cScrs::Load(
const char *FileName,
bool AllowComments,
bool MustExist)
194 if (!
IsBitSet(p->Devices(), Device - 1))
230 char *sourcebuf = NULL;
234 if (4 <= fields && fields <= 5) {
240 const char *CurrentAction = NULL;
241 while (
Execute(&CurrentAction, NULL, NULL, NULL, NULL) !=
daNone)
244 result = !
commands || !*CurrentAction;
250 esyslog(
"ERROR: unknown source '%s'", sourcebuf);
258 if ((Codes[0] & 0xF0) == 0x70 ) {
259 int 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 int 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,
']');
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);
406 while (*CurrentAction && **CurrentAction) {
407 switch (*(*CurrentAction)++) {
415 case 'W': *CurrentAction =
Wait(*CurrentAction);
return daWait;
416 case 'P': *CurrentAction =
GetPosition(*CurrentAction);
421 case '[': *CurrentAction =
GetCodes(*CurrentAction, Codes, MaxCodes);
422 if (*CurrentAction) {
423 if (Scr && Frequency) {
430 default:
esyslog(
"ERROR: unknown diseqc code '%c'", *(*CurrentAction - 1));
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);
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
const char * FileName(void)
bool Load(const char *FileName=NULL, bool AllowComments=false, bool MustExist=false)
virtual void DisableLimits(void)
Disables the soft limits for the dish movement.
void SendDiseqc(uint8_t *Codes, int NumCodes)
virtual void GotoPosition(uint Number, int Longitude)
Move the dish to the satellite position stored under the given Number.
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 Step(ePositionerDirection Direction, uint Steps=1)
Move the dish the given number of Steps in the given Direction.
virtual void Halt(void)
Stop any ongoing motion of the dish.
virtual void RecalcPositions(uint Number)
Take the difference between the current actual position of the dish and the position stored with the ...
virtual void EnableLimits(void)
Enables the soft limits for the dish movement.
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 ...
eDiseqcActions Execute(const char **CurrentAction, uchar *Codes, uint8_t *MaxCodes, const cScr *Scr, int *Frequency) const
Parses the DiSEqC commands and returns the appropriate action code with every call.
bool Parse(const char *s)
const char * GetPosition(const char *s) const
const char * Wait(const char *s) const
int SetScrFrequency(int SatFrequency, const cScr *Scr, uint8_t *Codes) const
const char * GetCodes(const char *s, uchar *Codes=NULL, uint8_t *MaxCodes=NULL) const
int SetScrPin(const cScr *Scr, uint8_t *Codes) const
const char * GetScrBank(const char *s) const
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.
bool Load(const char *FileName, bool AllowComments=false, bool MustExist=false)
const cScr * First(void) const
const cScr * Next(const cScr *Object) const
int Frontend(void) const
Returns the file descriptor of the DVB frontend the positioner is connected to.
static int CalcHourAngle(int Longitude)
Takes the longitude and latitude of the dish location from the system setup and the given Longitude t...
void SetCapabilities(int Capabilities)
A derived class shall call this function in its constructor to set the capability flags it supports.
virtual void GotoPosition(uint Number, int Longitude)
Move the dish to the satellite position stored under the given Number.
virtual void GotoAngle(int Longitude)
Move the dish to the given angular position.
uint UserBand(void) const
bool Parse(const char *s)
bool Load(const char *FileName, bool AllowComments=false, bool MustExist=false)
cScr * GetUnused(int Device)
static int FromString(const char *s)
static bool Matches(int Code1, int Code2)
Returns true if Code2 matches Code1.
static bool IsDeviceNumbers(const char *s)
static bool ParseDeviceNumbers(const char *s)
static int CurrentDevices