1 |
1 |
/*
|
2 |
2 |
* tvheadend, CWC interface
|
3 |
|
* Copyright (C) 2007 Andreas ?man
|
|
3 |
* Copyright (C) 2007 Andreas Vman
|
4 |
4 |
*
|
5 |
5 |
* This program is free software: you can redistribute it and/or modify
|
6 |
6 |
* it under the terms of the GNU General Public License as published by
|
... | ... | |
72 |
72 |
MSG_KEEPALIVE = CWS_FIRSTCMDNO + 0x1d
|
73 |
73 |
} net_msg_type_t;
|
74 |
74 |
|
|
75 |
typedef enum {
|
|
76 |
CARD_IRDETO,
|
|
77 |
CARD_SECA,
|
|
78 |
CARD_CONAX,
|
|
79 |
CARD_NDS,
|
|
80 |
CARD_VIA,
|
|
81 |
CARD_CRYPTOWORKS,
|
|
82 |
CARD_NAGRA2,
|
|
83 |
CARD_UNKNOWN
|
|
84 |
} card_type_t;
|
75 |
85 |
|
76 |
86 |
/**
|
77 |
87 |
*
|
... | ... | |
194 |
204 |
|
195 |
205 |
/* Emm forwarding */
|
196 |
206 |
int cwc_forward_emm;
|
|
207 |
|
|
208 |
/* Card type */
|
|
209 |
card_type_t cwc_card_type;
|
197 |
210 |
|
198 |
211 |
/* From configuration */
|
199 |
212 |
|
... | ... | |
222 |
235 |
static void cwc_transport_destroy(th_descrambler_t *td);
|
223 |
236 |
extern char *cwc_krypt(const char *key, const char *salt);
|
224 |
237 |
|
|
238 |
static void cwc_detect_card_type(cwc_t *cwc);
|
|
239 |
|
|
240 |
void cwc_emm_conax(cwc_t *cwc, uint8_t *data, int len);
|
|
241 |
void cwc_emm_irdeto(cwc_t *cwc, uint8_t *data, int len);
|
225 |
242 |
|
226 |
243 |
/**
|
227 |
244 |
*
|
... | ... | |
374 |
391 |
}
|
375 |
392 |
|
376 |
393 |
/**
|
|
394 |
* Detects the cam card type
|
|
395 |
* Card bytes are from sasc-ng
|
|
396 |
*/
|
|
397 |
static void
|
|
398 |
cwc_detect_card_type(cwc_t *cwc)
|
|
399 |
{
|
|
400 |
unsigned short c_sys = cwc->cwc_caid >> 8;
|
|
401 |
|
|
402 |
tvhlog(LOG_INFO, "cwc", "%s: Checking card type",
|
|
403 |
cwc->cwc_hostname);
|
|
404 |
|
|
405 |
switch (c_sys)
|
|
406 |
{
|
|
407 |
case 0x17:
|
|
408 |
case 0x06:
|
|
409 |
cwc->cwc_card_type = CARD_IRDETO;
|
|
410 |
tvhlog(LOG_INFO, "cwc", "%s: irdeto card",
|
|
411 |
cwc->cwc_hostname);
|
|
412 |
break;
|
|
413 |
case 0x01:
|
|
414 |
cwc->cwc_card_type = CARD_SECA;
|
|
415 |
tvhlog(LOG_INFO, "cwc", "%s: seca card",
|
|
416 |
cwc->cwc_hostname);
|
|
417 |
break;
|
|
418 |
case 0x0b:
|
|
419 |
cwc->cwc_card_type = CARD_CONAX;
|
|
420 |
tvhlog(LOG_INFO, "cwc", "%s: conax card",
|
|
421 |
cwc->cwc_hostname);
|
|
422 |
break;
|
|
423 |
case 0x09:
|
|
424 |
cwc->cwc_card_type = CARD_NDS;
|
|
425 |
tvhlog(LOG_INFO, "cwc", "%s: nds card",
|
|
426 |
cwc->cwc_hostname);
|
|
427 |
break;
|
|
428 |
case 0x05:
|
|
429 |
cwc->cwc_card_type = CARD_VIA;
|
|
430 |
tvhlog(LOG_INFO, "cwc", "%s: via card",
|
|
431 |
cwc->cwc_hostname);
|
|
432 |
break;
|
|
433 |
case 0x0d:
|
|
434 |
cwc->cwc_card_type = CARD_CRYPTOWORKS;
|
|
435 |
tvhlog(LOG_INFO, "cwc", "%s: cryptoworks card",
|
|
436 |
cwc->cwc_hostname);
|
|
437 |
break;
|
|
438 |
case 0x12:
|
|
439 |
case 0x18:
|
|
440 |
if(cwc->cwc_caid >= 0x1801 || cwc->cwc_caid == 0x1234)
|
|
441 |
{
|
|
442 |
cwc->cwc_card_type = CARD_NAGRA2;
|
|
443 |
tvhlog(LOG_INFO, "cwc", "%s: nagra2 card",
|
|
444 |
cwc->cwc_hostname);
|
|
445 |
break;
|
|
446 |
}
|
|
447 |
// not a nagra2 card; defaulting to unknown
|
|
448 |
default:
|
|
449 |
cwc->cwc_card_type = CARD_UNKNOWN;
|
|
450 |
tvhlog(LOG_INFO, "cwc", "%s: unknown card",
|
|
451 |
cwc->cwc_hostname);
|
|
452 |
}
|
|
453 |
}
|
|
454 |
|
|
455 |
/**
|
377 |
456 |
* Note, this function is called from multiple threads so beware of
|
378 |
457 |
* locking / race issues (Note how we use atomic_add() to generate
|
379 |
458 |
* the ID)
|
... | ... | |
542 |
621 |
msg += 11;
|
543 |
622 |
}
|
544 |
623 |
|
545 |
|
cwc->cwc_forward_emm = 0;
|
546 |
|
if (cwc->cwc_emm) {
|
547 |
|
int emm_allowed = (cwc->cwc_ua[0] || cwc->cwc_ua[1] ||
|
|
624 |
cwc_detect_card_type(cwc);
|
|
625 |
|
|
626 |
cwc->cwc_forward_emm = 0;
|
|
627 |
if (cwc->cwc_emm)
|
|
628 |
{
|
|
629 |
int emm_allowed = (cwc->cwc_ua[0] || cwc->cwc_ua[1] ||
|
548 |
630 |
cwc->cwc_ua[2] || cwc->cwc_ua[3] ||
|
549 |
631 |
cwc->cwc_ua[4] || cwc->cwc_ua[5] ||
|
550 |
632 |
cwc->cwc_ua[6] || cwc->cwc_ua[7]);
|
551 |
633 |
|
552 |
|
if (!emm_allowed)
|
553 |
|
tvhlog(LOG_INFO, "cwc", "%s: Will not forward EMMs (not allowed by server)",
|
554 |
|
cwc->cwc_hostname);
|
555 |
|
else if ((cwc->cwc_caid>>8) != 0x0b)
|
556 |
|
tvhlog(LOG_INFO, "cwc", "%s: Will not forward EMMs (unsupported ca system)",
|
557 |
|
cwc->cwc_hostname);
|
558 |
|
else {
|
559 |
|
tvhlog(LOG_INFO, "cwc", "%s: Will forward EMMs",
|
560 |
|
cwc->cwc_hostname);
|
561 |
|
cwc->cwc_forward_emm = 1;
|
562 |
|
}
|
563 |
|
}
|
|
634 |
if (!emm_allowed)
|
|
635 |
{
|
|
636 |
tvhlog(LOG_INFO, "cwc", "%s: Will not forward EMMs (not allowed by server)",
|
|
637 |
cwc->cwc_hostname);
|
|
638 |
}
|
|
639 |
else
|
|
640 |
{
|
|
641 |
if (cwc->cwc_card_type == CARD_CONAX ||
|
|
642 |
cwc->cwc_card_type == CARD_IRDETO)
|
|
643 |
{
|
|
644 |
cwc->cwc_forward_emm = 1;
|
|
645 |
|
|
646 |
tvhlog(LOG_INFO, "cwc", "%s: Will forward EMMs",
|
|
647 |
cwc->cwc_hostname);
|
|
648 |
}
|
|
649 |
else
|
|
650 |
{
|
|
651 |
tvhlog(LOG_INFO, "cwc", "%s: Will not forward EMMs (unsupported ca system)",
|
|
652 |
cwc->cwc_hostname);
|
|
653 |
}
|
|
654 |
}
|
|
655 |
}
|
564 |
656 |
|
565 |
657 |
return 0;
|
566 |
658 |
}
|
... | ... | |
1022 |
1114 |
|
1023 |
1115 |
|
1024 |
1116 |
/**
|
1025 |
|
*
|
|
1117 |
* conax emm handler
|
|
1118 |
*/
|
|
1119 |
void cwc_emm_conax(cwc_t *cwc, uint8_t *data, int len)
|
|
1120 |
{
|
|
1121 |
if (data[0] == 0x82)
|
|
1122 |
{
|
|
1123 |
int i;
|
|
1124 |
for (i=0; i < cwc->cwc_num_providers; i++)
|
|
1125 |
if (memcmp(&data[3], &cwc->cwc_providers[i].sa[1], 7) == 0)
|
|
1126 |
{
|
|
1127 |
cwc_send_msg(cwc, data, len, 0, 1);
|
|
1128 |
break;
|
|
1129 |
}
|
|
1130 |
}
|
|
1131 |
}
|
|
1132 |
|
|
1133 |
/**
|
|
1134 |
* conax emm handler
|
|
1135 |
*/
|
|
1136 |
void cwc_emm_irdeto(cwc_t *cwc, uint8_t *data, int len)
|
|
1137 |
{
|
|
1138 |
// TODO: stub!
|
|
1139 |
}
|
|
1140 |
|
|
1141 |
/**
|
|
1142 |
* Handles emm data received from the dvb stream
|
1026 |
1143 |
*/
|
1027 |
1144 |
void
|
1028 |
1145 |
cwc_emm(uint8_t *data, int len)
|
1029 |
1146 |
{
|
1030 |
|
cwc_t *cwc;
|
|
1147 |
cwc_t *cwc;
|
1031 |
1148 |
|
1032 |
|
lock_assert(&global_lock);
|
|
1149 |
lock_assert(&global_lock);
|
1033 |
1150 |
|
1034 |
|
TAILQ_FOREACH(cwc, &cwcs, cwc_link)
|
1035 |
|
if(cwc->cwc_forward_emm && cwc->cwc_writer_running &&
|
1036 |
|
data[0] == 0x82 /* Conax */ ) {
|
1037 |
|
int i;
|
1038 |
|
for (i=0; i < cwc->cwc_num_providers; i++)
|
1039 |
|
if (memcmp(&data[3], &cwc->cwc_providers[i].sa[1], 7) == 0) {
|
1040 |
|
cwc_send_msg(cwc, data, len, 0, 1);
|
1041 |
|
break;
|
1042 |
|
}
|
1043 |
|
}
|
|
1151 |
TAILQ_FOREACH(cwc, &cwcs, cwc_link)
|
|
1152 |
if(cwc->cwc_forward_emm && cwc->cwc_writer_running)
|
|
1153 |
{
|
|
1154 |
if (cwc->cwc_card_type == CARD_CONAX)
|
|
1155 |
cwc_emm_conax(cwc, data, len);
|
|
1156 |
else if (cwc->cwc_card_type == CARD_IRDETO)
|
|
1157 |
cwc_emm_irdeto(cwc, data, len);
|
|
1158 |
}
|
1044 |
1159 |
}
|
1045 |
1160 |
|
1046 |
1161 |
|