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