vdr  2.7.6
filter.c
Go to the documentation of this file.
1 /*
2  * filter.c: Section filter
3  *
4  * See the main source file 'vdr.c' for copyright information and
5  * how to reach the author.
6  *
7  * $Id: filter.c 5.2 2024/10/13 09:47:18 kls Exp $
8  */
9 
10 #include "filter.h"
11 #include "sections.h"
12 
13 // --- cSectionSyncer --------------------------------------------------------
14 
16 {
17  random = Random;
18  Reset();
19 }
20 
22 {
23  currentVersion = -1;
24  currentSection = -1;
25  synced = false;
26  complete = false;
27  segments = 0;
28  memset(sections, 0x00, sizeof(sections));
29 }
30 
31 bool cSectionSyncer::Check(uchar Version, int SectionNumber)
32 {
33  if (Version != currentVersion) {
34  Reset();
35  currentVersion = Version;
36  }
37  if (complete)
38  return false;
39  if (!random) {
40  if (!synced) {
41  if (SectionNumber == 0) {
42  currentSection = 0;
43  synced = true;
44  }
45  else
46  return false;
47  }
48  if (SectionNumber != currentSection)
49  return false;
50  }
51  return !GetSectionFlag(SectionNumber);
52 }
53 
54 bool cSectionSyncer::Processed(int SectionNumber, int LastSectionNumber, int SegmentLastSectionNumber)
55 {
56  SetSectionFlag(SectionNumber, true); // the flag for this section
57  if (!random)
58  currentSection++; // expect the next section
59  int Index = SectionNumber / 8; // the segment (byte) in which this section lies
60  uchar b = 0xFF; // all sections in this segment
61  if (SegmentLastSectionNumber < 0 && Index == LastSectionNumber / 8)
62  SegmentLastSectionNumber = LastSectionNumber;
63  if (SegmentLastSectionNumber >= 0) {
64  b >>= 7 - (SegmentLastSectionNumber & 0x07); // limits them up to the last section in this segment
65  if (!random && SectionNumber == SegmentLastSectionNumber)
66  currentSection = (SectionNumber + 8) & ~0x07; // expect first section of next segment
67  }
68  if (sections[Index] == b) // all expected sections in this segment have been received
69  segments |= 1 << Index; // so we set the respective bit in the segments flags
70  uint32_t s = 0xFFFFFFFF; // all segments
71  s >>= 31 - (LastSectionNumber / 8); // limits them up to the last expected segment
72  complete = segments == s;
73  return complete;
74 }
75 
76 // --- cFilterData -----------------------------------------------------------
77 
79 {
80  pid = 0;
81  tid = 0;
82  mask = 0;
83  sticky = false;
84 }
85 
86 cFilterData::cFilterData(u_short Pid, u_char Tid, u_char Mask, bool Sticky)
87 {
88  pid = Pid;
89  tid = Tid;
90  mask = Mask;
91  sticky = Sticky;
92 }
93 
95 {
96  pid = FilterData.pid;
97  tid = FilterData.tid;
98  mask = FilterData.mask;
99  sticky = FilterData.sticky;
100  return *this;
101 }
102 
103 bool cFilterData::Is(u_short Pid, u_char Tid, u_char Mask)
104 {
105  return pid == Pid && tid == Tid && mask == Mask;
106 }
107 
108 bool cFilterData::Matches(u_short Pid, u_char Tid)
109 {
110  return pid == Pid && tid == (Tid & mask);
111 }
112 
113 // --- cFilter ---------------------------------------------------------------
114 
116 {
117  sectionHandler = NULL;
118  on = false;
119 }
120 
121 cFilter::cFilter(u_short Pid, u_char Tid, u_char Mask)
122 {
123  sectionHandler = NULL;
124  on = false;
125  Set(Pid, Tid, Mask);
126 }
127 
129 {
130  if (sectionHandler)
131  sectionHandler->Detach(this);
132 }
133 
135 {
136  return sectionHandler ? sectionHandler->Source() : 0;
137 }
138 
140 {
141  return sectionHandler ? sectionHandler->Transponder() : 0;
142 }
143 
145 {
146  return sectionHandler ? sectionHandler->Channel() : NULL;
147 }
148 
149 void cFilter::SetStatus(bool On)
150 {
151  if (sectionHandler && on != On) {
152  cFilterData *fd = data.First();
153  while (fd) {
154  if (On)
155  sectionHandler->Add(fd);
156  else {
157  sectionHandler->Del(fd);
158  if (!fd->sticky) {
159  cFilterData *next = data.Next(fd);
160  data.Del(fd);
161  fd = next;
162  continue;
163  }
164  }
165  fd = data.Next(fd);
166  }
167  on = On;
168  }
169 }
170 
171 bool cFilter::Matches(u_short Pid, u_char Tid)
172 {
173  if (on) {
174  for (cFilterData *fd = data.First(); fd; fd = data.Next(fd)) {
175  if (fd->Matches(Pid, Tid))
176  return true;
177  }
178  }
179  return false;
180 }
181 
182 void cFilter::Set(u_short Pid, u_char Tid, u_char Mask)
183 {
184  Add(Pid, Tid, Mask, true);
185 }
186 
187 void cFilter::Add(u_short Pid, u_char Tid, u_char Mask, bool Sticky)
188 {
189  cFilterData *fd = new cFilterData(Pid, Tid, Mask, Sticky);
190  data.Add(fd);
191  if (sectionHandler && on)
192  sectionHandler->Add(fd);
193 }
194 
195 void cFilter::Del(u_short Pid, u_char Tid, u_char Mask)
196 {
197  for (cFilterData *fd = data.First(); fd; fd = data.Next(fd)) {
198  if (fd->Is(Pid, Tid, Mask)) {
199  if (sectionHandler && on)
200  sectionHandler->Del(fd);
201  data.Del(fd);
202  return;
203  }
204  }
205 }
cFilterData & operator=(const cFilterData &FilterData)
Definition: filter.c:94
bool Matches(u_short Pid, u_char Tid)
Definition: filter.c:108
bool Is(u_short Pid, u_char Tid, u_char Mask)
Definition: filter.c:103
u_short pid
Definition: filter.h:60
bool sticky
Definition: filter.h:63
u_char tid
Definition: filter.h:61
cFilterData(void)
Definition: filter.c:78
u_char mask
Definition: filter.h:62
void Set(u_short Pid, u_char Tid, u_char Mask=0xFF)
Sets the given filter data by calling Add() with Sticky = true.
Definition: filter.c:182
cSectionHandler * sectionHandler
Definition: filter.h:77
int Transponder(void)
Returns the transponder of the data delivered to this filter.
Definition: filter.c:139
virtual void SetStatus(bool On)
Turns this filter on or off, depending on the value of On.
Definition: filter.c:149
int Source(void)
Returns the source of the data delivered to this filter.
Definition: filter.c:134
const cChannel * Channel(void)
Returns the channel of the data delivered to this filter.
Definition: filter.c:144
bool on
Definition: filter.h:79
cList< cFilterData > data
Definition: filter.h:78
void Del(u_short Pid, u_char Tid, u_char Mask=0xFF)
Deletes the given filter data from this filter.
Definition: filter.c:195
void Add(u_short Pid, u_char Tid, u_char Mask=0xFF, bool Sticky=false)
Adds the given filter data to this filter.
Definition: filter.c:187
cFilter(void)
Definition: filter.c:115
virtual ~cFilter() override
Definition: filter.c:128
bool Matches(u_short Pid, u_char Tid)
Indicates whether this filter wants to receive data from the given Pid/Tid.
Definition: filter.c:171
void Del(cListObject *Object, bool DeleteObject=true)
Definition: tools.c:2209
void Add(cListObject *Object, cListObject *After=NULL)
Definition: tools.c:2177
cListObject * next
Definition: tools.h:533
const T * Next(const T *Object) const
< Returns the element immediately before Object in this list, or NULL if Object is the first element ...
Definition: tools.h:650
const T * First(void) const
Returns the first element in this list, or NULL if the list is empty.
Definition: tools.h:643
int Transponder(void)
Definition: sections.c:70
int Source(void)
Definition: sections.c:65
const cChannel * Channel(void)
Definition: sections.c:75
void Del(const cFilterData *FilterData)
Definition: sections.c:102
void Add(const cFilterData *FilterData)
Definition: sections.c:80
void Detach(cFilter *Filter)
Definition: sections.c:130
void SetSectionFlag(uchar Section, bool On)
Definition: filter.h:25
bool Check(uchar Version, int SectionNumber)
Returns true if Version is not the current version, or the given SectionNumber has not been marked as...
Definition: filter.c:31
int currentSection
Definition: filter.h:19
cSectionSyncer(bool Random=false)
Sets up a new section syncer.
Definition: filter.c:15
int currentVersion
Definition: filter.h:18
bool complete
Definition: filter.h:22
bool Processed(int SectionNumber, int LastSectionNumber, int SegmentLastSectionNumber=-1)
Marks the given SectionNumber as processed.
Definition: filter.c:54
uchar sections[32]
Definition: filter.h:24
uint32_t segments
Definition: filter.h:23
void Reset(void)
Definition: filter.c:21
bool random
Definition: filter.h:20
bool GetSectionFlag(uchar Section)
Definition: filter.h:26
bool synced
Definition: filter.h:21
unsigned char u_char
Definition: headers.h:24
unsigned char uchar
Definition: tools.h:31