vdr  2.6.9
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.1 2021/03/16 15:10:54 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 #if DEPRECATED_SECTIONSYNCER_SYNC_REPEAT
78 {
80  synced = false;
81  complete = false;
82 }
83 
84 bool cSectionSyncer::Sync(uchar Version, int Number, int LastNumber)
85 {
86  if (Version != currentVersion) {
87  Reset();
88  currentVersion = Version;
89  }
90  if (!synced) {
91  if (Number != 0)
92  return false;
93  else
94  synced = true;
95  }
96  currentSection = Number;
97  bool Result = !GetSectionFlag(Number);
98  SetSectionFlag(Number, true);
99  if (Number == LastNumber)
100  complete = true;
101  return Result;
102 }
103 #endif
104 
105 // --- cFilterData -----------------------------------------------------------
106 
108 {
109  pid = 0;
110  tid = 0;
111  mask = 0;
112  sticky = false;
113 }
114 
115 cFilterData::cFilterData(u_short Pid, u_char Tid, u_char Mask, bool Sticky)
116 {
117  pid = Pid;
118  tid = Tid;
119  mask = Mask;
120  sticky = Sticky;
121 }
122 
124 {
125  pid = FilterData.pid;
126  tid = FilterData.tid;
127  mask = FilterData.mask;
128  sticky = FilterData.sticky;
129  return *this;
130 }
131 
132 bool cFilterData::Is(u_short Pid, u_char Tid, u_char Mask)
133 {
134  return pid == Pid && tid == Tid && mask == Mask;
135 }
136 
137 bool cFilterData::Matches(u_short Pid, u_char Tid)
138 {
139  return pid == Pid && tid == (Tid & mask);
140 }
141 
142 // --- cFilter ---------------------------------------------------------------
143 
145 {
146  sectionHandler = NULL;
147  on = false;
148 }
149 
150 cFilter::cFilter(u_short Pid, u_char Tid, u_char Mask)
151 {
152  sectionHandler = NULL;
153  on = false;
154  Set(Pid, Tid, Mask);
155 }
156 
158 {
159  if (sectionHandler)
160  sectionHandler->Detach(this);
161 }
162 
164 {
165  return sectionHandler ? sectionHandler->Source() : 0;
166 }
167 
169 {
170  return sectionHandler ? sectionHandler->Transponder() : 0;
171 }
172 
174 {
175  return sectionHandler ? sectionHandler->Channel() : NULL;
176 }
177 
178 void cFilter::SetStatus(bool On)
179 {
180  if (sectionHandler && on != On) {
181  cFilterData *fd = data.First();
182  while (fd) {
183  if (On)
184  sectionHandler->Add(fd);
185  else {
186  sectionHandler->Del(fd);
187  if (!fd->sticky) {
188  cFilterData *next = data.Next(fd);
189  data.Del(fd);
190  fd = next;
191  continue;
192  }
193  }
194  fd = data.Next(fd);
195  }
196  on = On;
197  }
198 }
199 
200 bool cFilter::Matches(u_short Pid, u_char Tid)
201 {
202  if (on) {
203  for (cFilterData *fd = data.First(); fd; fd = data.Next(fd)) {
204  if (fd->Matches(Pid, Tid))
205  return true;
206  }
207  }
208  return false;
209 }
210 
211 void cFilter::Set(u_short Pid, u_char Tid, u_char Mask)
212 {
213  Add(Pid, Tid, Mask, true);
214 }
215 
216 void cFilter::Add(u_short Pid, u_char Tid, u_char Mask, bool Sticky)
217 {
218  cFilterData *fd = new cFilterData(Pid, Tid, Mask, Sticky);
219  data.Add(fd);
220  if (sectionHandler && on)
221  sectionHandler->Add(fd);
222 }
223 
224 void cFilter::Del(u_short Pid, u_char Tid, u_char Mask)
225 {
226  for (cFilterData *fd = data.First(); fd; fd = data.Next(fd)) {
227  if (fd->Is(Pid, Tid, Mask)) {
228  if (sectionHandler && on)
229  sectionHandler->Del(fd);
230  data.Del(fd);
231  return;
232  }
233  }
234 }
cFilterData & operator=(const cFilterData &FilterData)
Definition: filter.c:123
bool Matches(u_short Pid, u_char Tid)
Definition: filter.c:137
bool Is(u_short Pid, u_char Tid, u_char Mask)
Definition: filter.c:132
u_short pid
Definition: filter.h:66
bool sticky
Definition: filter.h:69
u_char tid
Definition: filter.h:67
cFilterData(void)
Definition: filter.c:107
u_char mask
Definition: filter.h:68
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:211
cSectionHandler * sectionHandler
Definition: filter.h:83
int Transponder(void)
Returns the transponder of the data delivered to this filter.
Definition: filter.c:168
virtual void SetStatus(bool On)
Turns this filter on or off, depending on the value of On.
Definition: filter.c:178
int Source(void)
Returns the source of the data delivered to this filter.
Definition: filter.c:163
const cChannel * Channel(void)
Returns the channel of the data delivered to this filter.
Definition: filter.c:173
bool on
Definition: filter.h:85
cList< cFilterData > data
Definition: filter.h:84
void Del(u_short Pid, u_char Tid, u_char Mask=0xFF)
Deletes the given filter data from this filter.
Definition: filter.c:224
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:216
virtual ~cFilter()
Definition: filter.c:157
cFilter(void)
Definition: filter.c:144
bool Matches(u_short Pid, u_char Tid)
Indicates whether this filter wants to receive data from the given Pid/Tid.
Definition: filter.c:200
void Del(cListObject *Object, bool DeleteObject=true)
Definition: tools.c:2251
void Add(cListObject *Object, cListObject *After=NULL)
Definition: tools.c:2219
cListObject * next
Definition: tools.h:546
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:663
const T * First(void) const
Returns the first element in this list, or NULL if the list is empty.
Definition: tools.h:656
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:27
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:21
cSectionSyncer(bool Random=false)
Sets up a new section syncer.
Definition: filter.c:15
int currentVersion
Definition: filter.h:20
bool complete
Definition: filter.h:24
bool Processed(int SectionNumber, int LastSectionNumber, int SegmentLastSectionNumber=-1)
Marks the given SectionNumber as processed.
Definition: filter.c:54
bool Sync(uchar Version, int Number, int LastNumber)
Definition: filter.c:84
uchar sections[32]
Definition: filter.h:26
void Repeat(void)
Definition: filter.c:77
uint32_t segments
Definition: filter.h:25
void Reset(void)
Definition: filter.c:21
bool random
Definition: filter.h:22
bool GetSectionFlag(uchar Section)
Definition: filter.h:28
bool synced
Definition: filter.h:23
unsigned char u_char
Definition: headers.h:24
unsigned char uchar
Definition: tools.h:31