1 | DVBAPI
|
---|
2 | ======
|
---|
3 | DVB API stands for Linux DVB Application Programming Interface, so in short it is a set of API calls which is used on
|
---|
4 | linux to handle DVB hardware. From the OSCam point of view the most interesting part is to be able to provide all data
|
---|
5 | necessary for channel decryption. The OSCam DVBAPI module was written to handle this work.
|
---|
6 |
|
---|
7 | Architecture
|
---|
8 | ============
|
---|
9 | Basically to be able to decrypt a channel a DVBAPI module needs the following information:
|
---|
10 | - PMT table (information from TV receiver software about the requested channel for livetv/recording and the ECM PIDs)
|
---|
11 | - CAT table (needed to get information about EMM type and PIDs)
|
---|
12 | - Filtered ECM/EMM data
|
---|
13 |
|
---|
14 | As a result if OSCam is able to decrypt a service, an information with the decrypted PIDs (audio, video, etc)
|
---|
15 | and CW (keys) are sent back to the TV receiver software or a CAM device.
|
---|
16 |
|
---|
17 | History
|
---|
18 | =======
|
---|
19 | The first and "standard" use case is probably the Enigma. OSCam is creating a /tmp/camd.socket. Enigma is sending the
|
---|
20 | PMT data to this socket and as a result OSCam is opening the necessary DVB demux devices (eg /dev/dvb/adapter0/demux0)
|
---|
21 | and is filtering for ECM, CAT and EMM data. It is then parsed by the OSCam dvbapi module and as a result the CA_SET_PID
|
---|
22 | and CA_SET_DESCR ioctl calls was done leading to proper decryption. It was all working on same hardware and the same DVB
|
---|
23 | devices was used. This kind of usage was mainly for linux STB.
|
---|
24 |
|
---|
25 | Next step was the generic PC support. It was extending the dvbapi module to be able to send PIDs and keys back to
|
---|
26 | TV software (firstly via specially created UDP socket, later via the same /tmp/camd.socket).
|
---|
27 | The TV software was able to use this information in software decrypting (DeCSA).
|
---|
28 |
|
---|
29 | After some time the OpenPLi team created a new CaPMT interface, which was then implemented in OSCam (as pmt_mode=6).
|
---|
30 | It is described here: http://wiki.openpli.org/caPMT
|
---|
31 | The main feature was reverting the roles: the OSCam act as a client and connects to /tmp/.listen.camd.socket created by
|
---|
32 | Enigma. This way multiple Software CAMs could be running and connecting to Enigma's .listen.camd.socket.
|
---|
33 | The other important improvement in this mode (also implemented in OSCam) was the ability to handle extra CA_PMT list
|
---|
34 | managements. This allows to use one socket connection to handle more then one channel at a time (before a client
|
---|
35 | has to manage single connection to /tmp/camd.socket per subscribed channel).
|
---|
36 |
|
---|
37 | As the .listen.camd.socket mode makes less sense on generic PC platform (the OSCam is still server, while the client
|
---|
38 | could be any PC software used), the second feature which allows handling multiple channels on single socket connection
|
---|
39 | was extended to cover other modes (not only pmt_mode=6) in OSCam.
|
---|
40 |
|
---|
41 | Network mode
|
---|
42 | ============
|
---|
43 | The last feature that was added was a network mode. The change was made to be able to connect to an OSCam which
|
---|
44 | is not running on the same machine where the TV receiver software (and a DVB hardware) is running.
|
---|
45 |
|
---|
46 | Why not use a dedicated protocols like newcamd/camd in such cases?
|
---|
47 | - to have ECM/EMM handling in OSCam, where it belongs. It is better maintained and fixes comes in quicker.
|
---|
48 | - OSCam known what readers it has so it could do a load balance/filtering/priorities etc.
|
---|
49 |
|
---|
50 | As a result, instead of /tmp/camd.socket (which could be used only on the same machine) a listening_socket parameter
|
---|
51 | was added. So the unix domain socket switched to a full-featured TCP socket which can be connected from any network
|
---|
52 | client.
|
---|
53 |
|
---|
54 | As a result besides CA_SET_PID and CA_SET_DESCR a new calls was passed to socket: DMX_SET_FILTER and DMX_STOP.
|
---|
55 | The TV receiver software has to filter the demux itself (according to the above new calls) and send the results like
|
---|
56 | ECM/EMM/CAT data back to OSCam using the same connection.
|
---|
57 | Because the OSCam was only aware of PMT data on the socket, a new DVBAPI_FILTER_DATA command (0xffff0000) was added,
|
---|
58 | to be able to handle client data from filters.
|
---|
59 |
|
---|
60 | This way all the communication between the TV receiver software and the OSCam could be finally done using one single
|
---|
61 | TCP connection.
|
---|
62 | Moreover: the demux is only accessed by single TV receiver software process, which, from the architecture point of view
|
---|
63 | is definitely a better solution.
|
---|
64 |
|
---|
65 | New protocol description (sockets commands)
|
---|
66 | ===========================================
|
---|
67 | As there are more and more dvbapi clients, some problems starts to appear. First of all there was some kind of
|
---|
68 | mess because the OSCam network mode doesn't take into account the endianness in first form of network protocol.
|
---|
69 | Secondly it was not consistant (eg PID was always send as little endian in DMX_STOP, while the rest depend on OSCam
|
---|
70 | host architecture). Finally the standard API ioctl codes for: CA_SET_PID, CA_SET_DESCR, DMX_SET_FILTER and DMX_STOP
|
---|
71 | differences. These codes are composed by a macro which takes into account the length of the associated structures and
|
---|
72 | on some hardware the first bits of the MSB was different. So the clients had to do some strange workarounds with
|
---|
73 | the MSB byte:
|
---|
74 | fix 0x80 -> 0x40 and 0x20 -> 0x00 when needed
|
---|
75 |
|
---|
76 | Finally, the first byte sent to client was an adapter index, which was not always needed in all commands.
|
---|
77 | Now the first 4-byte integer is unique operation code, so a client will know what is the request type and could read
|
---|
78 | the rest of data according to the following description (and field sizes).
|
---|
79 |
|
---|
80 | To address all above problems and additionally makes smooth transitions when updating the protocol in the future
|
---|
81 | there was added some kind of "handshake" for clients. All new implementations should use it.
|
---|
82 | Currently the old and new implementations should work fine, but in the future a network client which will not
|
---|
83 | introduce itself (thus not providing it's supported protocol version) may be dropped/ignored by OSCam.
|
---|
84 |
|
---|
85 | All multibyte integers (if not specified otherwise) should be send using network byte order, so your client
|
---|
86 | should use ntoh() functions when receiving - oscam is doing hton() before send) and vice versa.
|
---|
87 |
|
---|
88 | Just right after a client connects to an OSCam network socket, it should send a greeting in format:
|
---|
89 |
|
---|
90 | -= DVBAPI_CLIENT_INFO =-
|
---|
91 | -----------------------------------------------------------------------
|
---|
92 | type/size description
|
---|
93 | -----------------------------------------------------------------------
|
---|
94 | uint32_t operation code -> DVBAPI_CLIENT_INFO
|
---|
95 | uint16_t protocol version supported by client
|
---|
96 | uint8_t size of followed string (255 bytes max)
|
---|
97 | string name and version of the client (string length should be max 255 bytes)
|
---|
98 |
|
---|
99 | The server will respond with similar reply:
|
---|
100 |
|
---|
101 | -= DVBAPI_SERVER_INFO =-
|
---|
102 | -----------------------------------------------------------------------
|
---|
103 | type/size description
|
---|
104 | -----------------------------------------------------------------------
|
---|
105 | uint32_t operation code -> DVBAPI_SERVER_INFO
|
---|
106 | uint16_t protocol version supported by OSCam
|
---|
107 | uint8_t size of followed string (255 bytes max)
|
---|
108 | string OSCam version and build (string length should be max 255 bytes)
|
---|
109 |
|
---|
110 | Next, when a client want to start a channel it should send the PMT data (program map table).
|
---|
111 | The PMT data structure starts with constant AOT_CA_PMT (0x9F8032).
|
---|
112 | The data format of the CA_PMT is described in chapter 8.4.3.4 (page 30) of the EN 50221 PDF (european standard).
|
---|
113 |
|
---|
114 | Please note that OSCam is expecting the own descriptor injected in the data.
|
---|
115 | Look into getDemuxOptions() OSCam function for the reference.
|
---|
116 |
|
---|
117 |
|
---|
118 | After OSCam parses the PMT data, it is starting to filtering ECM PIDs, so it send the following request to the client:
|
---|
119 |
|
---|
120 | -= DVBAPI_DMX_SET_FILTER =-
|
---|
121 | -----------------------------------------------------------------------
|
---|
122 | type/size description
|
---|
123 | -----------------------------------------------------------------------
|
---|
124 | uint32_t operation code -> DVBAPI_DMX_SET_FILTER
|
---|
125 | uint8_t adapter index
|
---|
126 | uint8_t demux index
|
---|
127 | uint8_t filter number
|
---|
128 | *** The following data are the fields from the dmx_sct_filter_params structure (added separately to avoid padding problems)
|
---|
129 | uint16_t pid
|
---|
130 | uchar[16] filter data (filter.filter)
|
---|
131 | uchar[16] filter mask (filter.mask)
|
---|
132 | uchar[16] filter mode (filter.mode)
|
---|
133 | uint32_t timeout
|
---|
134 | uint32_t flags
|
---|
135 |
|
---|
136 | The client should then filter the data and pass it back to the OSCam using the following frame:
|
---|
137 |
|
---|
138 | -= DVBAPI_FILTER_DATA =-
|
---|
139 | -----------------------------------------------------------------------
|
---|
140 | type/size description
|
---|
141 | -----------------------------------------------------------------------
|
---|
142 | uint32_t operation code -> DVBAPI_FILTER_DATA
|
---|
143 | uint8_t demux index
|
---|
144 | uint8_t filter number
|
---|
145 | uchar[] filtered data from demux
|
---|
146 |
|
---|
147 | When OSCam is able to decrypt a channel it firstly send the list of PIDs associated with the descrambler index using this packet:
|
---|
148 |
|
---|
149 | -= DVBAPI_CA_SET_PID =-
|
---|
150 | -----------------------------------------------------------------------
|
---|
151 | type/size description
|
---|
152 | -----------------------------------------------------------------------
|
---|
153 | uint32_t operation code -> DVBAPI_CA_SET_PID
|
---|
154 | uint8_t adapter index
|
---|
155 | ca_pid_t 8-byte ca_pid_t structure (the pid and index fields are in network byte order)
|
---|
156 |
|
---|
157 | And also send the CW for decryption:
|
---|
158 |
|
---|
159 | -= DVBAPI_CA_SET_DESCR =-
|
---|
160 | -----------------------------------------------------------------------
|
---|
161 | type/size description
|
---|
162 | -----------------------------------------------------------------------
|
---|
163 | uint32_t operation code -> DVBAPI_CA_SET_DESCR
|
---|
164 | uint8_t adapter index
|
---|
165 | ca_descr_t 16-byte ca_descr_t structure (the index and parity fields are in network byte order)
|
---|
166 |
|
---|
167 | When OSCam want to inform client about stopping a filter it send the following packet:
|
---|
168 |
|
---|
169 | -= DVBAPI_DMX_STOP =-
|
---|
170 | -----------------------------------------------------------------------
|
---|
171 | type/size description
|
---|
172 | -----------------------------------------------------------------------
|
---|
173 | uint32_t operation code -> DVBAPI_DMX_STOP
|
---|
174 | uint8_t adapter index
|
---|
175 | uint8_t demux index
|
---|
176 | uint8_t filter number
|
---|
177 | uint16_t PID to stop filtering
|
---|
178 |
|
---|
179 | When the client closes connection, all associated channels are stopped in the OSCam.
|
---|
180 |
|
---|
181 | Alternatively when there is a need to stop decoding channels, while having the connection still open you can send a special
|
---|
182 | '3f' packed to OSCam. To stop decoding specified demux the following CA_PMT data should be sent to OSCam:
|
---|
183 | 9F 80 3f 04 83 02 00 <demux index>
|
---|
184 | If <demux index> is 0xff, then it is parsed as a wildcard and all demuxers associated with the connection are stopped.
|
---|