mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
VDR now supports "Satellite Channel Routing" (SCR)
This commit is contained in:
parent
78e89efee8
commit
413a0e6373
@ -2661,6 +2661,7 @@ Stephan Austerm
|
||||
|
||||
Lars Hanisch <dvb@flensrocker.de>
|
||||
for suggesting to assign the source character 'V' to "Analog Video"
|
||||
for a patch that was used to implement SCR (Satellite Channel Routing)
|
||||
|
||||
Alex Lasnier <alex@fepg.org>
|
||||
for adding tuning support for ATSC devices
|
||||
|
9
HISTORY
9
HISTORY
@ -6743,8 +6743,15 @@ Video Disk Recorder Revision History
|
||||
extends over TS packet boundaries is now done by locally skipping TS packets
|
||||
in cFrameDetector.
|
||||
|
||||
2011-09-10: Version 1.7.22
|
||||
2011-09-11: Version 1.7.22
|
||||
|
||||
- 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().
|
||||
- VDR now supports "Satellite Channel Routing" (SCR) (based on the "unicable" patch
|
||||
from Lars Hanisch). Since "Unicable" is a registered trademark and stands for only
|
||||
one of many implementations of SCR, the following changes have been made compared
|
||||
to the patch, which need to be taken into account by people who have set up their
|
||||
system using the patch:
|
||||
- The 'U' parameter in the diseqc.conf file has been changed to 'S' ("Scr").
|
||||
- The configuration file name has been changed from "unicable.conf" to "scr.conf".
|
||||
|
6
INSTALL
6
INSTALL
@ -386,6 +386,12 @@ accessed using DiSEqC, you have to go to the "Setup" menu and set the "DiSEqC"
|
||||
parameter to "on". You also need to set up the file 'diseqc.conf' to properly
|
||||
access your DiSEqC equipment (see man vdr(5) for details).
|
||||
|
||||
A special form of DiSEqC is used to connect several receivers to one signal
|
||||
source using only a single cable. This method, known as "Satellite Channel Routing"
|
||||
according to EN50494 (aka "Unicable(TM)", "OLT(TM)", "SatCR", "Single Cable
|
||||
Distribution", "Channel Stacking System" or "Single Cable Interface") uses
|
||||
the file "scr.conf" to specify which SCR channels use which user band frequency.
|
||||
|
||||
Running VDR with DVB-C (cable) or DVB-T (terrestrial):
|
||||
------------------------------------------------------
|
||||
|
||||
|
118
diseqc.c
118
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.6 2011/09/10 13:38:38 kls Exp $
|
||||
* $Id: diseqc.c 2.7 2011/09/11 13:39:48 kls Exp $
|
||||
*/
|
||||
|
||||
#include "diseqc.h"
|
||||
@ -12,6 +12,51 @@
|
||||
#include "sources.h"
|
||||
#include "thread.h"
|
||||
|
||||
// --- cScr ------------------------------------------------------------------
|
||||
|
||||
cScr::cScr(void)
|
||||
{
|
||||
channel = -1;
|
||||
userBand = 0;
|
||||
pin = -1;
|
||||
used = false;
|
||||
}
|
||||
|
||||
bool cScr::Parse(const char *s)
|
||||
{
|
||||
bool result = false;
|
||||
int fields = sscanf(s, "%d %u %d", &channel, &userBand, &pin);
|
||||
if (fields == 2 || fields == 3) {
|
||||
if (channel >= 0 && channel < 8) {
|
||||
result = true;
|
||||
if (fields == 3 && (pin < 0 || pin > 255)) {
|
||||
esyslog("Error: invalid SCR pin '%d'", pin);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
esyslog("Error: invalid SCR channel '%d'", channel);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// --- cScrs -----------------------------------------------------------------
|
||||
|
||||
cScrs Scrs;
|
||||
|
||||
cScr *cScrs::GetUnused(void)
|
||||
{
|
||||
cMutexLock MutexLock(&mutex);
|
||||
for (cScr *p = First(); p; p = Next(p)) {
|
||||
if (!p->Used()) {
|
||||
p->SetUsed(true);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// --- cDiseqc ---------------------------------------------------------------
|
||||
|
||||
cDiseqc::cDiseqc(void)
|
||||
@ -21,6 +66,7 @@ cDiseqc::cDiseqc(void)
|
||||
slof = 0;
|
||||
polarization = 0;
|
||||
lof = 0;
|
||||
scrBank = -1;
|
||||
commands = NULL;
|
||||
parsing = false;
|
||||
}
|
||||
@ -59,7 +105,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, NULL, NULL) != daNone)
|
||||
while (Execute(&CurrentAction, NULL, NULL, NULL, NULL) != daNone)
|
||||
;
|
||||
parsing = false;
|
||||
result = !commands || !*CurrentAction;
|
||||
@ -74,6 +120,31 @@ bool cDiseqc::Parse(const char *s)
|
||||
return result;
|
||||
}
|
||||
|
||||
uint cDiseqc::SetScrFrequency(uint SatFrequency, const cScr *Scr, uint8_t *Codes) const
|
||||
{
|
||||
uint t = SatFrequency == 0 ? 0 : (SatFrequency + Scr->UserBand() + 2) / 4 - 350;
|
||||
if (t < 1024 && Scr->Channel() >= 0 && Scr->Channel() < 8) {
|
||||
Codes[3] = t >> 8 | (t == 0 ? 0 : scrBank << 2) | Scr->Channel() << 5;
|
||||
Codes[4] = t;
|
||||
if (t)
|
||||
return (t + 350) * 4 - SatFrequency;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cDiseqc::SetScrPin(const cScr *Scr, uint8_t *Codes) const
|
||||
{
|
||||
if (Scr->Pin() >= 0 && Scr->Pin() <= 255) {
|
||||
Codes[2] = 0x5C;
|
||||
Codes[5] = Scr->Pin();
|
||||
return 6;
|
||||
}
|
||||
else {
|
||||
Codes[2] = 0x5A;
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
const char *cDiseqc::Wait(const char *s) const
|
||||
{
|
||||
char *p = NULL;
|
||||
@ -88,6 +159,24 @@ const char *cDiseqc::Wait(const char *s) const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *cDiseqc::GetScrBank(const char *s) const
|
||||
{
|
||||
char *p = NULL;
|
||||
errno = 0;
|
||||
int n = strtol(s, &p, 10);
|
||||
if (!errno && p != s && n >= 0 && n < 8) {
|
||||
if (parsing) {
|
||||
if (scrBank < 0)
|
||||
scrBank = n;
|
||||
else
|
||||
esyslog("ERROR: more than one scr bank in '%s'", s - 1);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
esyslog("ERROR: more than one scr bank in '%s'", s - 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *cDiseqc::GetCodes(const char *s, uchar *Codes, uint8_t *MaxCodes) const
|
||||
{
|
||||
const char *e = strchr(s, ']');
|
||||
@ -129,7 +218,7 @@ const char *cDiseqc::GetCodes(const char *s, uchar *Codes, uint8_t *MaxCodes) co
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction, uchar *Codes, uint8_t *MaxCodes) const
|
||||
cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction, uchar *Codes, uint8_t *MaxCodes, const cScr *Scr, uint *Frequency) const
|
||||
{
|
||||
if (!*CurrentAction)
|
||||
*CurrentAction = commands;
|
||||
@ -143,7 +232,16 @@ cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction, uchar *Code
|
||||
case 'A': return daMiniA;
|
||||
case 'B': return daMiniB;
|
||||
case 'W': *CurrentAction = Wait(*CurrentAction); break;
|
||||
case '[': *CurrentAction = GetCodes(*CurrentAction, Codes, MaxCodes); return *CurrentAction ? daCodes : daNone;
|
||||
case 'S': *CurrentAction = GetScrBank(*CurrentAction); break;
|
||||
case '[': *CurrentAction = GetCodes(*CurrentAction, Codes, MaxCodes);
|
||||
if (*CurrentAction) {
|
||||
if (Scr && Frequency) {
|
||||
*Frequency = SetScrFrequency(*Frequency, Scr, Codes);
|
||||
*MaxCodes = SetScrPin(Scr, Codes);
|
||||
}
|
||||
return daCodes;
|
||||
}
|
||||
break;
|
||||
default: return daNone;
|
||||
}
|
||||
}
|
||||
@ -154,7 +252,7 @@ cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction, uchar *Code
|
||||
|
||||
cDiseqcs Diseqcs;
|
||||
|
||||
const cDiseqc *cDiseqcs::Get(int Device, int Source, int Frequency, char Polarization) const
|
||||
const cDiseqc *cDiseqcs::Get(int Device, int Source, int Frequency, char Polarization, const cScr **Scr) const
|
||||
{
|
||||
int Devices = 0;
|
||||
for (const cDiseqc *p = First(); p; p = Next(p)) {
|
||||
@ -164,8 +262,16 @@ const cDiseqc *cDiseqcs::Get(int Device, int Source, int Frequency, char Polariz
|
||||
}
|
||||
if (Devices && !(Devices & (1 << Device - 1)))
|
||||
continue;
|
||||
if (p->Source() == Source && p->Slof() > Frequency && p->Polarization() == toupper(Polarization))
|
||||
if (p->Source() == Source && p->Slof() > Frequency && p->Polarization() == toupper(Polarization)) {
|
||||
if (p->IsScr() && Scr && !*Scr) {
|
||||
*Scr = Scrs.GetUnused();
|
||||
if (*Scr)
|
||||
dsyslog("SCR %d assigned to device %d", (*Scr)->Index(), Device);
|
||||
else
|
||||
esyslog("ERROR: no free SCR entry available for device %d", Device);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
13
diseqc.conf
13
diseqc.conf
@ -18,6 +18,7 @@
|
||||
# V voltage high (18V)
|
||||
# A mini A
|
||||
# B mini B
|
||||
# Sn Satellite channel routing code sequence for bank n follows
|
||||
# Wnn wait nn milliseconds (nn may be any positive integer number)
|
||||
# [xx ...] hex code sequence (max. 6)
|
||||
#
|
||||
@ -75,3 +76,15 @@ S13.0E 99999 H 10600 t V W15 [E0 10 38 F7] W15 B W15 T
|
||||
# S19.2E 99999 H 10560 t v
|
||||
# S19.2E 12110 V 11080 t v
|
||||
# S19.2E 99999 V 10720 t v
|
||||
#
|
||||
# SCR (Satellite Channel Routing):
|
||||
#
|
||||
# S19.2E 11700 V 9750 t V W10 S0 [E0 10 5A 00 00] W10 v
|
||||
# S19.2E 99999 V 10600 t V W10 S1 [E0 10 5A 00 00] W10 v
|
||||
# S19.2E 11700 H 9750 t V W10 S2 [E0 10 5A 00 00] W10 v
|
||||
# S19.2E 99999 H 10600 t V W10 S3 [E0 10 5A 00 00] W10 v
|
||||
#
|
||||
# S13.0E 11700 V 9750 t V W10 S4 [E0 10 5A 00 00] W10 v
|
||||
# S13.0E 99999 V 10600 t V W10 S5 [E0 10 5A 00 00] W10 v
|
||||
# S13.0E 11700 H 9750 t V W10 S6 [E0 10 5A 00 00] W10 v
|
||||
# S13.0E 99999 H 10600 t V W10 S7 [E0 10 5A 00 00] W10 v
|
||||
|
71
diseqc.h
71
diseqc.h
@ -4,13 +4,39 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: diseqc.h 2.3 2011/09/10 13:36:50 kls Exp $
|
||||
* $Id: diseqc.h 2.4 2011/09/11 13:40:16 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __DISEQC_H
|
||||
#define __DISEQC_H
|
||||
|
||||
#include "config.h"
|
||||
#include "thread.h"
|
||||
|
||||
class cScr : public cListObject {
|
||||
private:
|
||||
int channel;
|
||||
uint userBand;
|
||||
int pin;
|
||||
bool used;
|
||||
public:
|
||||
cScr(void);
|
||||
bool Parse(const char *s);
|
||||
int Channel(void) const { return channel; }
|
||||
uint UserBand(void) const { return userBand; }
|
||||
int Pin(void) const { return pin; }
|
||||
bool Used(void) const { return used; }
|
||||
void SetUsed(bool Used) { used = Used; }
|
||||
};
|
||||
|
||||
class cScrs : public cConfig<cScr> {
|
||||
private:
|
||||
cMutex mutex;
|
||||
public:
|
||||
cScr *GetUnused(void);
|
||||
};
|
||||
|
||||
extern cScrs Scrs;
|
||||
|
||||
class cDiseqc : public cListObject {
|
||||
public:
|
||||
@ -22,6 +48,7 @@ public:
|
||||
daVoltage18,
|
||||
daMiniA,
|
||||
daMiniB,
|
||||
daScr,
|
||||
daCodes,
|
||||
};
|
||||
enum { MaxDiseqcCodes = 6 };
|
||||
@ -31,37 +58,53 @@ private:
|
||||
int slof;
|
||||
char polarization;
|
||||
int lof;
|
||||
mutable int scrBank;
|
||||
char *commands;
|
||||
bool parsing;
|
||||
uint SetScrFrequency(uint SatFrequency, const cScr *Scr, uint8_t *Codes) const;
|
||||
int SetScrPin(const cScr *Scr, uint8_t *Codes) const;
|
||||
const char *Wait(const char *s) const;
|
||||
const char *GetScrBank(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, 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
|
||||
// the commands and shall not be modified once Execute() has been called with
|
||||
// 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.
|
||||
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. CurrentAction must be the address of a character pointer,
|
||||
///< which is initialized to NULL. This pointer is used internally while parsing
|
||||
///< the commands and shall not be modified once Execute() has been called with
|
||||
///< 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.
|
||||
///< If this DiSEqC entry requires SCR, the given Scr will be used. This must
|
||||
///< be a pointer returned from a previous call to cDiseqcs::Get().
|
||||
///< Frequency must be the frequency the tuner will be tuned to, and will be
|
||||
///< set to the proper SCR frequency upon return (if SCR is used).
|
||||
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; }
|
||||
bool IsScr() const { return scrBank >= 0; }
|
||||
const char *Commands(void) const { return commands; }
|
||||
};
|
||||
|
||||
class cDiseqcs : public cConfig<cDiseqc> {
|
||||
public:
|
||||
const cDiseqc *Get(int Device, int Source, int Frequency, char Polarization) 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.
|
||||
///< If this DiSEqC entry requires SCR and the given *Scr is NULL
|
||||
///< a free one will be selected from the Scrs and a pointer to that will
|
||||
///< be returned in Scr. The caller shall memorize that pointer and reuse it in
|
||||
///< subsequent calls.
|
||||
///< Scr may be NULL for checking whether there is any DiSEqC entry for the
|
||||
///< given transponder.
|
||||
};
|
||||
|
||||
extern cDiseqcs Diseqcs;
|
||||
|
73
dvbdevice.c
73
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.44 2011/09/10 13:34:02 kls Exp $
|
||||
* $Id: dvbdevice.c 2.45 2011/09/11 13:50:20 kls Exp $
|
||||
*/
|
||||
|
||||
#include "dvbdevice.h"
|
||||
@ -267,13 +267,15 @@ private:
|
||||
time_t lastTimeoutReport;
|
||||
fe_delivery_system frontendType;
|
||||
cChannel channel;
|
||||
const char *diseqcCommands;
|
||||
const cDiseqc *lastDiseqc;
|
||||
const cScr *scr;
|
||||
eTunerStatus tunerStatus;
|
||||
cMutex mutex;
|
||||
cCondVar locked;
|
||||
cCondVar newSet;
|
||||
void ClearEventQueue(void) const;
|
||||
bool GetFrontendStatus(fe_status_t &Status) const;
|
||||
void ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency) const;
|
||||
bool SetFrontend(void);
|
||||
virtual void Action(void);
|
||||
public:
|
||||
@ -299,7 +301,8 @@ cDvbTuner::cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_
|
||||
tuneTimeout = 0;
|
||||
lockTimeout = 0;
|
||||
lastTimeoutReport = 0;
|
||||
diseqcCommands = NULL;
|
||||
lastDiseqc = NULL;
|
||||
scr = NULL;
|
||||
tunerStatus = tsIdle;
|
||||
if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2)
|
||||
CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); // must explicitly turn on LNB power
|
||||
@ -313,6 +316,10 @@ cDvbTuner::~cDvbTuner()
|
||||
newSet.Broadcast();
|
||||
locked.Broadcast();
|
||||
Cancel(3);
|
||||
if (lastDiseqc && lastDiseqc->IsScr()) {
|
||||
unsigned int Frequency = 0;
|
||||
ExecuteDiseqc(lastDiseqc, &Frequency);
|
||||
}
|
||||
}
|
||||
|
||||
bool cDvbTuner::IsTunedTo(const cChannel *Channel) const
|
||||
@ -482,6 +489,30 @@ static unsigned int FrequencyToHz(unsigned int f)
|
||||
return f;
|
||||
}
|
||||
|
||||
void cDvbTuner::ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency) const
|
||||
{
|
||||
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, scr, Frequency);
|
||||
if (da == cDiseqc::daNone)
|
||||
break;
|
||||
switch (da) {
|
||||
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: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); break;
|
||||
default: esyslog("ERROR: unknown diseqc command %d", da);
|
||||
}
|
||||
}
|
||||
if (scr)
|
||||
CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); // makes sure we don't block the bus!
|
||||
}
|
||||
|
||||
bool cDvbTuner::SetFrontend(void)
|
||||
{
|
||||
#define MAXFRONTENDCMDS 16
|
||||
@ -509,30 +540,14 @@ 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(), frequency, dtp.Polarization());
|
||||
if (diseqc) {
|
||||
if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) {
|
||||
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::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: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); break;
|
||||
default: esyslog("ERROR: unknown diseqc command %d", da);
|
||||
}
|
||||
}
|
||||
diseqcCommands = diseqc->Commands();
|
||||
}
|
||||
if (const cDiseqc *diseqc = Diseqcs.Get(device, channel.Source(), frequency, dtp.Polarization(), &scr)) {
|
||||
frequency -= diseqc->Lof();
|
||||
if (diseqc != lastDiseqc || diseqc->IsScr()) {
|
||||
ExecuteDiseqc(diseqc, &frequency);
|
||||
if (frequency == 0)
|
||||
return false;
|
||||
lastDiseqc = diseqc;
|
||||
}
|
||||
}
|
||||
else {
|
||||
esyslog("ERROR: no DiSEqC parameters found for channel %d", channel.Number());
|
||||
@ -651,7 +666,7 @@ void cDvbTuner::Action(void)
|
||||
case tsTuned:
|
||||
if (Timer.TimedOut()) {
|
||||
tunerStatus = tsSet;
|
||||
diseqcCommands = NULL;
|
||||
lastDiseqc = NULL;
|
||||
if (time(NULL) - lastTimeoutReport > 60) { // let's not get too many of these
|
||||
isyslog("frontend %d/%d timed out while tuning to channel %d, tp %d", adapter, frontend, channel.Number(), channel.Transponder());
|
||||
lastTimeoutReport = time(NULL);
|
||||
@ -661,7 +676,7 @@ void cDvbTuner::Action(void)
|
||||
case tsLocked:
|
||||
if (Status & FE_REINIT) {
|
||||
tunerStatus = tsSet;
|
||||
diseqcCommands = NULL;
|
||||
lastDiseqc = NULL;
|
||||
isyslog("frontend %d/%d was reinitialized", adapter, frontend);
|
||||
lastTimeoutReport = 0;
|
||||
continue;
|
||||
@ -1036,7 +1051,7 @@ bool cDvbDevice::ProvidesTransponder(const cChannel *Channel) const
|
||||
dtp.Modulation() == PSK_8 && !(frontendInfo.caps & FE_CAN_TURBO_FEC) && dtp.System() == SYS_DVBS) // "turbo fec" is a non standard FEC used by North American broadcasters - this is a best guess to determine this condition
|
||||
return false; // requires modulation system which frontend doesn't provide
|
||||
if (!cSource::IsSat(Channel->Source()) ||
|
||||
!Setup.DiSEqC || Diseqcs.Get(CardIndex() + 1, Channel->Source(), Channel->Frequency(), dtp.Polarization()))
|
||||
!Setup.DiSEqC || Diseqcs.Get(CardIndex() + 1, Channel->Source(), Channel->Frequency(), dtp.Polarization(), NULL))
|
||||
return DeviceHooksProvidesTransponder(Channel);
|
||||
return false;
|
||||
}
|
||||
|
20
scr.conf
Normal file
20
scr.conf
Normal file
@ -0,0 +1,20 @@
|
||||
# SCR (Satellite Channel Routing) configuration for VDR
|
||||
#
|
||||
# Format:
|
||||
#
|
||||
# channel frequency [pin]
|
||||
#
|
||||
# channel: SCR channel index (0-7)
|
||||
# frequency: frequency of the SCR channel ("user band")
|
||||
# pin: optional pin of the SCR channel (0-255)
|
||||
#
|
||||
# Examples:
|
||||
|
||||
# 0 1284
|
||||
# 1 1400
|
||||
# 2 1516
|
||||
# 3 1632
|
||||
# 4 1748
|
||||
# 5 1864
|
||||
# 6 1980
|
||||
# 7 2096
|
30
vdr.5
30
vdr.5
@ -8,7 +8,7 @@
|
||||
.\" License as specified in the file COPYING that comes with the
|
||||
.\" vdr distribution.
|
||||
.\"
|
||||
.\" $Id: vdr.5 2.23 2011/08/21 14:06:50 kls Exp $
|
||||
.\" $Id: vdr.5 2.24 2011/09/10 14:45:00 kls Exp $
|
||||
.\"
|
||||
.TH vdr 5 "10 Feb 2008" "1.6" "Video Disk Recorder Files"
|
||||
.SH NAME
|
||||
@ -467,6 +467,7 @@ l l.
|
||||
\fBV\fR@voltage high (18V)
|
||||
\fBA\fR@mini A
|
||||
\fBB\fR@mini B
|
||||
\fBSn\fR@Satellite channel routing code sequence for bank n follows
|
||||
\fBWnn\fR@wait nn milliseconds (nn may be any positive integer number)
|
||||
\fB[xx ...]\fR@hex code sequence (max. 6)
|
||||
.TE
|
||||
@ -484,6 +485,33 @@ to receive the satellites following thereafter. In this case, only the devices
|
||||
1, 2 and 4 would be able to receive any satellites following this line and up
|
||||
to the next such line, or the end of the file. Devices may be listed more than
|
||||
once.
|
||||
.SS SATELLITE CHANNEL ROUTING (SCR)
|
||||
The file \fIscr.conf\fR contains the channel definitions of the SCR device in use.
|
||||
The format is
|
||||
|
||||
channel frequency [pin]
|
||||
|
||||
where channel is the SCR device's channel index (0-7), frequency is the user band
|
||||
frequency of the given channel, and pin is an optional pin number (0-255). The
|
||||
actual values are device specific and can be found in the SCR device's manual.
|
||||
|
||||
Examples:
|
||||
|
||||
0 1284
|
||||
.br
|
||||
1 1400
|
||||
.br
|
||||
2 1516
|
||||
.br
|
||||
3 1632
|
||||
.br
|
||||
4 1748
|
||||
.br
|
||||
5 1864
|
||||
.br
|
||||
6 1980
|
||||
.br
|
||||
7 2096
|
||||
.SS REMOTE CONTROL KEYS
|
||||
The file \fIremote.conf\fR contains the key assignments for all remote control
|
||||
units. Each line consists of one key assignment in the following format:
|
||||
|
3
vdr.c
3
vdr.c
@ -22,7 +22,7 @@
|
||||
*
|
||||
* The project's page is at http://www.tvdr.de
|
||||
*
|
||||
* $Id: vdr.c 2.23 2011/08/15 12:42:39 kls Exp $
|
||||
* $Id: vdr.c 2.24 2011/09/10 15:03:23 kls Exp $
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
@ -598,6 +598,7 @@ int main(int argc, char *argv[])
|
||||
Setup.Load(AddDirectory(ConfigDirectory, "setup.conf"));
|
||||
Sources.Load(AddDirectory(ConfigDirectory, "sources.conf"), true, true);
|
||||
Diseqcs.Load(AddDirectory(ConfigDirectory, "diseqc.conf"), true, Setup.DiSEqC);
|
||||
Scrs.Load(AddDirectory(ConfigDirectory, "scr.conf"), true);
|
||||
Channels.Load(AddDirectory(ConfigDirectory, "channels.conf"), false, true);
|
||||
Timers.Load(AddDirectory(ConfigDirectory, "timers.conf"));
|
||||
Commands.Load(AddDirectory(ConfigDirectory, "commands.conf"));
|
||||
|
Loading…
Reference in New Issue
Block a user