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