1 /*
2 * Tvheadend
3 * Copyright (C) 2013 Andreas Öman
4 * Copyright (C) 2014,2015 Jaroslav Kysela
5 *
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "tvheadend.h"
22 #include "config.h"
23 #include "settings.h"
24 #include "descrambler.h"
25 #include "caid.h"
26 #include "caclient.h"
27 #include "ffdecsa/FFdecsa.h"
28 #include "input.h"
29 #include "input/mpegts/tsdemux.h"
30 #include "dvbcam.h"
31 #include "streaming.h"
32
33 #define MAX_QUICK_ECM_ENTRIES 100
34 #define MAX_CONSTCW_ENTRIES 100
35
36 typedef struct th_descrambler_data {
37 TAILQ_ENTRY(th_descrambler_data) dd_link;
38 int64_t dd_timestamp;
39 sbuf_t dd_sbuf;
40 } th_descrambler_data_t;
41
42 TAILQ_HEAD(th_descrambler_queue, th_descrambler_data);
43
44 uint16_t *quick_ecm_table = NULL;
45 uint16_t *constcw_table = NULL;
46
47 /*
48 *
49 */
50 static void
descrambler_data_destroy(th_descrambler_runtime_t * dr,th_descrambler_data_t * dd,int skip)51 descrambler_data_destroy(th_descrambler_runtime_t *dr, th_descrambler_data_t *dd, int skip)
52 {
53 if (dd) {
54 if (skip && dr->dr_skip)
55 ts_skip_packet2((mpegts_service_t *)dr->dr_service,
56 dd->dd_sbuf.sb_data, dd->dd_sbuf.sb_ptr);
57 dr->dr_queue_total -= dd->dd_sbuf.sb_ptr;
58 TAILQ_REMOVE(&dr->dr_queue, dd, dd_link);
59 sbuf_free(&dd->dd_sbuf);
60 free(dd);
61 #if ENABLE_TRACE
62 if (TAILQ_EMPTY(&dr->dr_queue))
63 assert(dr->dr_queue_total == 0);
64 #endif
65 }
66 }
67
68 static void
descrambler_data_time_flush(th_descrambler_runtime_t * dr,int64_t oldest)69 descrambler_data_time_flush(th_descrambler_runtime_t *dr, int64_t oldest)
70 {
71 th_descrambler_data_t *dd;
72
73 while ((dd = TAILQ_FIRST(&dr->dr_queue)) != NULL) {
74 if (dd->dd_timestamp >= oldest) break;
75 descrambler_data_destroy(dr, dd, 1);
76 }
77 }
78
79 static void
descrambler_data_append(th_descrambler_runtime_t * dr,const uint8_t * tsb,int len)80 descrambler_data_append(th_descrambler_runtime_t *dr, const uint8_t *tsb, int len)
81 {
82 th_descrambler_data_t *dd;
83
84 if (len == 0)
85 return;
86 dd = TAILQ_LAST(&dr->dr_queue, th_descrambler_queue);
87 if (dd && monocmpfastsec(dd->dd_timestamp, mclk()) &&
88 (dd->dd_sbuf.sb_data[3] & 0x40) == (tsb[3] & 0x40)) { /* key match */
89 sbuf_append(&dd->dd_sbuf, tsb, len);
90 dr->dr_queue_total += len;
91 return;
92 }
93 dd = malloc(sizeof(*dd));
94 dd->dd_timestamp = mclk();
95 sbuf_init(&dd->dd_sbuf);
96 sbuf_append(&dd->dd_sbuf, tsb, len);
97 TAILQ_INSERT_TAIL(&dr->dr_queue, dd, dd_link);
98 dr->dr_queue_total += len;
99 }
100
101 static void
descrambler_data_cut(th_descrambler_runtime_t * dr,int len)102 descrambler_data_cut(th_descrambler_runtime_t *dr, int len)
103 {
104 th_descrambler_data_t *dd;
105
106 while (len > 0 && (dd = TAILQ_FIRST(&dr->dr_queue)) != NULL) {
107 if (dr->dr_skip)
108 ts_skip_packet2((mpegts_service_t *)dr->dr_service,
109 dd->dd_sbuf.sb_data, MIN(len, dd->dd_sbuf.sb_ptr));
110 if (len < dd->dd_sbuf.sb_ptr) {
111 sbuf_cut(&dd->dd_sbuf, len);
112 dr->dr_queue_total -= len;
113 break;
114 }
115 len -= dd->dd_sbuf.sb_ptr;
116 descrambler_data_destroy(dr, dd, 1);
117 }
118 }
119
120 static int
descrambler_data_key_check(th_descrambler_runtime_t * dr,uint8_t key,int len)121 descrambler_data_key_check(th_descrambler_runtime_t *dr, uint8_t key, int len)
122 {
123 th_descrambler_data_t *dd = TAILQ_FIRST(&dr->dr_queue);
124 int off = 0;
125
126 if (dd == NULL)
127 return 0;
128 while (off < len) {
129 if (dd->dd_sbuf.sb_ptr <= off) {
130 dd = TAILQ_NEXT(dd, dd_link);
131 if (dd == NULL)
132 return 0;
133 len -= off;
134 off = 0;
135 }
136 if ((dd->dd_sbuf.sb_data[off + 3] & 0xc0) != key)
137 return 0;
138 off += 188;
139 }
140 return 1;
141 }
142
143 /*
144 *
145 */
146 void
descrambler_init(void)147 descrambler_init ( void )
148 {
149 htsmsg_t *c, *e, *q;
150 htsmsg_field_t *f;
151 const char *s;
152 uint32_t caid;
153 int idx;
154
155 #if (ENABLE_CWC || ENABLE_CAPMT) && !ENABLE_DVBCSA
156 ffdecsa_init();
157 #endif
158 caclient_init();
159 #if ENABLE_LINUXDVB_CA
160 dvbcam_init();
161 #endif
162
163 if ((c = hts_settings_load("descrambler")) != NULL) {
164 idx = 0;
165 if ((q = htsmsg_get_list(c, "quick_ecm")) != NULL) {
166 HTSMSG_FOREACH(f, q) {
167 if (!(e = htsmsg_field_get_map(f))) continue;
168 if (idx + 1 >= MAX_QUICK_ECM_ENTRIES) continue;
169 if ((s = htsmsg_get_str(e, "caid")) == NULL) continue;
170 caid = strtol(s, NULL, 16);
171 tvhinfo(LS_DESCRAMBLER, "adding CAID %04X as quick ECM (%s)", caid, htsmsg_get_str(e, "name") ?: "unknown");
172 if (!quick_ecm_table)
173 quick_ecm_table = malloc(sizeof(uint16_t) * MAX_QUICK_ECM_ENTRIES);
174 quick_ecm_table[idx++] = caid;
175 }
176 if (quick_ecm_table)
177 quick_ecm_table[idx] = 0;
178 }
179 idx = 0;
180 if ((q = htsmsg_get_list(c, "const_cw")) != NULL) {
181 HTSMSG_FOREACH(f, q) {
182 if (!(e = htsmsg_field_get_map(f))) continue;
183 if (idx + 1 >= MAX_CONSTCW_ENTRIES) continue;
184 if ((s = htsmsg_get_str(e, "caid")) == NULL) continue;
185 caid = strtol(s, NULL, 16);
186 tvhinfo(LS_DESCRAMBLER, "adding CAID %04X as constant crypto-word (%s)", caid, htsmsg_get_str(e, "name") ?: "unknown");
187 if (!constcw_table)
188 constcw_table = malloc(sizeof(uint16_t) * MAX_CONSTCW_ENTRIES);
189 constcw_table[idx++] = caid;
190 }
191 if (constcw_table)
192 constcw_table[idx] = 0;
193 }
194 htsmsg_destroy(c);
195 }
196 }
197
198 void
descrambler_done(void)199 descrambler_done ( void )
200 {
201 caclient_done();
202 free(quick_ecm_table);
203 quick_ecm_table = NULL;
204 free(constcw_table);
205 constcw_table = NULL;
206 }
207
208 /*
209 * Decide, if we should work in "quick ECM" mode
210 */
211 static int
descrambler_quick_ecm(mpegts_service_t * t,int pid)212 descrambler_quick_ecm ( mpegts_service_t *t, int pid )
213 {
214 elementary_stream_t *st;
215 caid_t *ca;
216 uint16_t *p;
217
218 if (!quick_ecm_table)
219 return 0;
220 TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link) {
221 if (st->es_pid != pid) continue;
222 LIST_FOREACH(ca, &st->es_caids, link)
223 for (p = quick_ecm_table; *p; p++)
224 if (ca->caid == *p)
225 return 1;
226 }
227 return 0;
228 }
229
230 /*
231 * This routine is called from two places
232 * a) start a new service
233 * b) restart a running service with possible caid changes
234 */
235 void
descrambler_service_start(service_t * t)236 descrambler_service_start ( service_t *t )
237 {
238 th_descrambler_runtime_t *dr;
239 elementary_stream_t *st;
240 caid_t *ca;
241 int count, constcw = 0;
242 uint16_t *p;
243
244 if (t->s_scrambled_pass)
245 return;
246
247 if (!t->s_dvb_forcecaid) {
248
249 count = 0;
250 TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link)
251 LIST_FOREACH(ca, &st->es_caids, link) {
252 if (ca->use == 0) continue;
253 for (p = constcw_table; p && *p; p++)
254 if (ca->caid == *p) {
255 constcw = 1;
256 break;
257 }
258 count++;
259 }
260
261 /* Do not run descrambler on FTA channels */
262 if (count == 0)
263 return;
264
265 } else {
266
267 if (constcw_table) {
268 for (p = constcw_table; *p; p++)
269 if (*p == t->s_dvb_forcecaid) {
270 constcw = 1;
271 break;
272 }
273 }
274
275 }
276
277 ((mpegts_service_t *)t)->s_dvb_mux->mm_descrambler_flush = 0;
278 if (t->s_descramble == NULL) {
279 t->s_descramble = dr = calloc(1, sizeof(th_descrambler_runtime_t));
280 dr->dr_service = t;
281 TAILQ_INIT(&dr->dr_queue);
282 dr->dr_key_index = 0xff;
283 dr->dr_key_interval = sec2mono(10);
284 dr->dr_key_const = constcw;
285 if (constcw)
286 tvhtrace(LS_DESCRAMBLER, "using constcw for \"%s\"", t->s_nicename);
287 dr->dr_skip = 0;
288 dr->dr_force_skip = 0;
289 tvhcsa_init(&dr->dr_csa);
290 }
291
292 if (t->s_dvb_forcecaid != 0xffff)
293 caclient_start(t);
294
295 #if ENABLE_LINUXDVB_CA
296 dvbcam_service_start(t);
297 #endif
298
299 if (t->s_dvb_forcecaid == 0xffff) {
300 pthread_mutex_lock(&t->s_stream_mutex);
301 descrambler_external(t, 1);
302 pthread_mutex_unlock(&t->s_stream_mutex);
303 }
304 }
305
306 void
descrambler_service_stop(service_t * t)307 descrambler_service_stop ( service_t *t )
308 {
309 th_descrambler_t *td;
310 th_descrambler_runtime_t *dr = t->s_descramble;
311 th_descrambler_data_t *dd;
312 void *p;
313
314 #if ENABLE_LINUXDVB_CA
315 dvbcam_service_stop(t);
316 #endif
317
318 while ((td = LIST_FIRST(&t->s_descramblers)) != NULL)
319 td->td_stop(td);
320 pthread_mutex_lock(&t->s_stream_mutex);
321 t->s_descramble = NULL;
322 t->s_descrambler = NULL;
323 p = t->s_descramble_info;
324 t->s_descramble_info = NULL;
325 pthread_mutex_unlock(&t->s_stream_mutex);
326 free(p);
327 if (dr) {
328 tvhcsa_destroy(&dr->dr_csa);
329 while ((dd = TAILQ_FIRST(&dr->dr_queue)) != NULL)
330 descrambler_data_destroy(dr, dd, 0);
331 free(dr);
332 }
333 }
334
335 void
descrambler_caid_changed(service_t * t)336 descrambler_caid_changed ( service_t *t )
337 {
338 th_descrambler_t *td;
339
340 LIST_FOREACH(td, &t->s_descramblers, td_service_link) {
341 if (td->td_caid_change)
342 td->td_caid_change(td);
343 }
344 }
345
346 static void
descrambler_notify_deliver(mpegts_service_t * t,descramble_info_t * di)347 descrambler_notify_deliver( mpegts_service_t *t, descramble_info_t *di )
348 {
349 streaming_message_t *sm;
350 int r;
351
352 lock_assert(&t->s_stream_mutex);
353 if (!t->s_descramble_info)
354 t->s_descramble_info = calloc(1, sizeof(*di));
355 r = memcmp(t->s_descramble_info, di, sizeof(*di));
356 if (r == 0) { /* identical */
357 free(di);
358 return;
359 }
360 memcpy(t->s_descramble_info, di, sizeof(*di));
361
362 sm = streaming_msg_create(SMT_DESCRAMBLE_INFO);
363 sm->sm_data = di;
364
365 streaming_pad_deliver(&t->s_streaming_pad, sm);
366 }
367
368 static void
descrambler_notify_nokey(th_descrambler_runtime_t * dr)369 descrambler_notify_nokey( th_descrambler_runtime_t *dr )
370 {
371 mpegts_service_t *t = (mpegts_service_t *)dr->dr_service;
372 descramble_info_t *di;
373
374 tvhdebug(LS_DESCRAMBLER, "no key for service='%s'", t->s_dvb_svcname);
375
376 di = calloc(1, sizeof(*di));
377 di->pid = t->s_pmt_pid;
378
379 descrambler_notify_deliver(t, di);
380 }
381
382 void
descrambler_notify(th_descrambler_t * td,uint16_t caid,uint32_t provid,const char * cardsystem,uint16_t pid,uint32_t ecmtime,uint16_t hops,const char * reader,const char * from,const char * protocol)383 descrambler_notify( th_descrambler_t *td,
384 uint16_t caid, uint32_t provid,
385 const char *cardsystem, uint16_t pid, uint32_t ecmtime,
386 uint16_t hops, const char *reader, const char *from,
387 const char *protocol )
388 {
389 mpegts_service_t *t = (mpegts_service_t *)td->td_service;
390 descramble_info_t *di;
391
392 tvhdebug(LS_DESCRAMBLER, "info - service='%s' caid=%04X(%s) "
393 "provid=%06X ecmtime=%d hops=%d "
394 "reader='%s' from='%s' protocol='%s'%s",
395 t->s_dvb_svcname, caid, cardsystem, provid,
396 ecmtime, hops, reader, from, protocol,
397 t->s_descrambler != td ? " (inactive)" : "");
398
399 if (t->s_descrambler != td)
400 return;
401
402 di = calloc(1, sizeof(*di));
403
404 di->pid = pid;
405 di->caid = caid;
406 di->provid = provid;
407 di->ecmtime = ecmtime;
408 di->hops = hops;
409 strlcpy(di->cardsystem, cardsystem, sizeof(di->cardsystem));
410 strlcpy(di->reader, reader, sizeof(di->reader));
411 strlcpy(di->from, from, sizeof(di->protocol));
412 strlcpy(di->protocol, protocol, sizeof(di->protocol));
413
414 pthread_mutex_lock(&t->s_stream_mutex);
415 descrambler_notify_deliver(t, di);
416 pthread_mutex_unlock(&t->s_stream_mutex);
417 }
418
419 int
descrambler_resolved(service_t * t,th_descrambler_t * ignore)420 descrambler_resolved( service_t *t, th_descrambler_t *ignore )
421 {
422 th_descrambler_t *td;
423
424 LIST_FOREACH(td, &t->s_descramblers, td_service_link)
425 if (td != ignore && td->td_keystate == DS_RESOLVED)
426 return 1;
427 return 0;
428 }
429
430 void
descrambler_external(service_t * t,int state)431 descrambler_external ( service_t *t, int state )
432 {
433 th_descrambler_runtime_t *dr;
434
435 if (t == NULL)
436 return;
437
438 lock_assert(&t->s_stream_mutex);
439
440 if ((dr = t->s_descramble) == NULL)
441 return;
442 dr->dr_external = state ? 1 : 0;
443 service_reset_streaming_status_flags(t, TSS_NO_DESCRAMBLER);
444 }
445
446 void
descrambler_keys(th_descrambler_t * td,int type,const uint8_t * even,const uint8_t * odd)447 descrambler_keys ( th_descrambler_t *td, int type,
448 const uint8_t *even, const uint8_t *odd )
449 {
450 static uint8_t empty[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
451 service_t *t = td->td_service;
452 th_descrambler_runtime_t *dr;
453 th_descrambler_t *td2;
454 int j = 0;
455
456 if (t == NULL || (dr = t->s_descramble) == NULL) {
457 td->td_keystate = DS_FORBIDDEN;
458 return;
459 }
460
461 pthread_mutex_lock(&t->s_stream_mutex);
462
463 if (tvhcsa_set_type(&dr->dr_csa, type) < 0)
464 goto fin;
465
466 LIST_FOREACH(td2, &t->s_descramblers, td_service_link)
467 if (td2 != td && td2->td_keystate == DS_RESOLVED) {
468 tvhdebug(LS_DESCRAMBLER,
469 "Already has a key from %s for service \"%s\", "
470 "ignoring key from \"%s\"%s",
471 td2->td_nicename,
472 ((mpegts_service_t *)td2->td_service)->s_dvb_svcname,
473 td->td_nicename,
474 dr->dr_key_const ? " (const)" : "");
475 td->td_keystate = DS_IDLE;
476 if (td->td_ecm_idle) {
477 pthread_mutex_unlock(&t->s_stream_mutex);
478 td->td_ecm_idle(td);
479 pthread_mutex_lock(&t->s_stream_mutex);
480 }
481 goto fin;
482 }
483
484 if (memcmp(empty, even, dr->dr_csa.csa_keylen)) {
485 j++;
486 memcpy(dr->dr_key_even, even, dr->dr_csa.csa_keylen);
487 dr->dr_key_changed |= 1;
488 dr->dr_key_valid |= 0x40;
489 dr->dr_key_timestamp[0] = mclk();
490 }
491 if (memcmp(empty, odd, dr->dr_csa.csa_keylen)) {
492 j++;
493 memcpy(dr->dr_key_odd, odd, dr->dr_csa.csa_keylen);
494 dr->dr_key_changed |= 2;
495 dr->dr_key_valid |= 0x80;
496 dr->dr_key_timestamp[1] = mclk();
497 }
498
499 if (j) {
500 if (td->td_keystate != DS_RESOLVED)
501 tvhdebug( LS_DESCRAMBLER,
502 "Obtained keys from %s for service \"%s\"%s",
503 td->td_nicename,
504 ((mpegts_service_t *)t)->s_dvb_svcname,
505 dr->dr_key_const ? " (const)" : "");
506 if (dr->dr_csa.csa_keylen == 8) {
507 tvhtrace(LS_DESCRAMBLER, "Obtained keys "
508 "%02X%02X%02X%02X%02X%02X%02X%02X:%02X%02X%02X%02X%02X%02X%02X%02X"
509 " from %s for service \"%s\"",
510 even[0], even[1], even[2], even[3], even[4], even[5], even[6], even[7],
511 odd[0], odd[1], odd[2], odd[3], odd[4], odd[5], odd[6], odd[7],
512 td->td_nicename,
513 ((mpegts_service_t *)t)->s_dvb_svcname);
514 } else if (dr->dr_csa.csa_keylen == 16) {
515 tvhtrace(LS_DESCRAMBLER, "Obtained keys "
516 "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X:"
517 "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
518 " from %s for service \"%s\"",
519 even[0], even[1], even[2], even[3], even[4], even[5], even[6], even[7],
520 even[8], even[9], even[10], even[11], even[12], even[13], even[14], even[15],
521 odd[0], odd[1], odd[2], odd[3], odd[4], odd[5], odd[6], odd[7],
522 odd[8], odd[9], odd[10], odd[11], odd[12], odd[13], odd[14], odd[15],
523 td->td_nicename,
524 ((mpegts_service_t *)t)->s_dvb_svcname);
525 } else {
526 tvhtrace(LS_DESCRAMBLER, "Unknown keys from %s for for service \"%s\"",
527 td->td_nicename, ((mpegts_service_t *)t)->s_dvb_svcname);
528 }
529 dr->dr_ecm_last_key_time = mclk();
530 td->td_keystate = DS_RESOLVED;
531 td->td_service->s_descrambler = td;
532 } else {
533 tvhdebug(LS_DESCRAMBLER,
534 "Empty keys received from %s for service \"%s\"%s",
535 td->td_nicename,
536 ((mpegts_service_t *)t)->s_dvb_svcname,
537 dr->dr_key_const ? " (const)" : "");
538 }
539
540 fin:
541 pthread_mutex_unlock(&t->s_stream_mutex);
542 #if ENABLE_TSDEBUG
543 if (j) {
544 tsdebug_packet_t *tp = malloc(sizeof(*tp));
545 uint16_t keylen = dr->dr_csa.csa_keylen;
546 uint16_t sid = ((mpegts_service_t *)td->td_service)->s_dvb_service_id;
547 uint32_t pos = 0, crc;
548 mpegts_mux_t *mm = ((mpegts_service_t *)td->td_service)->s_dvb_mux;
549 if (!mm->mm_active) {
550 free(tp);
551 return;
552 }
553 pthread_mutex_lock(&mm->mm_active->mmi_input->mi_output_lock);
554 tp->pos = mm->mm_tsdebug_pos;
555 memset(tp->pkt, 0xff, sizeof(tp->pkt));
556 tp->pkt[pos++] = 0x47; /* sync byte */
557 tp->pkt[pos++] = 0x1f; /* PID MSB */
558 tp->pkt[pos++] = 0xff; /* PID LSB */
559 tp->pkt[pos++] = 0x00; /* CC */
560 memcpy(tp->pkt + pos, "TVHeadendDescramblerKeys", 24);
561 pos += 24;
562 tp->pkt[pos++] = type & 0xff;
563 tp->pkt[pos++] = keylen & 0xff;
564 tp->pkt[pos++] = (sid >> 8) & 0xff;
565 tp->pkt[pos++] = sid & 0xff;
566 memcpy(tp->pkt + pos, even, keylen);
567 memcpy(tp->pkt + pos + keylen, odd, keylen);
568 pos += 2 * keylen;
569 crc = tvh_crc32(tp->pkt, pos, 0x859aa5ba);
570 tp->pkt[pos++] = (crc >> 24) & 0xff;
571 tp->pkt[pos++] = (crc >> 16) & 0xff;
572 tp->pkt[pos++] = (crc >> 8) & 0xff;
573 tp->pkt[pos++] = crc & 0xff;
574 TAILQ_INSERT_HEAD(&mm->mm_tsdebug_packets, tp, link);
575 pthread_mutex_unlock(&mm->mm_active->mmi_input->mi_output_lock);
576 }
577 #endif
578 }
579
580 void
descrambler_flush_table_data(service_t * t)581 descrambler_flush_table_data( service_t *t )
582 {
583 mpegts_service_t *ms = (mpegts_service_t *)t;
584 mpegts_mux_t *mux = ms->s_dvb_mux;
585 descrambler_table_t *dt;
586 descrambler_section_t *ds;
587 descrambler_ecmsec_t *des;
588
589 if (mux == NULL)
590 return;
591 tvhtrace(LS_DESCRAMBLER, "flush table data for service \"%s\"", ms->s_dvb_svcname);
592 pthread_mutex_lock(&mux->mm_descrambler_lock);
593 TAILQ_FOREACH(dt, &mux->mm_descrambler_tables, link) {
594 if (dt->table == NULL || dt->table->mt_service != ms)
595 continue;
596 TAILQ_FOREACH(ds, &dt->sections, link)
597 while ((des = LIST_FIRST(&ds->ecmsecs)) != NULL) {
598 LIST_REMOVE(des, link);
599 free(des->last_data);
600 if (atomic_dec(&des->refcnt, 1) == 0)
601 free(des);
602 }
603 }
604 pthread_mutex_unlock(&mux->mm_descrambler_lock);
605 }
606
607 static inline void
key_update(th_descrambler_runtime_t * dr,uint8_t key,int64_t timestamp)608 key_update( th_descrambler_runtime_t *dr, uint8_t key, int64_t timestamp )
609 {
610 /* set the even (0) or odd (0x40) key index */
611 dr->dr_key_index = key & 0x40;
612 if (dr->dr_key_start) {
613 dr->dr_key_interval = dr->dr_key_start + sec2mono(50) < timestamp ?
614 sec2mono(10) : timestamp - dr->dr_key_start;
615 dr->dr_key_start = timestamp;
616 } else {
617 /* We don't know the exact start key switch time */
618 dr->dr_key_start = timestamp - sec2mono(60);
619 }
620 }
621
622 static inline int
key_changed(th_descrambler_runtime_t * dr,uint8_t ki,int64_t timestamp)623 key_changed ( th_descrambler_runtime_t *dr, uint8_t ki, int64_t timestamp )
624 {
625 return dr->dr_key_index != (ki & 0x40) &&
626 dr->dr_key_start + sec2mono(2) < timestamp;
627 }
628
629 static inline int
key_valid(th_descrambler_runtime_t * dr,uint8_t ki)630 key_valid ( th_descrambler_runtime_t *dr, uint8_t ki )
631 {
632 /* 0x40 (for even) or 0x80 (for odd) */
633 uint8_t mask = ((ki & 0x40) + 0x40);
634 return dr->dr_key_valid & mask;
635 }
636
637 static inline int
key_late(th_descrambler_runtime_t * dr,uint8_t ki,int64_t timestamp)638 key_late( th_descrambler_runtime_t *dr, uint8_t ki, int64_t timestamp )
639 {
640 uint8_t kidx = (ki & 0x40) >> 6;
641 /* constcw - do not handle keys */
642 if (dr->dr_key_const)
643 return 0;
644 /* required key is older than previous? */
645 if (dr->dr_key_timestamp[kidx] < dr->dr_key_timestamp[kidx^1]) {
646 /* but don't take in account the keys modified just now */
647 if (dr->dr_key_timestamp[kidx^1] + 2 < timestamp)
648 goto late;
649 }
650 /* ECM was sent, but no new key was received */
651 if (dr->dr_ecm_last_key_time + sec2mono(2) < dr->dr_key_start &&
652 (!dr->dr_quick_ecm || dr->dr_ecm_start[kidx] + 4 < dr->dr_key_start)) {
653 late:
654 dr->dr_key_valid &= ~((ki & 0x40) + 0x40);
655 return 1;
656 }
657 return 0;
658 }
659
660 static inline int
key_started(th_descrambler_runtime_t * dr,uint8_t ki)661 key_started( th_descrambler_runtime_t *dr, uint8_t ki )
662 {
663 uint8_t kidx = (ki & 0x40) >> 6;
664 return mclk() - dr->dr_ecm_start[kidx] < sec2mono(5);
665 }
666
667 static int
ecm_reset(service_t * t,th_descrambler_runtime_t * dr)668 ecm_reset( service_t *t, th_descrambler_runtime_t *dr )
669 {
670 th_descrambler_t *td;
671 int ret = 0;
672
673 /* reset the reader ECM state */
674 LIST_FOREACH(td, &t->s_descramblers, td_service_link) {
675 if (!td->td_ecm_reset(td)) {
676 dr->dr_key_valid = 0;
677 ret = 1;
678 }
679 }
680 return ret;
681 }
682
683 int
descrambler_descramble(service_t * t,elementary_stream_t * st,const uint8_t * tsb,int len)684 descrambler_descramble ( service_t *t,
685 elementary_stream_t *st,
686 const uint8_t *tsb,
687 int len )
688 {
689 th_descrambler_t *td;
690 th_descrambler_runtime_t *dr = t->s_descramble;
691 th_descrambler_data_t *dd, *dd_next;
692 int count, failed, resolved, len2, len3, flush_data = 0;
693 uint32_t dbuflen;
694 const uint8_t *tsb2;
695 uint8_t ki;
696 sbuf_t *sb;
697
698 lock_assert(&t->s_stream_mutex);
699
700 if (dr == NULL || dr->dr_external) {
701 if ((tsb[3] & 0x80) == 0) {
702 ts_recv_packet0((mpegts_service_t *)t, st, tsb, len);
703 return 1;
704 }
705 return dr && dr->dr_external ? 1 : -1;
706 }
707
708 if (dr->dr_csa.csa_type == DESCRAMBLER_NONE && dr->dr_queue_total == 0)
709 if ((tsb[3] & 0x80) == 0) {
710 ts_recv_packet0((mpegts_service_t *)t, st, tsb, len);
711 return 1;
712 }
713
714 count = failed = resolved = 0;
715 LIST_FOREACH(td, &t->s_descramblers, td_service_link) {
716 count++;
717 switch (td->td_keystate) {
718 case DS_FORBIDDEN: failed++; break;
719 case DS_RESOLVED : resolved++; break;
720 default: break;
721 }
722 }
723
724 if (resolved) {
725
726 /* update the keys */
727 if (dr->dr_key_changed) {
728 dr->dr_csa.csa_flush(&dr->dr_csa, (mpegts_service_t *)t);
729 if (dr->dr_key_changed & 1)
730 tvhcsa_set_key_even(&dr->dr_csa, dr->dr_key_even);
731 if (dr->dr_key_changed & 2)
732 tvhcsa_set_key_odd(&dr->dr_csa, dr->dr_key_odd);
733 dr->dr_key_changed = 0;
734 }
735
736 /* process the queued TS packets */
737 if (dr->dr_queue_total > 0) {
738 descrambler_data_time_flush(dr, mclk() - (dr->dr_key_interval - sec2mono(2)));
739 for (dd = TAILQ_FIRST(&dr->dr_queue); dd; dd = dd_next) {
740 dd_next = TAILQ_NEXT(dd, dd_link);
741 sb = &dd->dd_sbuf;
742 tsb2 = sb->sb_data;
743 len2 = sb->sb_ptr;
744 for (; len2 > 0; tsb2 += len3, len2 -= len3) {
745 ki = tsb2[3];
746 if ((ki & 0x80) != 0x00) {
747 if (key_valid(dr, ki) == 0)
748 goto next;
749 if (key_changed(dr, ki, dd->dd_timestamp)) {
750 tvhtrace(LS_DESCRAMBLER, "stream key changed to %s for service \"%s\"",
751 (ki & 0x40) ? "odd" : "even",
752 ((mpegts_service_t *)t)->s_dvb_svcname);
753 if (key_late(dr, ki, dd->dd_timestamp)) {
754 descrambler_notify_nokey(dr);
755 if (ecm_reset(t, dr)) {
756 descrambler_data_cut(dr, tsb2 - sb->sb_data);
757 flush_data = 1;
758 goto next;
759 }
760 }
761 key_update(dr, ki, dd->dd_timestamp);
762 }
763 }
764 len3 = mpegts_word_count(tsb2, len2, 0xFF0000C0);
765 dr->dr_csa.csa_descramble(&dr->dr_csa, (mpegts_service_t *)t, tsb2, len3);
766 }
767 if (len2 == 0)
768 service_reset_streaming_status_flags(t, TSS_NO_ACCESS);
769 descrambler_data_destroy(dr, dd, 0);
770 }
771 }
772
773 /* check for key change */
774 ki = tsb[3];
775 if ((ki & 0x80) != 0x00) {
776 if (key_valid(dr, ki) == 0) {
777 if (!key_started(dr, ki) && tvhlog_limit(&dr->dr_loglimit_key, 10))
778 tvhwarn(LS_DESCRAMBLER, "%s %s",
779 ((mpegts_service_t *)t)->s_dvb_svcname,
780 (ki & 0x40) ? "odd stream key is not valid" :
781 "even stream key is not valid");
782 goto next;
783 }
784 if (key_changed(dr, ki, mclk())) {
785 tvhtrace(LS_DESCRAMBLER, "stream key changed to %s for service \"%s\"",
786 (ki & 0x40) ? "odd" : "even",
787 ((mpegts_service_t *)t)->s_dvb_svcname);
788 if (key_late(dr, ki, mclk())) {
789 tvherror(LS_DESCRAMBLER, "ECM - key late (%"PRId64" ms) for service \"%s\"",
790 mono2ms(mclk() - dr->dr_ecm_last_key_time),
791 ((mpegts_service_t *)t)->s_dvb_svcname);
792 descrambler_notify_nokey(dr);
793 if (ecm_reset(t, dr)) {
794 flush_data = 1;
795 goto next;
796 }
797 }
798 key_update(dr, ki, mclk());
799 }
800 }
801 dr->dr_skip = 1;
802 dr->dr_csa.csa_descramble(&dr->dr_csa, (mpegts_service_t *)t, tsb, len);
803 service_reset_streaming_status_flags(t, TSS_NO_ACCESS);
804 return 1;
805 }
806 next:
807 if (!dr->dr_skip) {
808 if (!dr->dr_force_skip)
809 dr->dr_force_skip = mclk() + sec2mono(30);
810 else if (dr->dr_force_skip < mclk())
811 dr->dr_skip = 1;
812 }
813 if (dr->dr_ecm_start[0] || dr->dr_ecm_start[1]) { /* ECM sent */
814 ki = tsb[3];
815 if ((ki & 0x80) != 0x00) {
816 if (dr->dr_key_start == 0) {
817 /* do not use the first TS packet to decide - it may be wrong */
818 while (dr->dr_queue_total > 20 * 188) {
819 if (descrambler_data_key_check(dr, ki & 0xc0, 20 * 188)) {
820 tvhtrace(LS_DESCRAMBLER, "initial stream key set to %s for service \"%s\"",
821 (ki & 0x40) ? "odd" : "even",
822 ((mpegts_service_t *)t)->s_dvb_svcname);
823 key_update(dr, ki, mclk());
824 break;
825 } else {
826 descrambler_data_cut(dr, 188);
827 }
828 }
829 } else if (dr->dr_key_index != (ki & 0x40) &&
830 dr->dr_key_start + sec2mono(2) < mclk()) {
831 tvhtrace(LS_DESCRAMBLER, "stream key changed to %s for service \"%s\"",
832 (ki & 0x40) ? "odd" : "even",
833 ((mpegts_service_t *)t)->s_dvb_svcname);
834 key_update(dr, ki, mclk());
835 }
836 }
837 if (count != failed) {
838 /*
839 * Fill a temporary buffer until the keys are known to make
840 * streaming faster.
841 */
842 dbuflen = MAX(300, config.descrambler_buffer);
843 if (dr->dr_queue_total >= dbuflen * 188) {
844 descrambler_data_cut(dr, MAX((dbuflen / 10) * 188, len));
845 if (dr->dr_last_err + sec2mono(10) < mclk()) {
846 dr->dr_last_err = mclk();
847 tvherror(LS_DESCRAMBLER, "cannot decode packets for service \"%s\"",
848 ((mpegts_service_t *)t)->s_dvb_svcname);
849 } else {
850 tvhtrace(LS_DESCRAMBLER, "cannot decode packets for service \"%s\"",
851 ((mpegts_service_t *)t)->s_dvb_svcname);
852 }
853 }
854 descrambler_data_append(dr, tsb, len);
855 service_set_streaming_status_flags(t, TSS_NO_ACCESS);
856 }
857 } else {
858 if (dr->dr_skip || count == 0)
859 ts_skip_packet2((mpegts_service_t *)dr->dr_service, tsb, len);
860 service_set_streaming_status_flags(t, TSS_NO_ACCESS);
861 }
862 if (flush_data)
863 descrambler_flush_table_data(t);
864 if (count && count == failed)
865 return -1;
866 return count;
867 }
868
869 static int
descrambler_table_callback(mpegts_table_t * mt,const uint8_t * ptr,int len,int tableid)870 descrambler_table_callback
871 (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid)
872 {
873 descrambler_table_t *dt = mt->mt_opaque;
874 descrambler_section_t *ds;
875 descrambler_ecmsec_t *des;
876 th_descrambler_runtime_t *dr;
877 LIST_HEAD(,descrambler_ecmsec) sections;
878 int emm = (mt->mt_flags & MT_FAST) == 0;
879
880 if (len < 6)
881 return 0;
882 LIST_INIT(§ions);
883 pthread_mutex_lock(&mt->mt_mux->mm_descrambler_lock);
884 TAILQ_FOREACH(ds, &dt->sections, link) {
885 if (!emm) {
886 LIST_FOREACH(des, &ds->ecmsecs, link)
887 if (des->number == ptr[4])
888 break;
889 } else {
890 des = LIST_FIRST(&ds->ecmsecs);
891 }
892 if (des == NULL) {
893 des = calloc(1, sizeof(*des));
894 des->number = emm ? 0 : ptr[4];
895 LIST_INSERT_HEAD(&ds->ecmsecs, des, link);
896 }
897 if (des->last_data == NULL || len != des->last_data_len ||
898 memcmp(des->last_data, ptr, len)) {
899 free(des->last_data);
900 des->last_data = malloc(len);
901 if (des->last_data) {
902 memcpy(des->last_data, ptr, len);
903 des->last_data_len = len;
904 } else {
905 des->last_data_len = 0;
906 }
907 des->changed = 2;
908 } else {
909 des->changed = des->last_data != NULL ? 1 : 0;
910 }
911 atomic_add(&des->refcnt, 1);
912 des->callback = ds->callback;
913 des->opaque = ds->opaque;
914 LIST_INSERT_HEAD(§ions, des, active_link);
915 }
916 pthread_mutex_unlock(&mt->mt_mux->mm_descrambler_lock);
917
918 LIST_FOREACH(des, §ions, active_link) {
919 if (des->changed == 2) {
920 des->callback(des->opaque, mt->mt_pid, ptr, len, emm);
921 if (!emm) { /* ECM */
922 mpegts_service_t *t = mt->mt_service;
923 if (t) {
924 pthread_mutex_lock(&t->s_stream_mutex);
925 /* The keys are requested from this moment */
926 dr = t->s_descramble;
927 if (dr) {
928 if (!dr->dr_quick_ecm && !des->quick_ecm_called) {
929 des->quick_ecm_called = 1;
930 dr->dr_quick_ecm = descrambler_quick_ecm(mt->mt_service, mt->mt_pid);
931 if (dr->dr_quick_ecm)
932 tvhdebug(LS_DESCRAMBLER, "quick ECM enabled for service '%s'",
933 t->s_dvb_svcname);
934 }
935 if ((ptr[0] & 0xfe) == 0x80) { /* 0x80 = even, 0x81 = odd */
936 dr->dr_ecm_start[ptr[0] & 1] = mclk();
937 if (dr->dr_quick_ecm)
938 dr->dr_key_valid &= ~(1 << ((ptr[0] & 1) + 6)); /* 0x40 = even, 0x80 = odd */
939 }
940 tvhtrace(LS_DESCRAMBLER, "ECM message %02x (section %d, len %d, pid %d) for service \"%s\"",
941 ptr[0], des->number, len, mt->mt_pid, t->s_dvb_svcname);
942 }
943 pthread_mutex_unlock(&t->s_stream_mutex);
944 } else
945 tvhtrace(LS_DESCRAMBLER, "Unknown fast table message %02x (section %d, len %d, pid %d)",
946 ptr[0], des->number, len, mt->mt_pid);
947 } else if (tvhtrace_enabled()) {
948 const char *s;
949 if (mt->mt_pid == DVB_PAT_PID) s = "PAT";
950 else if (mt->mt_pid == DVB_CAT_PID) s = "CAT";
951 else s = "EMM";
952 if (len >= 18)
953 tvhtrace(LS_DESCRAMBLER_EMM, "%s message %02x:{%02x:%02x}:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x (len %d, pid %d)",
954 s, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7],
955 ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15],
956 ptr[16], ptr[17], len, mt->mt_pid);
957 else if (len >= 6)
958 tvhtrace(LS_DESCRAMBLER_EMM, "%s message %02x:{%02x:%02x}:%02x:%02x:%02x (len %d, pid %d)",
959 s, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], len, mt->mt_pid);
960 else if (len >= 4)
961 tvhtrace(LS_DESCRAMBLER_EMM, "%s message %02x:{%02x:%02x}:%02x (len %d, pid %d)",
962 s, ptr[0], ptr[1], ptr[2], ptr[3], len, mt->mt_pid);
963 }
964 }
965 }
966
967 while ((des = LIST_FIRST(§ions)) != NULL) {
968 LIST_REMOVE(des, active_link);
969 if (atomic_dec(&des->refcnt, 1) == 0)
970 free(des);
971 }
972 return 0;
973 }
974
975 static int
descrambler_open_pid_(mpegts_mux_t * mux,void * opaque,int pid,descrambler_section_callback_t callback,service_t * service)976 descrambler_open_pid_( mpegts_mux_t *mux, void *opaque, int pid,
977 descrambler_section_callback_t callback,
978 service_t *service )
979 {
980 descrambler_table_t *dt;
981 descrambler_section_t *ds;
982 int flags;
983
984 if (mux == NULL)
985 return 0;
986 if (mux->mm_descrambler_flush)
987 return 0;
988 flags = (pid >> 16) & MT_FAST;
989 pid &= 0x1fff;
990 TAILQ_FOREACH(dt, &mux->mm_descrambler_tables, link) {
991 if (dt->table->mt_pid != pid || (dt->table->mt_flags & MT_FAST) != flags)
992 continue;
993 TAILQ_FOREACH(ds, &dt->sections, link) {
994 if (ds->opaque == opaque)
995 return 0;
996 }
997 break;
998 }
999 if (!dt) {
1000 dt = calloc(1, sizeof(*dt));
1001 TAILQ_INIT(&dt->sections);
1002 dt->table = mpegts_table_add(mux, 0, 0, descrambler_table_callback,
1003 dt, (flags & MT_FAST) ? "ecm" : "emm",
1004 LS_TBL_CSA, MT_FULL | MT_DEFER | flags, pid,
1005 MPS_WEIGHT_CA);
1006 if (dt->table)
1007 dt->table->mt_service = (mpegts_service_t *)service;
1008 TAILQ_INSERT_TAIL(&mux->mm_descrambler_tables, dt, link);
1009 }
1010 ds = calloc(1, sizeof(*ds));
1011 ds->callback = callback;
1012 ds->opaque = opaque;
1013 LIST_INIT(&ds->ecmsecs);
1014 TAILQ_INSERT_TAIL(&dt->sections, ds, link);
1015 tvhtrace(LS_DESCRAMBLER, "mux %p open pid %04X (%i) (flags 0x%04x) for %p", mux, pid, pid, flags, opaque);
1016 return 1;
1017 }
1018
1019 int
descrambler_open_pid(mpegts_mux_t * mux,void * opaque,int pid,descrambler_section_callback_t callback,service_t * service)1020 descrambler_open_pid( mpegts_mux_t *mux, void *opaque, int pid,
1021 descrambler_section_callback_t callback,
1022 service_t *service )
1023 {
1024 int res;
1025
1026 pthread_mutex_lock(&mux->mm_descrambler_lock);
1027 res = descrambler_open_pid_(mux, opaque, pid, callback, service);
1028 pthread_mutex_unlock(&mux->mm_descrambler_lock);
1029 return res;
1030 }
1031
1032 static int
descrambler_close_pid_(mpegts_mux_t * mux,void * opaque,int pid)1033 descrambler_close_pid_( mpegts_mux_t *mux, void *opaque, int pid )
1034 {
1035 descrambler_table_t *dt;
1036 descrambler_section_t *ds;
1037 descrambler_ecmsec_t *des;
1038 int flags;
1039
1040 if (mux == NULL)
1041 return 0;
1042 flags = (pid >> 16) & MT_FAST;
1043 pid &= 0x1fff;
1044 TAILQ_FOREACH(dt, &mux->mm_descrambler_tables, link) {
1045 if (dt->table->mt_pid != pid || (dt->table->mt_flags & MT_FAST) != flags)
1046 continue;
1047 TAILQ_FOREACH(ds, &dt->sections, link) {
1048 if (ds->opaque == opaque) {
1049 TAILQ_REMOVE(&dt->sections, ds, link);
1050 ds->callback(ds->opaque, -1, NULL, 0, (flags & MT_FAST) == 0);
1051 while ((des = LIST_FIRST(&ds->ecmsecs)) != NULL) {
1052 LIST_REMOVE(des, link);
1053 free(des->last_data);
1054 if (atomic_dec(&des->refcnt, 1) == 0)
1055 free(des);
1056 }
1057 if (TAILQ_FIRST(&dt->sections) == NULL) {
1058 TAILQ_REMOVE(&mux->mm_descrambler_tables, dt, link);
1059 mpegts_table_destroy(dt->table);
1060 free(dt);
1061 }
1062 free(ds);
1063 tvhtrace(LS_DESCRAMBLER, "mux %p close pid %04X (%i) (flags 0x%04x) for %p", mux, pid, pid, flags, opaque);
1064 return 1;
1065 }
1066 }
1067 }
1068 return 0;
1069 }
1070
1071 int
descrambler_close_pid(mpegts_mux_t * mux,void * opaque,int pid)1072 descrambler_close_pid( mpegts_mux_t *mux, void *opaque, int pid )
1073 {
1074 int res;
1075
1076 pthread_mutex_lock(&mux->mm_descrambler_lock);
1077 res = descrambler_close_pid_(mux, opaque, pid);
1078 pthread_mutex_unlock(&mux->mm_descrambler_lock);
1079 return res;
1080 }
1081
1082 void
descrambler_flush_tables(mpegts_mux_t * mux)1083 descrambler_flush_tables( mpegts_mux_t *mux )
1084 {
1085 descrambler_table_t *dt;
1086 descrambler_section_t *ds;
1087 descrambler_ecmsec_t *des;
1088 descrambler_emm_t *emm;
1089
1090 if (mux == NULL)
1091 return;
1092 tvhtrace(LS_DESCRAMBLER, "mux %p - flush tables", mux);
1093 caclient_caid_update(mux, 0, 0, -1);
1094 pthread_mutex_lock(&mux->mm_descrambler_lock);
1095 mux->mm_descrambler_flush = 1;
1096 while ((dt = TAILQ_FIRST(&mux->mm_descrambler_tables)) != NULL) {
1097 while ((ds = TAILQ_FIRST(&dt->sections)) != NULL) {
1098 TAILQ_REMOVE(&dt->sections, ds, link);
1099 ds->callback(ds->opaque, -1, NULL, 0, (dt->table->mt_flags & MT_FAST) ? 0 : 1);
1100 while ((des = LIST_FIRST(&ds->ecmsecs)) != NULL) {
1101 LIST_REMOVE(des, link);
1102 free(des->last_data);
1103 if (atomic_dec(&des->refcnt, 1) == 0)
1104 free(des);
1105 }
1106 free(ds);
1107 }
1108 TAILQ_REMOVE(&mux->mm_descrambler_tables, dt, link);
1109 mpegts_table_destroy(dt->table);
1110 free(dt);
1111 }
1112 while ((emm = TAILQ_FIRST(&mux->mm_descrambler_emms)) != NULL) {
1113 TAILQ_REMOVE(&mux->mm_descrambler_emms, emm, link);
1114 free(emm);
1115 }
1116 pthread_mutex_unlock(&mux->mm_descrambler_lock);
1117 }
1118
1119 void
descrambler_cat_data(mpegts_mux_t * mux,const uint8_t * data,int len)1120 descrambler_cat_data( mpegts_mux_t *mux, const uint8_t *data, int len )
1121 {
1122 descrambler_emm_t *emm;
1123 uint8_t dtag, dlen;
1124 uint16_t caid = 0, pid = 0;
1125 TAILQ_HEAD(,descrambler_emm) removing;
1126
1127 tvhtrace(LS_DESCRAMBLER, "CAT data (len %d)", len);
1128 tvhlog_hexdump(LS_DESCRAMBLER, data, len);
1129 pthread_mutex_lock(&mux->mm_descrambler_lock);
1130 TAILQ_FOREACH(emm, &mux->mm_descrambler_emms, link)
1131 emm->to_be_removed = 1;
1132 pthread_mutex_unlock(&mux->mm_descrambler_lock);
1133 while (len > 2) {
1134 if (len > 2) {
1135 dtag = *data++;
1136 dlen = *data++;
1137 len -= 2;
1138 if (dtag != DVB_DESC_CA || len < 4 || dlen < 4)
1139 goto next;
1140 caid = (data[0] << 8) | data[1];
1141 pid = ((data[2] << 8) | data[3]) & 0x1fff;
1142 if (pid == 0)
1143 goto next;
1144 caclient_caid_update(mux, caid, pid, 1);
1145 pthread_mutex_lock(&mux->mm_descrambler_lock);
1146 TAILQ_FOREACH(emm, &mux->mm_descrambler_emms, link)
1147 if (emm->caid == caid) {
1148 emm->to_be_removed = 0;
1149 if (emm->pid == EMM_PID_UNKNOWN) {
1150 tvhtrace(LS_DESCRAMBLER, "attach emm caid %04X (%i) pid %04X (%i)", caid, caid, pid, pid);
1151 emm->pid = pid;
1152 descrambler_open_pid_(mux, emm->opaque, pid, emm->callback, NULL);
1153 }
1154 }
1155 pthread_mutex_unlock(&mux->mm_descrambler_lock);
1156 next:
1157 data += dlen;
1158 len -= dlen;
1159 }
1160 }
1161 TAILQ_INIT(&removing);
1162 pthread_mutex_lock(&mux->mm_descrambler_lock);
1163 TAILQ_FOREACH(emm, &mux->mm_descrambler_emms, link)
1164 if (emm->to_be_removed) {
1165 if (emm->pid != EMM_PID_UNKNOWN) {
1166 caid = emm->caid;
1167 pid = emm->pid;
1168 tvhtrace(LS_DESCRAMBLER, "close emm caid %04X (%i) pid %04X (%i)", caid, caid, pid, pid);
1169 descrambler_close_pid_(mux, emm->opaque, pid);
1170 }
1171 TAILQ_REMOVE(&mux->mm_descrambler_emms, emm, link);
1172 TAILQ_INSERT_TAIL(&removing, emm, link);
1173 }
1174 pthread_mutex_unlock(&mux->mm_descrambler_lock);
1175 while ((emm = TAILQ_FIRST(&removing)) != NULL) {
1176 if (emm->pid != EMM_PID_UNKNOWN)
1177 caclient_caid_update(mux, emm->caid, emm->pid, 0);
1178 TAILQ_REMOVE(&removing, emm, link);
1179 free(emm);
1180 }
1181 }
1182
1183 int
descrambler_open_emm(mpegts_mux_t * mux,void * opaque,int caid,descrambler_section_callback_t callback)1184 descrambler_open_emm( mpegts_mux_t *mux, void *opaque, int caid,
1185 descrambler_section_callback_t callback )
1186 {
1187 descrambler_emm_t *emm;
1188 caid_t *c;
1189 int pid = EMM_PID_UNKNOWN;
1190
1191 if (mux == NULL)
1192 return 0;
1193 pthread_mutex_lock(&mux->mm_descrambler_lock);
1194 if (mux->mm_descrambler_flush)
1195 goto unlock;
1196 TAILQ_FOREACH(emm, &mux->mm_descrambler_emms, link) {
1197 if (emm->caid == caid && emm->opaque == opaque) {
1198 unlock:
1199 pthread_mutex_unlock(&mux->mm_descrambler_lock);
1200 return 0;
1201 }
1202 }
1203 emm = calloc(1, sizeof(*emm));
1204 emm->caid = caid;
1205 emm->pid = EMM_PID_UNKNOWN;
1206 emm->opaque = opaque;
1207 emm->callback = callback;
1208 LIST_FOREACH(c, &mux->mm_descrambler_caids, link) {
1209 if (c->caid == caid) {
1210 emm->pid = pid = c->pid;
1211 break;
1212 }
1213 }
1214 TAILQ_INSERT_TAIL(&mux->mm_descrambler_emms, emm, link);
1215 if (pid != EMM_PID_UNKNOWN) {
1216 tvhtrace(LS_DESCRAMBLER,
1217 "attach emm caid %04X (%i) pid %04X (%i) - direct",
1218 caid, caid, pid, pid);
1219 descrambler_open_pid_(mux, opaque, pid, callback, NULL);
1220 }
1221 pthread_mutex_unlock(&mux->mm_descrambler_lock);
1222 return 1;
1223 }
1224
1225 int
descrambler_close_emm(mpegts_mux_t * mux,void * opaque,int caid)1226 descrambler_close_emm( mpegts_mux_t *mux, void *opaque, int caid )
1227 {
1228 descrambler_emm_t *emm;
1229 int pid;
1230
1231 if (mux == NULL)
1232 return 0;
1233 pthread_mutex_lock(&mux->mm_descrambler_lock);
1234 TAILQ_FOREACH(emm, &mux->mm_descrambler_emms, link)
1235 if (emm->caid == caid && emm->opaque == opaque)
1236 break;
1237 if (!emm) {
1238 pthread_mutex_unlock(&mux->mm_descrambler_lock);
1239 return 0;
1240 }
1241 TAILQ_REMOVE(&mux->mm_descrambler_emms, emm, link);
1242 pid = emm->pid;
1243 if (pid != EMM_PID_UNKNOWN) {
1244 caid = emm->caid;
1245 tvhtrace(LS_DESCRAMBLER, "close emm caid %04X (%i) pid %04X (%i) - direct", caid, caid, pid, pid);
1246 descrambler_close_pid_(mux, opaque, pid);
1247 }
1248 pthread_mutex_unlock(&mux->mm_descrambler_lock);
1249 free(emm);
1250 return 1;
1251 }
1252
1253 /* **************************************************************************
1254 * Editor
1255 *
1256 * vim:sts=2:ts=2:sw=2:et
1257 * *************************************************************************/
1258