vdr  2.2.0
sdt.c
Go to the documentation of this file.
1 /*
2  * sdt.c: SDT section filter
3  *
4  * See the main source file 'vdr.c' for copyright information and
5  * how to reach the author.
6  *
7  * $Id: sdt.c 3.4 2015/01/04 14:33:35 kls Exp $
8  */
9 
10 #include "sdt.h"
11 #include "channels.h"
12 #include "config.h"
13 #include "libsi/section.h"
14 #include "libsi/descriptor.h"
15 
16 // --- cSdtFilter ------------------------------------------------------------
17 
19 {
21  patFilter = PatFilter;
22  Set(0x11, 0x42); // SDT
23 }
24 
25 void cSdtFilter::SetStatus(bool On)
26 {
27  cMutexLock MutexLock(&mutex);
30  if (!On)
32 }
33 
35 {
36  cMutexLock MutexLock(&mutex);
37  source = Source;
38 }
39 
40 void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
41 {
42  cMutexLock MutexLock(&mutex);
43  if (!(source && Transponder()))
44  return;
45  SI::SDT sdt(Data, false);
46  if (!sdt.CheckCRCAndParse())
47  return;
49  return;
50  if (!Channels.Lock(true, 10))
51  return;
52  SI::SDT::Service SiSdtService;
53  for (SI::Loop::Iterator it; sdt.serviceLoop.getNext(SiSdtService, it); ) {
55  if (!channel)
56  channel = Channels.GetByChannelID(tChannelID(source, 0, Transponder(), SiSdtService.getServiceId()));
57  if (channel)
58  channel->SetSeen();
59 
60  cLinkChannels *LinkChannels = NULL;
61  SI::Descriptor *d;
62  for (SI::Loop::Iterator it2; (d = SiSdtService.serviceDescriptors.getNext(it2)); ) {
63  switch (d->getDescriptorTag()) {
66  switch (sd->getServiceType()) {
67  case 0x01: // digital television service
68  case 0x02: // digital radio sound service
69  case 0x04: // NVOD reference service
70  case 0x05: // NVOD time-shifted service
71  case 0x16: // digital SD television service
72  case 0x19: // digital HD television service
73  {
74  char NameBuf[Utf8BufSize(1024)];
75  char ShortNameBuf[Utf8BufSize(1024)];
76  char ProviderNameBuf[Utf8BufSize(1024)];
77  sd->serviceName.getText(NameBuf, ShortNameBuf, sizeof(NameBuf), sizeof(ShortNameBuf));
78  char *pn = compactspace(NameBuf);
79  char *ps = compactspace(ShortNameBuf);
80  if (!*ps && cSource::IsCable(source)) {
81  // Some cable providers don't mark short channel names according to the
82  // standard, but rather go their own way and use "name>short name":
83  char *p = strchr(pn, '>'); // fix for UPC Wien
84  if (p && p > pn) {
85  *p++ = 0;
86  strcpy(ShortNameBuf, skipspace(p));
87  }
88  }
89  // Avoid ',' in short name (would cause trouble in channels.conf):
90  for (char *p = ShortNameBuf; *p; p++) {
91  if (*p == ',')
92  *p = '.';
93  }
94  sd->providerName.getText(ProviderNameBuf, sizeof(ProviderNameBuf));
95  char *pp = compactspace(ProviderNameBuf);
96  if (channel) {
97  channel->SetId(sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId());
98  if (Setup.UpdateChannels == 1 || Setup.UpdateChannels >= 3)
99  channel->SetName(pn, ps, pp);
100  // Using SiSdtService.getFreeCaMode() is no good, because some
101  // tv stations set this flag even for non-encrypted channels :-(
102  // The special value 0xFFFF was supposed to mean "unknown encryption"
103  // and would have been overwritten with real CA values later:
104  // channel->SetCa(SiSdtService.getFreeCaMode() ? 0xFFFF : 0);
105  }
106  else if (*pn && Setup.UpdateChannels >= 4) {
107  channel = Channels.NewChannel(Channel(), pn, ps, pp, sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId());
108  patFilter->Trigger(SiSdtService.getServiceId());
109  }
110  }
111  default: ;
112  }
113  }
114  break;
115  // Using the CaIdentifierDescriptor is no good, because some tv stations
116  // just don't use it. The actual CA values are collected in pat.c:
117  /*
118  case SI::CaIdentifierDescriptorTag: {
119  SI::CaIdentifierDescriptor *cid = (SI::CaIdentifierDescriptor *)d;
120  if (channel) {
121  for (SI::Loop::Iterator it; cid->identifiers.hasNext(it); )
122  channel->SetCa(cid->identifiers.getNext(it));
123  }
124  }
125  break;
126  */
130  for (SI::Loop::Iterator it; nrd->serviceLoop.getNext(Service, it); ) {
132  if (!link && Setup.UpdateChannels >= 4) {
133  link = Channels.NewChannel(Channel(), "NVOD", "", "", Service.getOriginalNetworkId(), Service.getTransportStream(), Service.getServiceId());
134  patFilter->Trigger(Service.getServiceId());
135  }
136  if (link) {
137  if (!LinkChannels)
138  LinkChannels = new cLinkChannels;
139  LinkChannels->Add(new cLinkChannel(link));
140  }
141  }
142  }
143  break;
144  default: ;
145  }
146  delete d;
147  }
148  if (LinkChannels) {
149  if (channel)
150  channel->SetLinkChannels(LinkChannels);
151  else
152  delete LinkChannels;
153  }
154  }
155  if (sdt.getSectionNumber() == sdt.getLastSectionNumber()) {
156  if (Setup.UpdateChannels == 1 || Setup.UpdateChannels >= 3)
158  }
159  Channels.Unlock();
160 }
void SetId(int Nid, int Tid, int Sid, int Rid=0)
Definition: channels.c:233
StructureLoop< Service > serviceLoop
Definition: descriptor.h:281
cChannels Channels
Definition: channels.c:864
char * getText()
Definition: si.c:222
void Add(cListObject *Object, cListObject *After=NULL)
Definition: tools.c:2014
cPatFilter * patFilter
Definition: sdt.h:21
int getServiceType() const
Definition: descriptor.c:521
void MarkObsoleteChannels(int Source, int Nid, int Tid)
Definition: channels.c:1134
StructureLoop< Service > serviceLoop
Definition: section.h:143
const cChannel * Channel(void)
Returns the channel of the data delivered to this filter.
Definition: filter.c:99
int getServiceId() const
Definition: section.c:132
DescriptorTag getDescriptorTag() const
Definition: si.c:100
cMutex mutex
Definition: sdt.h:18
cSectionSyncer sectionSyncer
Definition: sdt.h:19
void Unlock(void)
Definition: thread.c:170
int getSectionNumber() const
Definition: si.c:88
void Trigger(int Sid=-1)
Definition: pat.c:316
bool Sync(uchar Version, int Number, int LastNumber)
Definition: filter.c:26
void Trigger(int Source)
Definition: sdt.c:34
cChannel * NewChannel(const cChannel *Transponder, const char *Name, const char *ShortName, const char *Provider, int Nid, int Tid, int Sid, int Rid=0)
Definition: channels.c:1115
void SetName(const char *Name, const char *ShortName, const char *Provider)
Definition: channels.c:261
int source
Definition: sdt.h:20
int Source(void)
Returns the source of the data delivered to this filter.
Definition: filter.c:89
cSetup Setup
Definition: config.c:373
DescriptorLoop serviceDescriptors
Definition: section.h:135
bool Lock(bool Write, int TimeoutMs=0)
Definition: thread.c:155
cChannel * GetByChannelID(tChannelID ChannelID, bool TryWithoutRid=false, bool TryWithoutPolarization=false)
Definition: channels.c:1023
bool CheckCRCAndParse()
Definition: si.c:65
int getOriginalNetworkId() const
Definition: section.c:128
virtual void SetStatus(bool On)
Turns this filter on or off, depending on the value of On.
Definition: filter.c:104
void SetLinkChannels(cLinkChannels *LinkChannels)
Definition: channels.c:481
Definition: pat.h:19
virtual void SetStatus(bool On)
Turns this filter on or off, depending on the value of On.
Definition: sdt.c:25
int getTransportStreamId() const
Definition: section.c:124
int getVersionNumber() const
Definition: si.c:84
virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
Processes the data delivered to this filter.
Definition: sdt.c:40
static bool IsCable(int Code)
Definition: sources.h:56
unsigned char u_char
Definition: headers.h:24
int getLastSectionNumber() const
Definition: si.c:92
int UpdateChannels
Definition: config.h:314
char * skipspace(const char *s)
Definition: tools.h:200
int Transponder(void)
Returns the transponder of the data delivered to this filter.
Definition: filter.c:94
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:137
char * compactspace(char *s)
Definition: tools.c:213
void Reset(void)
Definition: filter.c:20
void SetSeen(void)
Definition: channels.c:445
cSdtFilter(cPatFilter *PatFilter)
Definition: sdt.c:18
Descriptor * getNext(Iterator &it)
Definition: si.c:112
#define Utf8BufSize(s)
Definition: tools.h:133