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