vdr 2.6.8
sections.c
Go to the documentation of this file.
1/*
2 * sections.c: Section data handling
3 *
4 * See the main source file 'vdr.c' for copyright information and
5 * how to reach the author.
6 *
7 * $Id: sections.c 5.4 2022/12/06 12:25:08 kls Exp $
8 */
9
10#include "sections.h"
11#include <unistd.h>
12#include "channels.h"
13#include "device.h"
14#include "thread.h"
15
16// --- cFilterHandle----------------------------------------------------------
17
18class cFilterHandle : public cListObject {
19public:
21 int handle;
22 int used;
23 cFilterHandle(const cFilterData &FilterData);
24 };
25
27{
28 filterData = FilterData;
29 handle = -1;
30 used = 0;
31}
32
33// --- cSectionHandlerPrivate ------------------------------------------------
34
39
40// --- cSectionHandler -------------------------------------------------------
41
43:cThread(NULL, true)
44{
46 device = Device;
47 SetDescription("device %d section handler", device->DeviceNumber() + 1);
48 statusCount = 0;
49 on = false;
50 waitForLock = false;
51 flush = false;
52 startFilters = false;
53 Start();
54}
55
57{
58 Cancel(3);
59 cFilter *fi;
60 while ((fi = filters.First()) != NULL)
61 Detach(fi);
62 delete shp;
63}
64
66{
67 return shp->channel.Source();
68}
69
71{
72 return shp->channel.Transponder();
73}
74
76{
77 return &shp->channel;
78}
79
80void cSectionHandler::Add(const cFilterData *FilterData)
81{
82 Lock();
84 cFilterHandle *fh;
85 for (fh = filterHandles.First(); fh; fh = filterHandles.Next(fh)) {
86 if (fh->filterData.Is(FilterData->pid, FilterData->tid, FilterData->mask))
87 break;
88 }
89 if (!fh) {
90 int handle = device->OpenFilter(FilterData->pid, FilterData->tid, FilterData->mask);
91 if (handle >= 0) {
92 fh = new cFilterHandle(*FilterData);
93 fh->handle = handle;
95 }
96 }
97 if (fh)
98 fh->used++;
99 Unlock();
100}
101
102void cSectionHandler::Del(const cFilterData *FilterData)
103{
104 Lock();
105 statusCount++;
106 cFilterHandle *fh;
107 for (fh = filterHandles.First(); fh; fh = filterHandles.Next(fh)) {
108 if (fh->filterData.Is(FilterData->pid, FilterData->tid, FilterData->mask)) {
109 if (--fh->used <= 0) {
111 filterHandles.Del(fh);
112 break;
113 }
114 }
115 }
116 Unlock();
117}
118
120{
121 Lock();
122 statusCount++;
123 filters.Add(Filter);
124 Filter->sectionHandler = this;
125 if (on)
126 Filter->SetStatus(true);
127 Unlock();
128}
129
131{
132 Lock();
133 statusCount++;
134 Filter->SetStatus(false);
135 Filter->sectionHandler = NULL;
136 filters.Del(Filter, false);
137 Unlock();
138}
139
141{
142 Lock();
144 Unlock();
145}
146
148{
149 Lock();
150 if (on != On) {
151 if (!On || (device->HasLock() && startFilters)) {
152 statusCount++;
153 for (cFilter *fi = filters.First(); fi; fi = filters.Next(fi)) {
154 fi->SetStatus(false);
155 if (On)
156 fi->SetStatus(true);
157 }
158 flush = On;
159 if (flush)
160 flushTimer.Set();
161 on = On;
162 waitForLock = false;
163 }
164 else
165 waitForLock = On;
166 }
167 Unlock();
168}
169
170#define FLUSH_TIME 100 // ms
171
173{
174 while (Running()) {
175
176 Lock();
177 if (waitForLock) {
178 startFilters = true;
179 SetStatus(true);
180 startFilters = false;
181 }
182 int NumFilters = filterHandles.Count();
183 if (NumFilters == 0) {
184 Unlock();
186 continue;
187 }
188 pollfd pfd[NumFilters];
189 for (cFilterHandle *fh = filterHandles.First(); fh; fh = filterHandles.Next(fh)) {
190 int i = fh->Index();
191 pfd[i].fd = fh->handle;
192 pfd[i].events = POLLIN;
193 pfd[i].revents = 0;
194 }
195 int oldStatusCount = statusCount;
196 Unlock();
197
198 if (poll(pfd, NumFilters, (!on || waitForLock) ? 100 : 1000) > 0) {
199 for (int i = 0; i < NumFilters; i++) {
200 if (pfd[i].revents & POLLIN) {
201 cFilterHandle *fh = NULL;
203 if (statusCount != oldStatusCount)
204 break;
205 for (fh = filterHandles.First(); fh; fh = filterHandles.Next(fh)) {
206 if (pfd[i].fd == fh->handle)
207 break;
208 }
209 if (fh) {
210 // Read section data:
211 unsigned char buf[4096]; // max. allowed size for any EIT section
212 int r = device->ReadFilter(fh->handle, buf, sizeof(buf));
213 if (flush)
214 continue; // we do the read anyway, to flush any data that might have come from a different transponder
215 if (r > 3) { // minimum number of bytes necessary to get section length
216 int len = (((buf[1] & 0x0F) << 8) | (buf[2] & 0xFF)) + 3;
217 if (len == r) {
218 // Distribute data to all attached filters:
219 int pid = fh->filterData.pid;
220 int tid = buf[0];
221 for (cFilter *fi = filters.First(); fi; fi = filters.Next(fi)) {
222 if (fi->Matches(pid, tid))
223 fi->Process(pid, tid, buf, len);
224 }
225 }
226 else
227 dsyslog("tp %d (%d/%02X) read incomplete section - len = %d, r = %d", Transponder(), fh->filterData.pid, buf[0], len, r);
228 }
229 }
230 }
231 }
232 if (flush)
234 }
235 }
236}
int Source(void) const
Definition channels.h:152
int Transponder(void) const
Returns the transponder frequency in MHz, plus the polarization in case of sat.
Definition channels.c:154
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
Definition thread.c:72
virtual bool HasLock(int TimeoutMs=0) const
Returns true if the device has a lock on the requested transponder.
Definition device.c:1011
int DeviceNumber(void) const
Returns the number of this device (0 ... numDevices - 1).
Definition device.c:167
virtual void CloseFilter(int Handle)
Closes a file handle that has previously been opened by OpenFilter().
Definition device.c:707
virtual int ReadFilter(int Handle, void *Buffer, size_t Length)
Reads data from a handle for the given filter.
Definition device.c:702
virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask)
Opens a file handle for the given filter data.
Definition device.c:697
bool Is(u_short Pid, u_char Tid, u_char Mask)
Definition filter.c:132
u_short pid
Definition filter.h:66
u_char tid
Definition filter.h:67
u_char mask
Definition filter.h:68
cFilterData filterData
Definition sections.c:20
cFilterHandle(const cFilterData &FilterData)
Definition sections.c:26
cSectionHandler * sectionHandler
Definition filter.h:83
virtual void SetStatus(bool On)
Turns this filter on or off, depending on the value of On.
Definition filter.c:178
void Del(cListObject *Object, bool DeleteObject=true)
Definition tools.c:2251
int Count(void) const
Definition tools.h:640
void Add(cListObject *Object, cListObject *After=NULL)
Definition tools.c:2219
const T * First(void) const
Returns the first element in this list, or NULL if the list is empty.
Definition tools.h:656
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
int Transponder(void)
Definition sections.c:70
virtual void Action(void)
A derived cThread class must implement the code it wants to execute as a separate thread in this func...
Definition sections.c:172
void SetChannel(const cChannel *Channel)
Definition sections.c:140
cList< cFilterHandle > filterHandles
Definition sections.h:34
int Source(void)
Definition sections.c:65
cSectionHandlerPrivate * shp
Definition sections.h:26
const cChannel * Channel(void)
Definition sections.c:75
virtual ~cSectionHandler()
Definition sections.c:56
cTimeMs flushTimer
Definition sections.h:32
cSectionHandler(cDevice *Device)
Definition sections.c:42
void Del(const cFilterData *FilterData)
Definition sections.c:102
void Add(const cFilterData *FilterData)
Definition sections.c:80
void SetStatus(bool On)
Definition sections.c:147
bool startFilters
Definition sections.h:31
void Attach(cFilter *Filter)
Definition sections.c:119
cList< cFilter > filters
Definition sections.h:33
cDevice * device
Definition sections.h:27
void Detach(cFilter *Filter)
Definition sections.c:130
void Unlock(void)
Definition thread.h:95
void bool Start(void)
Sets the description of this thread, which will be used when logging starting or stopping of the thre...
Definition thread.c:304
void SetDescription(const char *Description,...) __attribute__((format(printf
Definition thread.c:267
bool Running(void)
Returns false if a derived cThread object shall leave its Action() function.
Definition thread.h:101
void Lock(void)
Definition thread.h:94
void Cancel(int WaitSeconds=0)
Cancels the thread by first setting 'running' to false, so that the Action() loop can finish in an or...
Definition thread.c:354
uint64_t Elapsed(void) const
Definition tools.c:807
void Set(int Ms=0)
Sets the timer.
Definition tools.c:797
#define FLUSH_TIME
Definition sections.c:170
#define LOCK_THREAD
Definition thread.h:167
#define dsyslog(a...)
Definition tools.h:37