• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2016 - 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 
19 #include <libudev.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <locale.h>
23 #include <unistd.h>
24 #include <string.h>
25 
26 #include "dvb-fe-priv.h"
27 #include "dvb-dev-priv.h"
28 
29 #ifdef ENABLE_NLS
30 # include "gettext.h"
31 # include <libintl.h>
32 # define _(string) dgettext(LIBDVBV5_DOMAIN, string)
33 #else
34 # define _(string) string
35 #endif
36 
37 const char * const dev_type_names[] = {
38         "frontend", "demux", "dvr", "net", "ca", "sec", "video", "audio"
39 };
40 
41 const unsigned int
42 dev_type_names_size = sizeof(dev_type_names)/sizeof(*dev_type_names);
43 
free_dvb_dev(struct dvb_dev_list * dvb_dev)44 void free_dvb_dev(struct dvb_dev_list *dvb_dev)
45 {
46 	if (dvb_dev->path)
47 		free(dvb_dev->path);
48 	if (dvb_dev->syspath)
49 		free(dvb_dev->syspath);
50 	if (dvb_dev->sysname)
51 		free(dvb_dev->sysname);
52 	if (dvb_dev->bus_addr)
53 		free(dvb_dev->bus_addr);
54 	if (dvb_dev->bus_id)
55 		free(dvb_dev->bus_id);
56 	if (dvb_dev->manufacturer)
57 		free(dvb_dev->manufacturer);
58 	if (dvb_dev->product)
59 		free(dvb_dev->product);
60 	if (dvb_dev->serial)
61 		free(dvb_dev->serial);
62 }
63 
dvb_dev_alloc(void)64 struct dvb_device *dvb_dev_alloc(void)
65 {
66 	struct dvb_device_priv *dvb;
67 	struct dvb_v5_fe_parms_priv *parms;
68 
69 	dvb = calloc(1, sizeof(struct dvb_device_priv));
70 	if (!dvb)
71 		return NULL;
72 
73 	dvb->d.fe_parms = dvb_fe_dummy();
74 	if (!dvb->d.fe_parms) {
75 		dvb_dev_free(&dvb->d);
76 		return NULL;
77 	}
78 	parms = (void *)dvb->d.fe_parms;
79 	parms->dvb = dvb;
80 
81 	/* Initialize it to use the local DVB devices */
82 	dvb_dev_local_init(dvb);
83 
84 	return &dvb->d;
85 }
86 
dvb_dev_free_devices(struct dvb_device_priv * dvb)87 void dvb_dev_free_devices(struct dvb_device_priv *dvb)
88 {
89 	int i;
90 
91 	for (i = 0; i < dvb->d.num_devices; i++)
92 		free_dvb_dev(&dvb->d.devices[i]);
93 	free(dvb->d.devices);
94 
95 	dvb->d.devices = NULL;
96 	dvb->d.num_devices = 0;
97 }
98 
dvb_dev_free(struct dvb_device * d)99 void dvb_dev_free(struct dvb_device *d)
100 {
101 	struct dvb_device_priv *dvb = (void *)d;
102 	struct dvb_open_descriptor *cur, *next;
103 	struct dvb_dev_ops *ops = &dvb->ops;
104 
105 	/* Close all devices */
106 	cur = dvb->open_list.next;
107 	while (cur) {
108 		next = cur->next;
109 		dvb_dev_close(cur);
110 		cur = next;
111 	}
112 
113 	/* Call an implementation-specific free method, if defined */
114 	if (ops->free)
115 		ops->free(dvb);
116 
117 	dvb_fe_close(dvb->d.fe_parms);
118 
119 	dvb_dev_free_devices(dvb);
120 
121 	free(dvb);
122 }
123 
dvb_dev_dump_device(char * msg,struct dvb_v5_fe_parms_priv * parms,struct dvb_dev_list * dev)124 void dvb_dev_dump_device(char *msg,
125 			struct dvb_v5_fe_parms_priv *parms,
126 			struct dvb_dev_list *dev)
127 {
128 	if (parms->p.verbose < 2)
129 		return;
130 
131 	dvb_log(msg, dev_type_names[dev->dvb_type], dev->sysname);
132 
133 	if (dev->path)
134 		dvb_log(_("  path: %s"), dev->path);
135 	if (dev->syspath)
136 		dvb_log(_("  sysfs path: %s"), dev->syspath);
137 	if (dev->bus_addr)
138 		dvb_log(_("  bus addr: %s"), dev->bus_addr);
139 	if (dev->bus_id)
140 		dvb_log(_("  bus ID: %s"), dev->bus_id);
141 	if (dev->manufacturer)
142 		dvb_log(_("  manufacturer: %s"), dev->manufacturer);
143 	if (dev->product)
144 		dvb_log(_("  product: %s"), dev->product);
145 	if (dev->serial)
146 		dvb_log(_("  serial: %s"), dev->serial);
147 }
148 
dvb_dev_seek_by_adapter(struct dvb_device * d,unsigned int adapter,unsigned int num,enum dvb_dev_type type)149 struct dvb_dev_list *dvb_dev_seek_by_adapter(struct dvb_device *d,
150 					     unsigned int adapter,
151 					     unsigned int num,
152 					     enum dvb_dev_type type)
153 {
154 	struct dvb_device_priv *dvb = (void *)d;
155 	struct dvb_dev_ops *ops = &dvb->ops;
156 
157 	if (!ops->seek_by_adapter)
158 		return NULL;
159 
160 	return ops->seek_by_adapter(dvb, adapter, num, type);
161 }
162 
dvb_dev_set_logpriv(struct dvb_device * dvb,unsigned verbose,dvb_logfunc_priv logfunc_priv,void * logpriv)163 void dvb_dev_set_logpriv(struct dvb_device *dvb, unsigned verbose,
164 		     dvb_logfunc_priv logfunc_priv, void *logpriv)
165 {
166 	struct dvb_v5_fe_parms_priv *parms = (void *)dvb->fe_parms;
167 
168 	/* FIXME: how to get remote logs and set verbosity? */
169 	parms->p.verbose = verbose;
170 	parms->logpriv = logpriv;
171 
172 	if (logfunc_priv != NULL)
173 			parms->logfunc_priv = logfunc_priv;
174 }
175 
dvb_dev_set_log(struct dvb_device * dvb,unsigned verbose,dvb_logfunc logfunc)176 void dvb_dev_set_log(struct dvb_device *dvb, unsigned verbose,
177 		     dvb_logfunc logfunc)
178 {
179 	struct dvb_v5_fe_parms_priv *parms = (void *)dvb->fe_parms;
180 
181 	/* FIXME: how to get remote logs and set verbosity? */
182 	parms->p.verbose = verbose;
183 
184 	if (logfunc != NULL)
185 			parms->p.logfunc = logfunc;
186 }
187 
dvb_dev_find(struct dvb_device * d,dvb_dev_change_t handler,void * user_priv)188 int dvb_dev_find(struct dvb_device *d, dvb_dev_change_t handler, void *user_priv)
189 {
190 	struct dvb_device_priv *dvb = (void *)d;
191 	struct dvb_dev_ops *ops = &dvb->ops;
192 
193 	if (!ops->find)
194 		return -1;
195 
196 	return ops->find(dvb, handler, user_priv);
197 }
198 
dvb_dev_stop_monitor(struct dvb_device * d)199 void dvb_dev_stop_monitor(struct dvb_device *d)
200 {
201 	struct dvb_device_priv *dvb = (void *)d;
202 	struct dvb_dev_ops *ops = &dvb->ops;
203 
204 	if (ops->stop_monitor)
205 		ops->stop_monitor(dvb);
206 }
207 
dvb_get_dev_info(struct dvb_device * d,const char * sysname)208 struct dvb_dev_list *dvb_get_dev_info(struct dvb_device *d,
209 				      const char *sysname)
210 {
211 	struct dvb_device_priv *dvb = (void *)d;
212 	struct dvb_dev_ops *ops = &dvb->ops;
213 
214 	if (!ops->get_dev_info)
215 		return NULL;
216 
217 	return ops->get_dev_info(dvb, sysname);
218 }
219 
dvb_dev_open(struct dvb_device * d,const char * sysname,int flags)220 struct dvb_open_descriptor *dvb_dev_open(struct dvb_device *d,
221 					 const char *sysname, int flags)
222 {
223 	struct dvb_device_priv *dvb = (void *)d;
224 	struct dvb_dev_ops *ops = &dvb->ops;
225 
226 	if (!ops->open)
227 		return NULL;
228 
229 	return ops->open(dvb, sysname, flags);
230 }
231 
dvb_dev_get_fd(struct dvb_open_descriptor * open_dev)232 int dvb_dev_get_fd(struct dvb_open_descriptor *open_dev)
233 {
234 	struct dvb_device_priv *dvb = open_dev->dvb;
235 	struct dvb_dev_ops *ops = &dvb->ops;
236 
237 	if (!ops->get_fd)
238 		return -1;
239 
240 	return ops->get_fd(open_dev);
241 }
242 
dvb_dev_close(struct dvb_open_descriptor * open_dev)243 void dvb_dev_close(struct dvb_open_descriptor *open_dev)
244 {
245 	struct dvb_device_priv *dvb = open_dev->dvb;
246 	struct dvb_dev_ops *ops = &dvb->ops;
247 
248 	if (ops->close)
249 		ops->close(open_dev);
250 }
251 
dvb_dev_dmx_stop(struct dvb_open_descriptor * open_dev)252 void dvb_dev_dmx_stop(struct dvb_open_descriptor *open_dev)
253 {
254 	struct dvb_device_priv *dvb = open_dev->dvb;
255 	struct dvb_dev_ops *ops = &dvb->ops;
256 
257 	if (ops->dmx_stop)
258 		ops->dmx_stop(open_dev);
259 }
260 
dvb_dev_set_bufsize(struct dvb_open_descriptor * open_dev,int buffersize)261 int dvb_dev_set_bufsize(struct dvb_open_descriptor *open_dev,
262 			int buffersize)
263 {
264 	struct dvb_device_priv *dvb = open_dev->dvb;
265 	struct dvb_dev_ops *ops = &dvb->ops;
266 
267 	if (!ops->set_bufsize)
268 		return -1;
269 
270 	return ops->set_bufsize(open_dev, buffersize);
271 }
272 
dvb_dev_read(struct dvb_open_descriptor * open_dev,void * buf,size_t count)273 ssize_t dvb_dev_read(struct dvb_open_descriptor *open_dev,
274 		     void *buf, size_t count)
275 {
276 	struct dvb_device_priv *dvb = open_dev->dvb;
277 	struct dvb_dev_ops *ops = &dvb->ops;
278 
279 	if (!ops->read)
280 		return -1;
281 
282 	return ops->read(open_dev, buf, count);
283 }
284 
dvb_dev_dmx_set_pesfilter(struct dvb_open_descriptor * open_dev,int pid,dmx_pes_type_t type,dmx_output_t output,int bufsize)285 int dvb_dev_dmx_set_pesfilter(struct dvb_open_descriptor *open_dev,
286 			      int pid, dmx_pes_type_t type,
287 			      dmx_output_t output, int bufsize)
288 {
289 	struct dvb_device_priv *dvb = open_dev->dvb;
290 	struct dvb_dev_ops *ops = &dvb->ops;
291 
292 	if (!ops->dmx_set_pesfilter)
293 		return -1;
294 
295 	return ops->dmx_set_pesfilter(open_dev, pid, type, output, bufsize);
296 }
297 
dvb_dev_dmx_set_section_filter(struct dvb_open_descriptor * open_dev,int pid,unsigned filtsize,unsigned char * filter,unsigned char * mask,unsigned char * mode,unsigned int flags)298 int dvb_dev_dmx_set_section_filter(struct dvb_open_descriptor *open_dev,
299 				   int pid, unsigned filtsize,
300 				   unsigned char *filter,
301 				   unsigned char *mask,
302 				   unsigned char *mode,
303 				   unsigned int flags)
304 {
305 	struct dvb_device_priv *dvb = open_dev->dvb;
306 	struct dvb_dev_ops *ops = &dvb->ops;
307 
308 	if (!ops->dmx_set_section_filter)
309 		return -1;
310 
311 	return ops->dmx_set_section_filter(open_dev, pid, filtsize, filter,
312 					   mask, mode, flags);
313 }
314 
dvb_dev_dmx_get_pmt_pid(struct dvb_open_descriptor * open_dev,int sid)315 int dvb_dev_dmx_get_pmt_pid(struct dvb_open_descriptor *open_dev, int sid)
316 {
317 	struct dvb_device_priv *dvb = open_dev->dvb;
318 	struct dvb_dev_ops *ops = &dvb->ops;
319 
320 	if (!ops->dmx_get_pmt_pid)
321 		return -1;
322 
323 	return ops->dmx_get_pmt_pid(open_dev, sid);
324 }
325 
dvb_dev_scan(struct dvb_open_descriptor * open_dev,struct dvb_entry * entry,check_frontend_t * check_frontend,void * args,unsigned other_nit,unsigned timeout_multiply)326 struct dvb_v5_descriptors *dvb_dev_scan(struct dvb_open_descriptor *open_dev,
327 					struct dvb_entry *entry,
328 					check_frontend_t *check_frontend,
329 					void *args,
330 					unsigned other_nit,
331 					unsigned timeout_multiply)
332 {
333 	struct dvb_device_priv *dvb = open_dev->dvb;
334 	struct dvb_dev_ops *ops = &dvb->ops;
335 
336 	if (!ops->scan)
337 		return NULL;
338 
339 	return ops->scan(open_dev, entry, check_frontend, args, other_nit,
340 			 timeout_multiply);
341 }
342 
343 /* Frontend functions that can be overriden */
344 
dvb_set_sys(struct dvb_v5_fe_parms * p,fe_delivery_system_t sys)345 int dvb_set_sys(struct dvb_v5_fe_parms *p, fe_delivery_system_t sys)
346 {
347 	struct dvb_v5_fe_parms_priv *parms = (void *)p;
348 	struct dvb_device_priv *dvb = parms->dvb;
349 
350 	if (!dvb || !dvb->ops.fe_set_sys)
351 		return __dvb_set_sys(p, sys);
352 
353 	return dvb->ops.fe_set_sys(p, sys);
354 }
355 
dvb_fe_get_parms(struct dvb_v5_fe_parms * p)356 int dvb_fe_get_parms(struct dvb_v5_fe_parms *p)
357 {
358 	struct dvb_v5_fe_parms_priv *parms = (void *)p;
359 	struct dvb_device_priv *dvb = parms->dvb;
360 
361 	if (!dvb || !dvb->ops.fe_get_parms)
362 		return __dvb_fe_get_parms(p);
363 
364 	return dvb->ops.fe_get_parms(p);
365 }
366 
dvb_fe_set_parms(struct dvb_v5_fe_parms * p)367 int dvb_fe_set_parms(struct dvb_v5_fe_parms *p)
368 {
369 	struct dvb_v5_fe_parms_priv *parms = (void *)p;
370 	struct dvb_device_priv *dvb = parms->dvb;
371 
372 	if (!dvb || !dvb->ops.fe_set_parms)
373 		return __dvb_fe_set_parms(p);
374 
375 	return dvb->ops.fe_set_parms(p);
376 }
377 
dvb_fe_get_stats(struct dvb_v5_fe_parms * p)378 int dvb_fe_get_stats(struct dvb_v5_fe_parms *p)
379 {
380 	struct dvb_v5_fe_parms_priv *parms = (void *)p;
381 	struct dvb_device_priv *dvb = parms->dvb;
382 
383 	if (!dvb || !dvb->ops.fe_get_stats)
384 		return __dvb_fe_get_stats(p);
385 
386 	return dvb->ops.fe_get_stats(p);
387 }
388