vdr
2.0.2
Main Page
Namespaces
Classes
Files
File List
File Members
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 2.5 2010/05/16 14:23:21 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
18
cSdtFilter::cSdtFilter
(
cPatFilter
*PatFilter)
19
{
20
patFilter
= PatFilter;
21
Set
(0x11, 0x42);
// SDT
22
}
23
24
void
cSdtFilter::SetStatus
(
bool
On)
25
{
26
cFilter::SetStatus
(On);
27
sectionSyncer
.
Reset
();
28
}
29
30
void
cSdtFilter::Process
(u_short Pid,
u_char
Tid,
const
u_char
*Data,
int
Length)
31
{
32
if
(!(
Source
() &&
Transponder
()))
33
return
;
34
SI::SDT
sdt(Data,
false
);
35
if
(!sdt.
CheckCRCAndParse
())
36
return
;
37
if
(!
sectionSyncer
.
Sync
(sdt.
getVersionNumber
(), sdt.
getSectionNumber
(), sdt.
getLastSectionNumber
()))
38
return
;
39
if
(!
Channels
.
Lock
(
true
, 10))
40
return
;
41
SI::SDT::Service
SiSdtService;
42
for
(
SI::Loop::Iterator
it; sdt.
serviceLoop
.getNext(SiSdtService, it); ) {
43
cChannel
*channel =
Channels
.
GetByChannelID
(
tChannelID
(
Source
(), sdt.
getOriginalNetworkId
(), sdt.
getTransportStreamId
(), SiSdtService.
getServiceId
()));
44
if
(!channel)
45
channel =
Channels
.
GetByChannelID
(
tChannelID
(
Source
(), 0,
Transponder
(), SiSdtService.
getServiceId
()));
46
47
cLinkChannels
*LinkChannels = NULL;
48
SI::Descriptor
*d;
49
for
(
SI::Loop::Iterator
it2; (d = SiSdtService.
serviceDescriptors
.
getNext
(it2)); ) {
50
switch
(d->
getDescriptorTag
()) {
51
case
SI::ServiceDescriptorTag
: {
52
SI::ServiceDescriptor
*sd = (
SI::ServiceDescriptor
*)d;
53
switch
(sd->
getServiceType
()) {
54
case
0x01:
// digital television service
55
case
0x02:
// digital radio sound service
56
case
0x04:
// NVOD reference service
57
case
0x05:
// NVOD time-shifted service
58
case
0x16:
// digital SD television service
59
case
0x19:
// digital HD television service
60
{
61
char
NameBuf[
Utf8BufSize
(1024)];
62
char
ShortNameBuf[
Utf8BufSize
(1024)];
63
char
ProviderNameBuf[
Utf8BufSize
(1024)];
64
sd->
serviceName
.
getText
(NameBuf, ShortNameBuf,
sizeof
(NameBuf),
sizeof
(ShortNameBuf));
65
char
*pn =
compactspace
(NameBuf);
66
char
*ps =
compactspace
(ShortNameBuf);
67
if
(!*ps &&
cSource::IsCable
(
Source
())) {
68
// Some cable providers don't mark short channel names according to the
69
// standard, but rather go their own way and use "name>short name":
70
char
*p = strchr(pn,
'>'
);
// fix for UPC Wien
71
if
(p && p > pn) {
72
*p++ = 0;
73
strcpy(ShortNameBuf,
skipspace
(p));
74
}
75
}
76
// Avoid ',' in short name (would cause trouble in channels.conf):
77
for
(
char
*p = ShortNameBuf; *p; p++) {
78
if
(*p ==
','
)
79
*p =
'.'
;
80
}
81
sd->
providerName
.
getText
(ProviderNameBuf,
sizeof
(ProviderNameBuf));
82
char
*pp =
compactspace
(ProviderNameBuf);
83
if
(channel) {
84
channel->
SetId
(sdt.
getOriginalNetworkId
(), sdt.
getTransportStreamId
(), SiSdtService.
getServiceId
());
85
if
(
Setup
.
UpdateChannels
== 1 ||
Setup
.
UpdateChannels
>= 3)
86
channel->
SetName
(pn, ps, pp);
87
// Using SiSdtService.getFreeCaMode() is no good, because some
88
// tv stations set this flag even for non-encrypted channels :-(
89
// The special value 0xFFFF was supposed to mean "unknown encryption"
90
// and would have been overwritten with real CA values later:
91
// channel->SetCa(SiSdtService.getFreeCaMode() ? 0xFFFF : 0);
92
}
93
else
if
(*pn &&
Setup
.
UpdateChannels
>= 4) {
94
channel =
Channels
.
NewChannel
(
Channel
(), pn, ps, pp, sdt.
getOriginalNetworkId
(), sdt.
getTransportStreamId
(), SiSdtService.
getServiceId
());
95
patFilter
->
Trigger
();
96
}
97
}
98
default
: ;
99
}
100
}
101
break
;
102
// Using the CaIdentifierDescriptor is no good, because some tv stations
103
// just don't use it. The actual CA values are collected in pat.c:
104
/*
105
case SI::CaIdentifierDescriptorTag: {
106
SI::CaIdentifierDescriptor *cid = (SI::CaIdentifierDescriptor *)d;
107
if (channel) {
108
for (SI::Loop::Iterator it; cid->identifiers.hasNext(it); )
109
channel->SetCa(cid->identifiers.getNext(it));
110
}
111
}
112
break;
113
*/
114
case
SI::NVODReferenceDescriptorTag
: {
115
SI::NVODReferenceDescriptor
*nrd = (
SI::NVODReferenceDescriptor
*)d;
116
SI::NVODReferenceDescriptor::Service
Service;
117
for
(
SI::Loop::Iterator
it; nrd->
serviceLoop
.getNext(Service, it); ) {
118
cChannel
*link =
Channels
.
GetByChannelID
(
tChannelID
(
Source
(), Service.
getOriginalNetworkId
(), Service.
getTransportStream
(), Service.
getServiceId
()));
119
if
(!link &&
Setup
.
UpdateChannels
>= 4) {
120
link =
Channels
.
NewChannel
(
Channel
(),
"NVOD"
,
""
,
""
, Service.
getOriginalNetworkId
(), Service.
getTransportStream
(), Service.
getServiceId
());
121
patFilter
->
Trigger
();
122
}
123
if
(link) {
124
if
(!LinkChannels)
125
LinkChannels =
new
cLinkChannels
;
126
LinkChannels->
Add
(
new
cLinkChannel
(link));
127
}
128
}
129
}
130
break
;
131
default
: ;
132
}
133
delete
d;
134
}
135
if
(LinkChannels) {
136
if
(channel)
137
channel->
SetLinkChannels
(LinkChannels);
138
else
139
delete
LinkChannels;
140
}
141
}
142
Channels
.
Unlock
();
143
}
144
Generated by
1.8.3.1