xref: /netbsd-src/sys/dev/dtv/dtv_demux.c (revision e7cfc031b76a88e8db60402ec09155a3c9629c2b)
1 /* $NetBSD: dtv_demux.c,v 1.11 2020/05/30 13:15:10 jdolecek Exp $ */
2 
3 /*-
4  * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *        This product includes software developed by Jared D. McNeill.
18  * 4. Neither the name of The NetBSD Foundation nor the names of its
19  *    contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 /*
36  * This file contains support for the /dev/dvb/adapter<n>/demux0 device.
37  *
38  * The demux device is implemented as a cloning device. Each instance can
39  * be in one of three modes: unconfigured (NONE), section filter (SECTION),
40  * or PID filter (PES).
41  *
42  * An instance in section filter mode extracts PSI sections based on a
43  * filter configured by the DMX_SET_FILTER ioctl. When an entire section is
44  * received, it is made available to userspace via read method. Data is fed
45  * into the section filter using the dtv_demux_write function.
46  *
47  * An instance in PID filter mode extracts TS packets that match the
48  * specified PID filter configured by the DMX_SET_PES_FILTER, DMX_ADD_PID,
49  * and DMX_REMOVE_PID ioctls. As this driver only implements the
50  * DMX_OUT_TS_TAP output, these TS packets are made available to userspace
51  * by calling read on the /dev/dvb/adapter<n>/dvr0 device.
52  */
53 
54 #include <sys/cdefs.h>
55 __KERNEL_RCSID(0, "$NetBSD: dtv_demux.c,v 1.11 2020/05/30 13:15:10 jdolecek Exp $");
56 
57 #include <sys/param.h>
58 #include <sys/types.h>
59 #include <sys/conf.h>
60 #include <sys/kmem.h>
61 #include <sys/device.h>
62 #include <sys/select.h>
63 #include <sys/filedesc.h>
64 #include <sys/file.h>
65 #include <sys/poll.h>
66 #include <sys/vnode.h>
67 #include <sys/queue.h>
68 
69 #include <dev/dtv/dtvvar.h>
70 
71 static int	dtv_demux_read(struct file *, off_t *, struct uio *,
72 		    kauth_cred_t, int);
73 static int	dtv_demux_ioctl(struct file *, u_long, void *);
74 static int	dtv_demux_poll(struct file *, int);
75 static int	dtv_demux_close(struct file *);
76 
77 static const struct fileops dtv_demux_fileops = {
78 	.fo_name = "dtv_demux",
79 	.fo_read = dtv_demux_read,
80 	.fo_write = fbadop_write,
81 	.fo_ioctl = dtv_demux_ioctl,
82 	.fo_fcntl = fnullop_fcntl,
83 	.fo_poll = dtv_demux_poll,
84 	.fo_stat = fbadop_stat,
85 	.fo_close = dtv_demux_close,
86 	.fo_kqfilter = fnullop_kqfilter,
87 	.fo_restart = fnullop_restart,
88 };
89 
90 static uint32_t crc_table[256] = {
91 	0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
92 	0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
93 	0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
94 	0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
95 	0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
96 	0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
97 	0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
98 	0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
99 	0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
100 	0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
101 	0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
102 	0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
103 	0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
104 	0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
105 	0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
106 	0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
107 	0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
108 	0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
109 	0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
110 	0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
111 	0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
112 	0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
113 	0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
114 	0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
115 	0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
116 	0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
117 	0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
118 	0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
119 	0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
120 	0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
121 	0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
122 	0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
123 	0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
124 	0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
125 	0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
126 	0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
127 	0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
128 	0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
129 	0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
130 	0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
131 	0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
132 	0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
133 	0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
134 	0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
135 	0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
136 	0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
137 	0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
138 	0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
139 	0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
140 	0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
141 	0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
142 	0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
143 	0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
144 	0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
145 	0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
146 	0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
147 	0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
148 	0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
149 	0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
150 	0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
151 	0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
152 	0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
153 	0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
154 	0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
155 };
156 
157 /* ISO/IEC 13818-1 Annex A "CRC Decoder Model" */
158 static uint32_t
dtv_demux_crc32(uint8_t * buf,int len)159 dtv_demux_crc32(uint8_t *buf, int len)
160 {
161 	const uint32_t *crc_tab = crc_table;
162 	uint32_t CRC = 0xffffffff;
163 	int i;
164 
165 	for (i = 0; i < len; i++)
166 	      	CRC = (CRC << 8) ^ crc_tab[((CRC >> 24) ^ *buf++) & 0xff];
167 
168 	return CRC;
169 }
170 
171 /*
172  * Start running the demux.
173  */
174 static int
dtv_demux_start(struct dtv_demux * demux)175 dtv_demux_start(struct dtv_demux *demux)
176 {
177 	struct dtv_softc *sc = demux->dd_sc;
178 	int error = 0;
179 	bool dostart = false;
180 
181 	/*
182 	 * If the demux is not running, mark it as running and update the
183 	 * global demux run counter.
184 	 */
185 	mutex_enter(&sc->sc_lock);
186 	KASSERT(sc->sc_demux_runcnt >= 0);
187 	if (demux->dd_running == false) {
188 		sc->sc_demux_runcnt++;
189 		demux->dd_running = true;
190 		/* If this is the first demux running, trigger device start */
191 		dostart = sc->sc_demux_runcnt == 1;
192 	}
193 	mutex_exit(&sc->sc_lock);
194 
195 	if (dostart) {
196 		/* Setup receive buffers and trigger device start */
197 		error = dtv_buffer_setup(sc);
198 		if (error == 0)
199 			error = dtv_device_start_transfer(sc);
200 	}
201 
202 	/*
203 	 * If something went wrong, restore the run counter and mark this
204 	 * demux instance as halted.
205 	 */
206 	if (error) {
207 		mutex_enter(&sc->sc_lock);
208 		sc->sc_demux_runcnt--;
209 		demux->dd_running = false;
210 		mutex_exit(&sc->sc_lock);
211 	}
212 
213 	return error;
214 }
215 
216 /*
217  * Stop running the demux.
218  */
219 static int
dtv_demux_stop(struct dtv_demux * demux)220 dtv_demux_stop(struct dtv_demux *demux)
221 {
222 	struct dtv_softc *sc = demux->dd_sc;
223 	int error = 0;
224 	bool dostop = false;
225 
226 	/*
227 	 * If the demux is running, mark it as halted and update the
228 	 * global demux run counter.
229 	 */
230 	mutex_enter(&sc->sc_lock);
231 	if (demux->dd_running == true) {
232 		KASSERT(sc->sc_demux_runcnt > 0);
233 		demux->dd_running = false;
234 		sc->sc_demux_runcnt--;
235 		/* If this was the last demux running, trigger device stop */
236 		dostop = sc->sc_demux_runcnt == 0;
237 	}
238 	mutex_exit(&sc->sc_lock);
239 
240 	if (dostop) {
241 		/* Trigger device stop */
242 		error = dtv_device_stop_transfer(sc);
243 	}
244 
245 	/*
246 	 * If something went wrong, restore the run counter and mark this
247 	 * demux instance as running.
248 	 */
249 	if (error) {
250 		mutex_enter(&sc->sc_lock);
251 		sc->sc_demux_runcnt++;
252 		demux->dd_running = true;
253 		mutex_exit(&sc->sc_lock);
254 	}
255 
256 	return error;
257 }
258 
259 /*
260  * Put the demux into PID filter mode and update the PID filter table.
261  */
262 static int
dtv_demux_set_pidfilter(struct dtv_demux * demux,uint16_t pid,bool onoff)263 dtv_demux_set_pidfilter(struct dtv_demux *demux, uint16_t pid, bool onoff)
264 {
265 	struct dtv_softc *sc = demux->dd_sc;
266 
267 	/*
268 	 * TS PID is 13 bits; demux device uses special PID 0x2000 to mean
269 	 * "all PIDs". Verify that the requested PID is in range.
270 	 */
271 	if (pid > 0x2000)
272 		return EINVAL;
273 
274 	/* Set demux mode */
275 	demux->dd_mode = DTV_DEMUX_MODE_PES;
276 	/*
277 	 * If requesting "all PIDs", set the on/off flag for all PIDs in
278 	 * the PID map, otherwise set the on/off flag for the requested
279 	 * PID.
280 	 */
281 	if (pid == 0x2000) {
282 		memset(sc->sc_ts.ts_pidfilter, onoff ? 0xff : 0,
283 		    sizeof(sc->sc_ts.ts_pidfilter));
284 	} else {
285 		sc->sc_ts.ts_pidfilter[pid] = onoff;
286 	}
287 
288 	return 0;
289 }
290 
291 /*
292  * Open a new instance of the demux cloning device.
293  */
294 int
dtv_demux_open(struct dtv_softc * sc,int flags,int mode,lwp_t * l)295 dtv_demux_open(struct dtv_softc *sc, int flags, int mode, lwp_t *l)
296 {
297 	struct file *fp;
298 	struct dtv_demux *demux;
299 	int error, fd;
300 
301 	/* Allocate private storage */
302 	demux = kmem_zalloc(sizeof(*demux), KM_SLEEP);
303 	demux->dd_sc = sc;
304 	/* Default operation mode is unconfigured */
305 	demux->dd_mode = DTV_DEMUX_MODE_NONE;
306 	selinit(&demux->dd_sel);
307 	mutex_init(&demux->dd_lock, MUTEX_DEFAULT, IPL_SCHED);
308 	cv_init(&demux->dd_section_cv, "dtvsec");
309 
310 	error = fd_allocfile(&fp, &fd);
311 	if (error) {
312 		kmem_free(demux, sizeof(*demux));
313 		return error;
314 	}
315 
316 	/* Add the demux to the list of demux instances */
317 	mutex_enter(&sc->sc_demux_lock);
318 	TAILQ_INSERT_TAIL(&sc->sc_demux_list, demux, dd_entries);
319 	mutex_exit(&sc->sc_demux_lock);
320 
321 	return fd_clone(fp, fd, flags, &dtv_demux_fileops, demux);
322 }
323 
324 /*
325  * Close the instance of the demux cloning device.
326  */
327 int
dtv_demux_close(struct file * fp)328 dtv_demux_close(struct file *fp)
329 {
330 	struct dtv_demux *demux = fp->f_data;
331 	struct dtv_softc *sc;
332 	int error;
333 
334 	if (demux == NULL)
335 		return ENXIO;
336 
337 	fp->f_data = NULL;
338 
339 	sc = demux->dd_sc;
340 
341 	/* If the demux is still running, stop it */
342 	if (demux->dd_running) {
343 		error = dtv_demux_stop(demux);
344 		if (error)
345 			return error;
346 	}
347 
348 	/* Remove the demux from the list of demux instances */
349 	mutex_enter(&sc->sc_demux_lock);
350 	TAILQ_REMOVE(&sc->sc_demux_list, demux, dd_entries);
351 	mutex_exit(&sc->sc_demux_lock);
352 
353 	mutex_destroy(&demux->dd_lock);
354 	cv_destroy(&demux->dd_section_cv);
355 	kmem_free(demux, sizeof(*demux));
356 
357 	/* Update the global device open count */
358 	dtv_common_close(sc);
359 
360 	return 0;
361 }
362 
363 /*
364  * Handle demux ioctl requests
365  */
366 static int
dtv_demux_ioctl(struct file * fp,u_long cmd,void * data)367 dtv_demux_ioctl(struct file *fp, u_long cmd, void *data)
368 {
369 	struct dtv_demux *demux = fp->f_data;
370 	struct dmx_pes_filter_params *pesfilt;
371 	struct dmx_sct_filter_params *sctfilt;
372 	uint16_t pid;
373 	int error;
374 
375 	if (demux == NULL)
376 		return ENXIO;
377 
378 	switch (cmd) {
379 	case DMX_START:
380 		return dtv_demux_start(demux);
381 	case DMX_STOP:
382 		return dtv_demux_stop(demux);
383 	case DMX_SET_BUFFER_SIZE:
384 		/*
385 		 * The demux driver doesn't support configurable buffer sizes,
386 		 * but software relies on this command succeeding.
387 		 */
388 		return 0;
389 	case DMX_SET_FILTER:
390 		sctfilt = data;
391 
392 		/* Verify that the requested PID is in range. */
393 		if (sctfilt->pid >= 0x2000)
394 			return EINVAL;
395 
396 		/*
397 		 * Update section filter parameters, reset read/write ptrs,
398 		 * clear section count and overflow flag, and set the
399 		 * demux instance mode to section filter.
400 		 */
401 		demux->dd_secfilt.params = *sctfilt;
402 		demux->dd_secfilt.rp = demux->dd_secfilt.wp = 0;
403 		demux->dd_secfilt.nsections = 0;
404 		demux->dd_secfilt.overflow = false;
405 		demux->dd_mode = DTV_DEMUX_MODE_SECTION;
406 
407 		/*
408 		 * If the DMX_IMMEDIATE_START flag is present in the request,
409 		 * start running the demux immediately (no need for a
410 		 * subsequent DMX_START ioctl).
411 		 */
412 		if (sctfilt->flags & DMX_IMMEDIATE_START) {
413 			error = dtv_demux_start(demux);
414 			if (error)
415 				return error;
416 		}
417 
418 		return 0;
419 	case DMX_SET_PES_FILTER:
420 		pesfilt = data;
421 
422 		/* The driver only supports input from the frontend */
423 		if (pesfilt->input != DMX_IN_FRONTEND)
424 			return EINVAL;
425 		/*
426 		 * The driver only supports output to the TS TAP in PID
427 		 * filter mode.
428 		 */
429 		if (pesfilt->output != DMX_OUT_TS_TAP)
430 			return EINVAL;
431 
432 		/* Update PID filter table */
433 		error = dtv_demux_set_pidfilter(demux, pesfilt->pid, true);
434 		if (error)
435 			return error;
436 
437 		/*
438 		 * If the DMX_IMMEDIATE_START flag is present in the request,
439 		 * start running the demux immediately (no need for a
440 		 * subsequent DMX_START ioctl).
441 		 */
442 		if (pesfilt->flags & DMX_IMMEDIATE_START) {
443 			error = dtv_demux_start(demux);
444 			if (error)
445 				return error;
446 		}
447 		return 0;
448 	case DMX_ADD_PID:
449 		pid = *(uint16_t *)data;
450 		return dtv_demux_set_pidfilter(demux, pid, true);
451 	case DMX_REMOVE_PID:
452 		pid = *(uint16_t *)data;
453 		return dtv_demux_set_pidfilter(demux, pid, false);
454 	default:
455 		return EINVAL;
456 	}
457 }
458 
459 /*
460  * Test for I/O readiness
461  */
462 static int
dtv_demux_poll(struct file * fp,int events)463 dtv_demux_poll(struct file *fp, int events)
464 {
465 	struct dtv_demux *demux = fp->f_data;
466 	int revents = 0;
467 
468 	if (demux == NULL)
469 		return POLLERR;
470 
471 	/*
472 	 * If the demux instance is in section filter mode, wait for an
473 	 * entire section to become ready.
474 	 */
475 	mutex_enter(&demux->dd_lock);
476 	if (demux->dd_mode == DTV_DEMUX_MODE_SECTION &&
477 	    demux->dd_secfilt.nsections > 0) {
478 		revents |= POLLIN;
479 	} else {
480 		selrecord(curlwp, &demux->dd_sel);
481 	}
482 	mutex_exit(&demux->dd_lock);
483 
484 	return revents;
485 }
486 
487 /*
488  * Read from the demux instance
489  */
490 static int
dtv_demux_read(struct file * fp,off_t * offp,struct uio * uio,kauth_cred_t cred,int flags)491 dtv_demux_read(struct file *fp, off_t *offp, struct uio *uio,
492     kauth_cred_t cred, int flags)
493 {
494 	struct dtv_demux *demux = fp->f_data;
495 	struct dtv_ts_section *sec;
496 	int error;
497 
498 	if (demux == NULL)
499 		return ENXIO;
500 
501 	/* Only support read if the instance is in section filter mode */
502 	if (demux->dd_mode != DTV_DEMUX_MODE_SECTION)
503 		return EIO;
504 
505 	sec = kmem_alloc(sizeof(*sec), KM_SLEEP);
506 
507 	/* Wait for a complete PSI section */
508 	mutex_enter(&demux->dd_lock);
509 	while (demux->dd_secfilt.nsections == 0) {
510 		if (flags & IO_NDELAY) {
511 			mutex_exit(&demux->dd_lock);
512 			/* No data available */
513 			error = EWOULDBLOCK;
514 			goto out;
515 		}
516 		error = cv_wait_sig(&demux->dd_section_cv, &demux->dd_lock);
517 		if (error) {
518 			mutex_exit(&demux->dd_lock);
519 			goto out;
520 		}
521 	}
522 	/* Copy the completed PSI section */
523 	*sec = demux->dd_secfilt.section[demux->dd_secfilt.rp];
524 	/* Update read pointer */
525 	demux->dd_secfilt.rp++;
526 	if (demux->dd_secfilt.rp >= __arraycount(demux->dd_secfilt.section))
527 		demux->dd_secfilt.rp = 0;
528 	/* Update section count */
529 	demux->dd_secfilt.nsections--;
530 	mutex_exit(&demux->dd_lock);
531 
532 	/*
533 	 * If the filter parameters specify the DMX_ONESHOT flag, stop
534 	 * the demux after one PSI section is received.
535 	 */
536 	if (demux->dd_secfilt.params.flags & DMX_ONESHOT)
537 		dtv_demux_stop(demux);
538 
539 	/*
540 	 * Copy the PSI section to userspace. If the receiving buffer is
541 	 * too small, the rest of the payload will be discarded. Although
542 	 * this behaviour differs from the Linux implementation, in practice
543 	 * it should not be an issue as PSI sections have a max size of 4KB
544 	 * (and callers will generally provide a big enough buffer).
545 	 */
546 	error = uiomove(sec->sec_buf, sec->sec_length, uio);
547 
548 out:
549 	kmem_free(sec, sizeof(*sec));
550 	return error;
551 
552 }
553 
554 /*
555  * Verify the CRC of a PSI section.
556  */
557 static bool
dtv_demux_check_crc(struct dtv_demux * demux,struct dtv_ts_section * sec)558 dtv_demux_check_crc(struct dtv_demux *demux, struct dtv_ts_section *sec)
559 {
560 	uint32_t crc, sec_crc;
561 
562 	/*
563 	 * If section_syntax_indicator is not set, the PSI section does
564 	 * not include a CRC field.
565 	 */
566 	if ((sec->sec_buf[1] & 0x80) == 0)
567 		return false;
568 
569 	sec_crc = be32dec(&sec->sec_buf[sec->sec_length - 4]);
570 	crc = dtv_demux_crc32(&sec->sec_buf[0], sec->sec_length - 4);
571 
572 	return crc == sec_crc;
573 }
574 
575 /*
576  * Process a single TS packet and extract PSI sections based on the
577  * instance's section filter.
578  */
579 static int
dtv_demux_process(struct dtv_demux * demux,const uint8_t * tspkt,size_t tspktlen)580 dtv_demux_process(struct dtv_demux *demux, const uint8_t *tspkt,
581     size_t tspktlen)
582 {
583 	struct dtv_ts_section *sec;
584 	dmx_filter_t *dmxfilt = &demux->dd_secfilt.params.filter;
585 	const uint8_t *p;
586 	uint16_t section_length;
587 	int brem, avail;
588 
589 	KASSERT(tspktlen == TS_PKTLEN);
590 
591 	/* If the demux instance is not running, ignore the packet */
592 	if (demux->dd_running == false)
593 		return 0;
594 
595 	/*
596 	 * If the demux instance is not in section filter mode, ignore
597 	 * the packet
598 	 */
599 	if (demux->dd_mode != DTV_DEMUX_MODE_SECTION)
600 		return 0;
601 	/*
602 	 * If the packet's TS PID does not match the section filter PID,
603 	 * ignore the packet
604 	 */
605 	if (TS_PID(tspkt) != demux->dd_secfilt.params.pid)
606 		return 0;
607 	/*
608 	 * If the TS packet does not contain a payload, ignore the packet
609 	 */
610 	if (TS_HAS_PAYLOAD(tspkt) == 0)
611 		return 0;
612 
613 	mutex_enter(&demux->dd_lock);
614 
615 	/* If the section buffer is full, set the overflow flag and return */
616 	if (demux->dd_secfilt.nsections ==
617 	    __arraycount(demux->dd_secfilt.section)) {
618 		demux->dd_secfilt.overflow = true;
619 		goto done;
620 	}
621 	sec = &demux->dd_secfilt.section[demux->dd_secfilt.wp];
622 	/* If we have no bytes in our buffer, wait for payload unit start */
623 	if (sec->sec_bytesused == 0 && TS_HAS_PUSI(tspkt) == 0)
624 		goto done;
625 
626 	/* find payload start */
627 	p = tspkt + 4;
628 	if (TS_HAS_AF(tspkt)) {
629 		if (*p > 182)	/* AF length with payload is between 0-182 */
630 			goto done;
631 		p += (1 + *p);
632 	}
633 	if (TS_HAS_PUSI(tspkt)) {
634 		p += (1 + *p);
635 	}
636 
637 	brem = tspktlen - (p - tspkt);
638 
639 	if (TS_HAS_PUSI(tspkt)) {
640 		if (brem < 16)
641 			goto done;
642 
643 		section_length = ((p[1] & 0xf) << 8) | p[2];
644 
645 		/* table_id filter */
646 		if (dmxfilt->mask[0]) {
647 			if ((p[0] & dmxfilt->mask[0]) != dmxfilt->filter[0])
648 				goto done;
649 		}
650 		/* table_id_ext filter */
651 		if (dmxfilt->mask[1] && dmxfilt->mask[2]) {
652 			/*
653 			 * table_id_ext is only valid if
654 			 * section_syntax_indicator is set
655 			 */
656 			if (section_length < 2 || (p[1] & 0x80) == 0)
657 				goto done;
658 			if ((p[3] & dmxfilt->mask[1]) != dmxfilt->filter[1])
659 				goto done;
660 			if ((p[4] & dmxfilt->mask[2]) != dmxfilt->filter[2])
661 				goto done;
662 		}
663 
664 		sec->sec_length = section_length + 3;
665 
666 		/* maximum section length is 4KB */
667 		if (sec->sec_length > sizeof(sec->sec_buf)) {
668 			sec->sec_bytesused = sec->sec_length = 0;
669 			goto done;
670 		}
671 
672 	}
673 
674 	/* If we have bytes pending and we see payload unit start, flush buf */
675 	if (sec->sec_bytesused > 0 && TS_HAS_PUSI(tspkt))
676 		sec->sec_bytesused = sec->sec_length = 0;
677 
678 	/* Copy data into section buffer */
679 	avail = uimin(sec->sec_length - sec->sec_bytesused, brem);
680 	if (avail < 0)
681 		goto done;
682 	memcpy(&sec->sec_buf[sec->sec_bytesused], p, avail);
683 	sec->sec_bytesused += avail;
684 
685 	/*
686 	 * If a complete section has been received, update section count
687 	 * and notify readers.
688 	 */
689 	if (sec->sec_bytesused == sec->sec_length) {
690 		/*
691 		 * If the DMX_CHECK_CRC flag was present in the DMX_SET_FILTER
692 		 * parameters, verify the PSI section checksum. If the
693 		 * checksum is invalid, discard the entire corrupt section.
694 		 */
695 		if ((demux->dd_secfilt.params.flags & DMX_CHECK_CRC) &&
696 		    dtv_demux_check_crc(demux, sec) == false) {
697 			/* discard section */
698 			sec->sec_bytesused = sec->sec_length = 0;
699 			goto done;
700 		}
701 
702 		demux->dd_secfilt.wp++;
703 		if (demux->dd_secfilt.wp >=
704 		    __arraycount(demux->dd_secfilt.section))
705 			demux->dd_secfilt.wp = 0;
706 		demux->dd_secfilt.nsections++;
707 		cv_broadcast(&demux->dd_section_cv);
708 		selnotify(&demux->dd_sel, 0, 0);
709 	}
710 
711 done:
712 	mutex_exit(&demux->dd_lock);
713 	return 0;
714 }
715 
716 /*
717  * Submit TS data to all demux instances
718  */
719 void
dtv_demux_write(struct dtv_softc * sc,const uint8_t * tspkt,size_t tspktlen)720 dtv_demux_write(struct dtv_softc *sc, const uint8_t *tspkt, size_t tspktlen)
721 {
722 	struct dtv_demux *demux;
723 
724 	mutex_enter(&sc->sc_demux_lock);
725 	TAILQ_FOREACH(demux, &sc->sc_demux_list, dd_entries) {
726 		dtv_demux_process(demux, tspkt, tspktlen);
727 	}
728 	mutex_exit(&sc->sc_demux_lock);
729 }
730