1 /*
2  * Copyright (c) 2011-2014 - Mauro Carvalho Chehab
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation version 2.1 of the License.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16  * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
17  */
18 #ifndef _LIBSCAN_H
19 #define _LIBSCAN_H
20 
21 #include <stdint.h>
22 #include <linux/dvb/dmx.h>
23 #include <libdvbv5/descriptors.h>
24 #include <libdvbv5/dvb-sat.h>
25 
26 /**
27  * @file dvb-scan.h
28  * @ingroup frontend_scan
29  * @brief Provides interfaces to scan programs inside MPEG-TS digital TV streams.
30  * @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
31  * @author Mauro Carvalho Chehab
32  *
33  * @par Bug Report
34  * Please submit bug reports and patches to linux-media@vger.kernel.org
35  */
36 
37 /* According with ISO/IEC 13818-1:2007 */
38 
39 #define MAX_TABLE_SIZE 1024 * 1024
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 struct dvb_entry;
46 
47 /**
48  * @struct dvb_v5_descriptors_program
49  * @brief Associates PMT with PAT tables
50  * @ingroup frontend_scan
51  *
52  * @param pat_pgm	pointer for PAT descriptor
53  * @param pmt	pointer for PMT descriptor
54  */
55 struct dvb_v5_descriptors_program {
56 	struct dvb_table_pat_program *pat_pgm;
57 	struct dvb_table_pmt *pmt;
58 };
59 
60 /**
61  * @struct dvb_v5_descriptors
62  * @brief Contains the descriptors needed to scan the Service ID and other relevant info at a MPEG-TS Digital TV stream
63  * @ingroup frontend_scan
64  *
65  * @param delivery_system Delivery system of the parsed MPEG-TS
66  * @param entry		struct dvb_entry pointer (see dvb-file.h)
67  * @param pat		PAT table descriptor pointer (table ID 0x00).
68  * @param vct		VCT table descriptor pointer (either table ID 0xc8,
69  * 			for TVCT or table ID 0xc9, for CVCT)
70  * @param program	PAT/PMT array associated programs found at MPEG-TS
71  * @param num_program	Number of program entries at @ref program array.
72  * @param nit		NIT table descriptor pointer for table ID 0x40.
73  * @param sdt		SDT table descriptor pointer for table ID 0x42.
74  * @param other_nits	Contains an array of pointers to the other NIT
75  *			extension tables identified by table ID 0x41.
76  * @param num_other_nits Number of NIT tables at @ref other_nits array.
77  * @param other_sdts	Contains an array of pointers to the other NIT
78  *			extension tables identified by table ID 0x46.
79  * @param num_other_sdts Number of NIT tables at @ref other_sdts array.
80  *
81  * Those descriptors are filled by the scan routines when the tables are
82  * found. Otherwise, they're NULL.
83  *
84  * @note: Never alloc this struct yourself. This is meant to always be
85  * allocated via dvb_scan_alloc_handler_table() or via dvb_get_ts_tables().
86  */
87 struct dvb_v5_descriptors {
88 	uint32_t delivery_system;
89 
90 	struct dvb_entry *entry;
91 	unsigned num_entry;
92 
93 	struct dvb_table_pat *pat;
94 	struct atsc_table_vct *vct;
95 	struct dvb_v5_descriptors_program *program;
96 	struct dvb_table_nit *nit;
97 	struct dvb_table_sdt *sdt;
98 
99 	unsigned num_program;
100 
101 	struct dvb_table_nit **other_nits;
102 	unsigned num_other_nits;
103 
104 	struct dvb_table_sdt **other_sdts;
105 	unsigned num_other_sdts;
106 };
107 
108 /**
109  * @struct dvb_table_filter
110  * @brief Describes the PES filters used by DVB scan
111  * @ingroup frontend_scan
112  *
113  * @param tid		Table ID
114  * @param pid		Program ID
115  * @param ts_id		Table section ID (for multisession filtering). If no
116  *			specific table section is needed, -1 should be used
117  * @param table		pointer to a pointer for the table struct to be filled
118  * @param allow_section_gaps	Allow non-continuous section numbering
119  * @param priv		Internal structure used inside the DVB core. shouldn't
120  *			be touched externally.
121  */
122 struct dvb_table_filter {
123 	/* Input data */
124 	unsigned char tid;
125 	uint16_t pid;
126 	int ts_id;
127 	void **table;
128 
129 	int allow_section_gaps;
130 
131 	/*
132 	 * Private temp data used by dvb_read_sections().
133 	 * Should not be filled outside dvb-scan.c, as they'll be
134 	 * overrided
135 	 */
136 	void *priv;
137 };
138 /**
139  * @brief deallocates all data associated with a table filter
140  * @ingroup frontend_scan
141  *
142  * @param sect	table filter pointer
143  */
144 void dvb_table_filter_free(struct dvb_table_filter *sect);
145 
146 /**
147  * @brief read MPEG-TS tables that comes from a DTV card
148  * @ingroup frontend_scan
149  *
150  * @param parms		pointer to struct dvb_v5_fe_parms created when the
151  *			frontend is opened
152  * @param dmx_fd	an opened demux file descriptor
153  * @param tid		Table ID
154  * @param pid		Program ID
155  * @param table		pointer to a pointer for the table struct to be filled
156  * @param timeout	Limit, in seconds, to read a MPEG-TS table
157  *
158  * This function is used to read the DVB tables by specifying a table ID and
159  * a program ID. The libdvbv5 should have a parser for the descriptors of the
160  * table type that should be parsed.
161  * The table will be automatically allocated on success.
162  * The function will read on the specified demux and return when reading is
163  * done or an error has occurred. If table is not NULL after the call, it has
164  * to be freed with the apropriate free table function (even if an error has
165  * occurred).
166  *
167  * If the application wants to abort the read operation, it can change the
168  * value of parms->p.abort to 1.
169  *
170  * Returns 0 on success or a negative error code.
171  *
172  * Example usage:
173  * @code
174  * struct dvb_table_pat *pat;
175  * int r = dvb_read_section( parms, dmx_fd, DVB_TABLE_PAT, DVB_TABLE_PAT_PID,
176  *			    (void **) &pat, 5 );
177  * if (r < 0)
178  *	dvb_logerr("error reading PAT table");
179  * else {
180  *	// do something with pat
181  * }
182  * if (pat)
183  *	dvb_table_pat_free( pat );
184  * @endcode
185  */
186 int dvb_read_section(struct dvb_v5_fe_parms *parms, int dmx_fd,
187 		     unsigned char tid, uint16_t pid, void **table,
188 		     unsigned timeout);
189 
190 /**
191  * @brief read MPEG-TS tables that comes from a DTV card
192  *				with an specific table section ID
193  * @ingroup frontend_scan
194  *
195  * @param parms		pointer to struct dvb_v5_fe_parms created when the
196  * 			frontend is opened
197  * @param dmx_fd	an opened demux file descriptor
198  * @param tid		Table ID
199  * @param pid		Program ID
200  * @param ts_id		Table section ID (for multisession filtering). If no
201  *			specific table section is needed, -1 should be used
202  * @param table		pointer to a pointer for the table struct to be filled
203  * @param timeout	limit, in seconds, to read a MPEG-TS table
204  *
205  * This is a variant of dvb_read_section() that also seeks for an specific
206  * table section ID given by ts_id.
207  */
208  int dvb_read_section_with_id(struct dvb_v5_fe_parms *parms, int dmx_fd,
209 			      unsigned char tid, uint16_t pid, int ts_id,
210 			      void **table, unsigned timeout);
211 
212 /**
213  * @brief read MPEG-TS tables that comes from a DTV card
214  * @ingroup frontend_scan
215  *
216  * @param parms		pointer to struct dvb_v5_fe_parms created when the
217  *			frontend is opened
218  * @param dmx_fd	an opened demux file descriptor
219  * @param sect		section filter pointer
220  * @param timeout	limit, in seconds, to read a MPEG-TS table
221  *
222  * This is a variant of dvb_read_section() that uses a struct dvb_table_filter
223  * to specify the filter to use.
224  */
225 int dvb_read_sections(struct dvb_v5_fe_parms *parms, int dmx_fd,
226 			     struct dvb_table_filter *sect,
227 			     unsigned timeout);
228 
229 /**
230  * @brief allocates a struct dvb_v5_descriptors
231  * @ingroup frontend_scan
232  *
233  * @param delivery_system	Delivery system to be used on the table
234  *
235  * At success, returns a pointer. NULL otherwise.
236  */
237 struct dvb_v5_descriptors *dvb_scan_alloc_handler_table(uint32_t delivery_system);
238 
239 /**
240  * @brief frees a struct dvb_v5_descriptors
241  * @ingroup frontend_scan
242  *
243  * @param dvb_scan_handler	pointer to the struct to be freed.
244  */
245 void dvb_scan_free_handler_table(struct dvb_v5_descriptors *dvb_scan_handler);
246 
247 /**
248  * @brief Scans a DVB stream, looking for the tables needed to
249  *			 identify the programs inside a MPEG-TS
250  * @ingroup frontend_scan
251  *
252  * @param parms			pointer to struct dvb_v5_fe_parms created when
253  *				the frontend is opened
254  * @param dmx_fd		an opened demux file descriptor
255  * @param delivery_system	delivery system to be scanned
256  * @param other_nit		use alternate table IDs for NIT and other tables
257  * @param timeout_multiply	improves the timeout for each table reception
258  * 				by using a value that will multiply the wait
259  *				time.
260  *
261  * Given an opened frontend and demux, this function seeks for all programs
262  * available at the transport stream, and parses the following tables:
263  * PAT, PMT, NIT, SDT (and VCT, if the delivery system is ATSC).
264  *
265  * On sucess, it returns a pointer to a struct dvb_v5_descriptors, that can
266  * either be used to tune into a service or to be stored inside a file.
267  */
268 struct dvb_v5_descriptors *dvb_get_ts_tables(struct dvb_v5_fe_parms *parms, int dmx_fd,
269 					  uint32_t delivery_system,
270 					  unsigned other_nit,
271 					  unsigned timeout_multiply);
272 
273 /**
274  * @brief frees a struct dvb_v5_descriptors
275  * @ingroup frontend_scan
276  *
277  * @param dvb_desc	pointed to the structure to be freed.
278  *
279  * This function recursively frees everything that is allocated by
280  * dvb_get_ts_tables() and stored at dvb_desc, including dvb_desc itself.
281  */
282 void dvb_free_ts_tables(struct dvb_v5_descriptors *dvb_desc);
283 
284 /**
285  * @brief Callback for the application to show the frontend status
286  * @ingroup frontend_scan
287  *
288  * @param args		a pointer, opaque to libdvbv5, to be used by the
289  *			application if needed.
290  * @param parms		pointer to struct dvb_v5_fe_parms created when the
291  *			frontend is opened
292  */
293 typedef int (check_frontend_t)(void *args, struct dvb_v5_fe_parms *parms);
294 
295 /**
296  * @brief Scans a DVB dvb_add_scaned_transponder
297  * @ingroup frontend_scan
298  *
299  * @param parms		pointer to struct dvb_v5_fe_parms created when the
300  *			frontend is opened
301  * @param entry		DVB file entry that corresponds to a transponder to be
302  * 			tuned
303  * @param dmx_fd		an opened demux file descriptor
304  * @param check_frontend	a pointer to a function that will show the frontend
305  *			status while tuning into a transponder
306  * @param args		a pointer, opaque to libdvbv5, that will be used when
307  *			calling check_frontend. It should contain any parameters
308  *			that could be needed by check_frontend.
309  * @param other_nit		Use alternate table IDs for NIT and other tables
310  * @param timeout_multiply	Improves the timeout for each table reception, by
311  *
312  * This is the function that applications should use when doing a transponders
313  * scan. It does everything needed to fill the entries with DVB programs
314  * (virtual channels) and detect the PIDs associated with them.
315  *
316  * A typical usage is to after open a channel file, open a dmx_fd and open
317  * a frontend. Then, seek for the MPEG tables on all the transponder
318  * frequencies with:
319  *
320  * @code
321  * for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) {
322  *	struct dvb_v5_descriptors *dvb_scan_handler = NULL;
323  *
324  *	dvb_scan_handler = dvb_scan_transponder(parms, entry, dmx_fd,
325  *						&check_frontend, args,
326  *						args->other_nit,
327  *						args->timeout_multiply);
328  *	if (parms->abort) {
329  *		dvb_scan_free_handler_table(dvb_scan_handler);
330  *		break;
331  *	}
332  *	if (dvb_scan_handler) {
333  *		dvb_store_channel(&dvb_file_new, parms, dvb_scan_handler,
334  *				  args->get_detected, args->get_nit);
335  *		dvb_scan_free_handler_table(dvb_scan_handler);
336  * 	}
337  * }
338  * @endcode
339  */
340 struct dvb_v5_descriptors *dvb_scan_transponder(struct dvb_v5_fe_parms *parms,
341 						struct dvb_entry *entry,
342 						int dmx_fd,
343 						check_frontend_t *check_frontend,
344 						void *args,
345 						unsigned other_nit,
346 						unsigned timeout_multiply);
347 
348 
349 /**
350  * @brief Add new transponders to a dvb_file
351  * @ingroup frontend_scan
352  *
353  * @param parms		pointer to struct dvb_v5_fe_parms created when the
354  *			frontend is opened
355  * @param dvb_scan_handler	pointer to a struct dvb_v5_descriptors containing
356  *			scaned MPEG-TS
357  * @param first_entry	first entry of a DVB file struct
358  * @param entry		current entry on a DVB file struct
359  *
360  * When the NIT table is parsed, some new transponders could be described
361  * inside. This function adds new entries to a dvb_file struct, pointing
362  * to those new transponders. It is used inside the scan loop, as shown at
363  * the dvb_scan_transponder(), to add new channels.
364  *
365  * Example:
366  * @code
367  * for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) {
368  *	struct dvb_v5_descriptors *dvb_scan_handler = NULL;
369  *
370  *	dvb_scan_handler = dvb_scan_transponder(parms, entry, dmx_fd,
371  *						&check_frontend, args,
372  *						args->other_nit,
373  *						args->timeout_multiply);
374  *	if (parms->abort) {
375  *		dvb_scan_free_handler_table(dvb_scan_handler);
376  *		break;
377  *	}
378  *	if (dvb_scan_handler) {
379  *		dvb_store_channel(&dvb_file_new, parms, dvb_scan_handler,
380  *				  args->get_detected, args->get_nit);
381  *		dvb_scan_free_handler_table(dvb_scan_handler);
382  *
383  *		dvb_add_scaned_transponders(parms, dvb_scan_handler,
384  *					    dvb_file->first_entry, entry);
385  *
386  *		dvb_scan_free_handler_table(dvb_scan_handler);
387  * 	}
388  * }
389  * @endcode
390  */
391 void dvb_add_scaned_transponders(struct dvb_v5_fe_parms *parms,
392 				 struct dvb_v5_descriptors *dvb_scan_handler,
393 				 struct dvb_entry *first_entry,
394 				 struct dvb_entry *entry);
395 
396 #ifndef _DOXYGEN
397 /*
398  * Some ancillary functions used internally inside the library, used to
399  * identify duplicated transport streams and add new found transponder entries
400  */
401 int dvb_estimate_freq_shift(struct dvb_v5_fe_parms *parms);
402 
403 int dvb_new_freq_is_needed(struct dvb_entry *entry, struct dvb_entry *last_entry,
404 			   uint32_t freq, enum dvb_sat_polarization pol, int shift);
405 
406 struct dvb_entry *dvb_scan_add_entry(struct dvb_v5_fe_parms *parms,
407 				     struct dvb_entry *first_entry,
408 			             struct dvb_entry *entry,
409 			             uint32_t freq, uint32_t shift,
410 			             enum dvb_sat_polarization pol);
411 
412 int dvb_new_entry_is_needed(struct dvb_entry *entry,
413 			    struct dvb_entry *last_entry,
414 			    uint32_t freq, int shift,
415 			    enum dvb_sat_polarization pol, uint32_t stream_id);
416 
417 struct dvb_entry *dvb_scan_add_entry_ex(struct dvb_v5_fe_parms *parms,
418 					struct dvb_entry *first_entry,
419 					struct dvb_entry *entry,
420 					uint32_t freq, uint32_t shift,
421 					enum dvb_sat_polarization pol,
422 					uint32_t stream_id);
423 
424 void dvb_update_transponders(struct dvb_v5_fe_parms *parms,
425 			     struct dvb_v5_descriptors *dvb_scan_handler,
426 			     struct dvb_entry *first_entry,
427 			     struct dvb_entry *entry);
428 #endif
429 
430 #ifdef __cplusplus
431 }
432 #endif
433 
434 #endif
435