vdr 2.7.5
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
31bool 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) {
43 synced = true;
44 }
45 else
46 return false;
47 }
48 if (SectionNumber != currentSection)
49 return false;
50 }
51 return !GetSectionFlag(SectionNumber);
52}
53
54bool 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
86cFilterData::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
103bool cFilterData::Is(u_short Pid, u_char Tid, u_char Mask)
104{
105 return pid == Pid && tid == Tid && mask == Mask;
106}
107
108bool 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
121cFilter::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
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
171bool 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
182void cFilter::Set(u_short Pid, u_char Tid, u_char Mask)
183{
184 Add(Pid, Tid, Mask, true);
185}
186
187void 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
195void 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
cListObject * next
Definition tools.h:533
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 uchar
Definition tools.h:31