25 char *sourcebuf = NULL;
30 int fields = sscanf(s,
"%m[^-]-%d-%d-%d-%d", &sourcebuf, &
nid, &
tid, &
sid, &
rid);
31 if (fields == 4 || fields == 5) {
107 if (
Setup.ShowChannelNamesWithSource == 0) {
113 if (
Setup.ShowChannelNamesWithSource == 1)
144 switch (toupper(Polarization)) {
149 default:
esyslog(
"ERROR: invalid value for Polarization '%c'", Polarization);
161 const char *p = strpbrk(
parameters,
"HVLRhvlr");
240 if (Channels &&
Number()) {
241 dsyslog(
"changing id of channel %d (%s) from %d-%d-%d-%d to %d-%d-%d-%d",
Number(),
name,
nid,
tid,
sid,
rid,
Nid,
Tid,
Sid,
Rid);
274 if (nn || ns || np) {
312 for (
int i = 0; a[i] || b[i]; i++) {
313 if (!a[i] || !b[i]) {
317 if (na && nb && strcmp(na[i], nb[i]) != 0)
329 while (a[i] || i == 0) {
330 q += sprintf(q, Base == 16 ?
"%s%X" :
"%s%d", i ?
"," :
"", a[i]);
331 const char *Delim =
"=";
334 q += sprintf(q,
"%s%s", Delim, n[i]);
338 q += sprintf(q,
"%s@%d", Delim, t[i]);
348bool cChannel::SetPids(
int Vpid,
int Ppid,
int Vtype,
int *
Apids,
int *Atypes,
char ALangs[][
MAXLANGCODE2],
int *
Dpids,
int *Dtypes,
char DLangs[][
MAXLANGCODE2],
int *
Spids,
char SLangs[][
MAXLANGCODE2],
int Tpid)
355 int m =
IntArraysDiffer(
apids,
Apids,
alangs, ALangs) |
IntArraysDiffer(
atypes, Atypes) |
IntArraysDiffer(
dpids,
Dpids,
dlangs, DLangs) |
IntArraysDiffer(
dtypes, Dtypes) |
IntArraysDiffer(
spids,
Spids,
slangs, SLangs);
362 char OldApidsBuf[BufferSize];
363 char NewApidsBuf[BufferSize];
364 char *q = OldApidsBuf;
379 char OldSpidsBuf[SBufferSize];
380 char NewSpidsBuf[SBufferSize];
388 dsyslog(
"changing pids of channel %d (%s) from %d+%d=%d:%s:%s:%d to %d+%d=%d:%s:%s:%d",
Number(),
name,
vpid,
ppid,
vtype, OldApidsBuf, OldSpidsBuf,
tpid,
Vpid,
Ppid,
Vtype, NewApidsBuf, NewSpidsBuf,
Tpid);
392 for (
int i = 0; i <
MAXAPIDS; i++) {
398 for (
int i = 0; i <
MAXDPIDS; i++) {
404 for (
int i = 0; i <
MAXSPIDS; i++) {
418 bool Modified =
false;
419 if (SubtitlingTypes) {
420 for (
int i = 0; i <
MAXSPIDS; i++) {
425 if (CompositionPageIds) {
426 for (
int i = 0; i <
MAXSPIDS; i++) {
431 if (AncillaryPageIds) {
432 for (
int i = 0; i <
MAXSPIDS; i++) {
449 if (lc->Channel() == LinkChannel) {
466 char OldCaIdsBuf[
MAXCAIDS * 5 + 10];
467 char NewCaIdsBuf[
MAXCAIDS * 5 + 10];
471 dsyslog(
"changing caids of channel %d (%s) from %s to %s",
Number(),
name, OldCaIdsBuf, NewCaIdsBuf);
472 for (
int i = 0; i <=
MAXCAIDS; i++) {
487 if (
Number() && Level > 1)
516 q += sprintf(q,
"linking channel %d (%s) from",
Number(),
name);
519 lc->Channel()->SetRefChannel(NULL);
520 q += sprintf(q,
" %d", lc->Channel()->Number());
525 q += sprintf(q,
" none");
526 q += sprintf(q,
" to");
530 lc->Channel()->SetRefChannel(
this);
531 q += sprintf(q,
" %d", lc->Channel()->Number());
536 q += sprintf(q,
" none");
556 char FullName[strlen(Channel->
name) + 1 + strlen(Channel->
shortName) + 1 + strlen(Channel->
provider) + 1 + 10];
558 q += sprintf(q,
"%s", Channel->
name);
561 q += sprintf(q,
",%s", Channel->
shortName);
562 else if (strchr(Channel->
name,
','))
563 q += sprintf(q,
",");
565 q += sprintf(q,
";%s", Channel->
provider);
579 q += snprintf(q,
sizeof(vpidbuf),
"%d", Channel->
vpid);
581 q += snprintf(q,
sizeof(vpidbuf) - (q - vpidbuf),
"+%d", Channel->
ppid);
583 q += snprintf(q,
sizeof(vpidbuf) - (q - vpidbuf),
"=%d", Channel->
vtype);
586 char apidbuf[ABufferSize];
589 if (Channel->
dpids[0]) {
595 char tpidbuf[TBufferSize];
597 q += snprintf(q,
sizeof(tpidbuf),
"%d", Channel->
tpid);
598 if (Channel->
spids[0]) {
606 buffer =
cString::sprintf(
"%s:%d:%s:%s:%d:%s:%s:%s:%s:%d:%d:%d:%d", FullName, Channel->
frequency, *Channel->
parameters, *
cSource::ToString(Channel->
source), Channel->
srate, vpidbuf, apidbuf, tpidbuf, caidbuf, Channel->
sid, Channel->
nid, Channel->
tid, Channel->
rid);
621 if (*++s ==
'@' && *++s) {
624 int n = strtol(s, &p, 10);
625 if (!errno && p != s && n > 0) {
635 char *namebuf = NULL;
636 char *sourcebuf = NULL;
637 char *parambuf = NULL;
638 char *vpidbuf = NULL;
639 char *apidbuf = NULL;
640 char *tpidbuf = NULL;
641 char *caidbuf = NULL;
642 int fields = sscanf(s,
"%m[^:]:%d :%m[^:]:%m[^:] :%d :%m[^:]:%m[^:]:%m[^:]:%m[^:]:%d :%d :%d :%d ", &namebuf, &
frequency, ¶mbuf, &sourcebuf, &
srate, &vpidbuf, &apidbuf, &tpidbuf, &caidbuf, &
sid, &
nid, &
tid, &
rid);
649 if (sscanf(tpidbuf,
"%d", &
tpid) != 1)
663 if (parambuf && sourcebuf && vpidbuf && apidbuf) {
669 if ((p = strchr(vpidbuf,
'=')) != NULL) {
671 if (sscanf(p,
"%d", &
vtype) != 1)
674 if ((p = strchr(vpidbuf,
'+')) != NULL) {
676 if (sscanf(p,
"%d", &
ppid) != 1)
679 if (sscanf(vpidbuf,
"%d", &
vpid) != 1)
686 char *dpidbuf = strchr(apidbuf,
';');
693 while ((q = strtok_r(p,
",", &strtok_next)) != NULL) {
696 char *l = strchr(q,
'=');
699 char *t = strchr(l,
'@');
702 atypes[NumApids] = strtol(t, NULL, 10);
708 if ((
apids[NumApids] = strtol(q, NULL, 10)) != 0)
712 esyslog(
"ERROR: too many APIDs!");
722 while ((q = strtok_r(p,
",", &strtok_next)) != NULL) {
725 char *l = strchr(q,
'=');
728 char *t = strchr(l,
'@');
731 dtypes[NumDpids] = strtol(t, NULL, 10);
737 if ((
dpids[NumDpids] = strtol(q, NULL, 10)) != 0)
741 esyslog(
"ERROR: too many DPIDs!");
748 if ((p = strchr(tpidbuf,
';')) != NULL) {
752 while ((q = strtok_r(p,
",", &strtok_next)) != NULL) {
754 char *l = strchr(q,
'=');
761 spids[NumSpids++] = strtol(q, NULL, 10);
764 esyslog(
"ERROR: too many SPIDs!");
769 if (sscanf(tpidbuf,
"%d", &
tpid) != 1)
776 while ((q = strtok_r(p,
",", &strtok_next)) != NULL) {
778 caids[NumCaIds++] = strtol(q, NULL, 16) & 0xFFFF;
783 esyslog(
"ERROR: too many CA ids!");
791 char *p = strchr(namebuf,
';');
796 p = strrchr(namebuf,
',');
812 esyslog(
"ERROR: channel data results in invalid ID!");
824 return fprintf(f,
"%s\n", *
ToText()) > 0;
870 if (!Channel->GroupSep())
873 ChannelSorter.
Sort();
878 dsyslog(
"deleting duplicate channel %s", *
Next->channel->ToText());
909 while (Channel && !(Channel->
GroupSep() && *Channel->
Name()))
910 Channel =
Get(++Idx);
911 return Channel ? Idx : -1;
917 while (Channel && !(Channel->
GroupSep() && *Channel->
Name()))
918 Channel =
Get(--Idx);
919 return Channel ? Idx : -1;
925 while (Channel && Channel->
GroupSep())
926 Channel =
Get(++Idx);
927 return Channel ? Idx : -1;
933 while (Channel && Channel->
GroupSep())
934 Channel =
Get(--Idx);
935 return Channel ? Idx : -1;
944 if (Channel->GroupSep()) {
945 if (Channel->Number() > Number)
946 Number = Channel->Number();
951 Channel->SetNumber(Number++);
958 int Number = From->
Number();
959 if (Number < To->Number()) {
963 if (Channel->GroupSep()) {
964 if (Channel->Number() > Number)
965 Number = Channel->Number();
970 return Number == To->
Number();
979 ch->DelLinkChannel(Channel);
987 if (!Channel->GroupSep()) {
988 if (Channel->Number() == Number)
990 else if (SkipGap && Channel->Number() > Number)
991 return SkipGap > 0 ? Channel : Previous;
1013 int sid = ChannelID.
Sid();
1021 if (TryWithoutRid) {
1029 if (TryWithoutPolarization) {
1043 int source = ChannelID.
Source();
1044 int nid = ChannelID.
Nid();
1045 int tid = ChannelID.
Tid();
1047 if (Channel->Tid() == tid && Channel->Nid() == nid && Channel->Source() == source)
1057 if (!Channel->GroupSep() && Channel != OldChannel && Channel->
GetChannelID() == NewChannelID)
1073 for (
const cChannel *Channel = Channels->First(); Channel; Channel = Channels->
Next(Channel)) {
1074 if (!Channel->GroupSep())
1085 for (
const cChannel *Channel = Channels->First(); Channel; Channel = Channels->
Next(Channel)) {
1086 if (!Channel->GroupSep())
1109 dsyslog(
"creating new channel '%s,%s;%s' on %s transponder %d with id %d-%d-%d-%d", Name, ShortName, Provider, *
cSource::ToString(Transponder->
Source()), Transponder->
Transponder(), Nid, Tid, Sid, Rid);
1111 NewChannel->CopyTransponderData(Transponder);
1113 NewChannel->SetName(Name, ShortName, Provider);
1122#define CHANNELMARKOBSOLETE "OBSOLETE"
1123#define CHANNELTIMEOBSOLETE 3600
1127 bool ChannelsModified =
false;
1129 if (time(NULL) - Channel->Seen() >
CHANNELTIMEOBSOLETE && Channel->Source() == Source && Channel->Nid() == Nid && Channel->Tid() == Tid && Channel->Rid() == 0) {
1130 int OldShowChannelNamesWithSource =
Setup.ShowChannelNamesWithSource;
1131 Setup.ShowChannelNamesWithSource = 0;
1134 Setup.ShowChannelNamesWithSource = OldShowChannelNamesWithSource;
1137 return ChannelsModified;
1145 snprintf(buffer,
sizeof(buffer),
"%s", Channel->
Name());
1147 snprintf(buffer,
sizeof(buffer),
"%d%s %s", Channel->
Number(), Number ?
"-" :
"", Channel->
Name());
1150 snprintf(buffer,
sizeof(buffer),
"%d-", Number);
1152 snprintf(buffer,
sizeof(buffer),
"%s",
tr(
"*** Invalid Channel ***"));
1160 bool ChannelsModified =
false;
1163 int e = strlen(
name) - mlen - 1;
1168 int OldShowChannelNamesWithSource =
Setup.ShowChannelNamesWithSource;
1169 Setup.ShowChannelNamesWithSource = 0;
1171 Setup.ShowChannelNamesWithSource = OldShowChannelNamesWithSource;
1173 return ChannelsModified;
#define CHANNELMARKOBSOLETE
static int IntArrayToString(char *s, const int *a, int Base=10, const char n[][MAXLANGCODE2]=NULL, const int *t=NULL)
#define CHANNELTIMEOBSOLETE
static int IntArraysDiffer(const int *a, const int *b, const char na[][MAXLANGCODE2]=NULL, const char nb[][MAXLANGCODE2]=NULL)
cString ChannelString(const cChannel *Channel, int Number)
#define CHANNELMOD_TRANSP
#define LOCK_CHANNELS_READ
#define ISTRANSPONDER(f1, f2)
#define LOCK_CHANNELS_WRITE
cChannelSorter(cChannel *Channel)
virtual int Compare(const cListObject &ListObject) const override
Must return 0 if this object is equal to ListObject, a positive value if it is "greater",...
const int * Dpids(void) const
const cChannel * RefChannel(void) const
bool Parse(const char *s)
cString TransponderDataToString(void) const
bool SetCaIds(const int *CaIds)
bool SetName(const char *Name, const char *ShortName, const char *Provider)
cString ToText(void) const
bool SetPortalName(const char *PortalName)
bool SetLinkChannels(cLinkChannels *LinkChannels)
const char * Name(void) const
tChannelID GetChannelID(void) const
bool SetPids(int Vpid, int Ppid, int Vtype, int *Apids, int *Atypes, char ALangs[][MAXLANGCODE2], int *Dpids, int *Dtypes, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid)
const cSchedule * schedule
char alangs[MAXAPIDS][MAXLANGCODE2]
char dlangs[MAXDPIDS][MAXLANGCODE2]
bool GroupSep(void) const
const char * Parameters(void) const
void CopyTransponderData(const cChannel *Channel)
int Frequency(void) const
Returns the actual frequency, as given in 'channels.conf'.
void SetRefChannel(cChannel *RefChannel)
bool ClearObsoleteChannel(void)
const char * ShortName(bool OrName=false) const
bool SetTransponderData(int Source, int Frequency, int Srate, const char *Parameters, bool Quiet=false)
char slangs[MAXSPIDS][MAXLANGCODE2]
const char * PortalName(void) const
uchar subtitlingTypes[MAXSPIDS]
bool SetSource(int Source)
const int * Apids(void) const
bool SetId(cChannels *Channels, int Nid, int Tid, int Sid, int Rid=0)
int Modification(int Mask=CHANNELMOD_ALL) const
bool SetCaDescriptors(int Level)
cLinkChannels * linkChannels
int Transponder(void) const
Returns the transponder frequency in MHz, plus the polarization in case of sat.
uint16_t ancillaryPageIds[MAXSPIDS]
void DelLinkChannel(cChannel *LinkChannel)
const char * Provider(void) const
bool SetSubtitlingDescriptors(uchar *SubtitlingTypes, uint16_t *CompositionPageIds, uint16_t *AncillaryPageIds)
const cLinkChannels * LinkChannels(void) const
void UpdateNameSource(void)
const int * Spids(void) const
uint16_t compositionPageIds[MAXSPIDS]
cChannel & operator=(const cChannel &Channel)
static cChannels * GetChannelsWrite(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of channels for write access.
void UnhashChannel(cChannel *Channel)
static int MaxChannelNameLength(void)
int GetNextGroup(int Idx) const
Get next channel group.
bool HasUniqueChannelID(const cChannel *NewChannel, const cChannel *OldChannel=NULL) const
bool MoveNeedsDecrement(cChannel *From, cChannel *To)
int GetPrevNormal(int Idx) const
Get previous normal channel (not group)
static int maxChannelNameLength
const cChannel * GetByServiceID(int Source, int Transponder, unsigned short ServiceID) const
bool ModifiedByUser(int &State) const
Returns true if the channels have been modified by the user since the last call to this function with...
static int MaxShortChannelNameLength(void)
static int maxShortChannelNameLength
void HashChannel(cChannel *Channel)
static const cChannels * GetChannelsRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of channels for read access.
cHash< cChannel > channelsHashSid
void ReNumber(void)
Recalculate 'number' based on channel type.
const cChannel * GetByNumber(int Number, int SkipGap=0) const
void SetModifiedByUser(void)
static cChannels channels
cChannel * NewChannel(const cChannel *Transponder, const char *Name, const char *ShortName, const char *Provider, int Nid, int Tid, int Sid, int Rid=0)
const cChannel * GetByTransponderID(tChannelID ChannelID) const
bool MarkObsoleteChannels(int Source, int Nid, int Tid)
const cChannel * GetByChannelID(tChannelID ChannelID, bool TryWithoutRid=false, bool TryWithoutPolarization=false) const
bool SwitchTo(int Number) const
void DeleteDuplicateChannels(void)
int GetPrevGroup(int Idx) const
Get previous channel group.
static bool Load(const char *FileName, bool AllowComments=false, bool MustExist=false)
void Del(cChannel *Channel)
Delete the given Channel from the list.
int GetNextNormal(int Idx) const
Get next normal channel (not group)
cConfig(const char *NeedsLocking=NULL)
const char * FileName(void)
static cDevice * PrimaryDevice(void)
Returns the primary device.
bool SwitchChannel(const cChannel *Channel, bool LiveView)
Switches the device to the given Channel, initiating transfer mode if necessary.
void Del(cListObject *Object, bool DeleteObject=true)
void Add(cListObject *Object, cListObject *After=NULL)
cListObject(const cListObject &ListObject)
cListObject * Next(void) const
const cChannel * First(void) const
cList(const char *NeedsLocking=NULL)
const cChannel * Next(const cChannel *Object) const
const cChannel * Get(int Index) const
static int FromString(const char *s)
static bool IsTerr(int Code)
static cString ToString(int Code)
static char ToChar(int Code)
static cString sprintf(const char *fmt,...) __attribute__((format(printf
tChannelID & ClrRid(void)
static const tChannelID InvalidID
int nid
actually the "original" network id
static tChannelID FromString(const char *s)
cString ToString(void) const
tChannelID & ClrPolarization(void)