diff -Naur hts-tvheadend-2.10-orig/src/cwc.c hts-tvheadend-2.10/src/cwc.c --- hts-tvheadend-2.10-orig/src/cwc.c 2010-03-10 13:50:33.998141272 +0100 +++ hts-tvheadend-2.10/src/cwc.c 2010-03-10 13:46:19.498415050 +0100 @@ -1,6 +1,6 @@ /* * tvheadend, CWC interface - * Copyright (C) 2007 Andreas Öman + * Copyright (C) 2007 Andreas Vman * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -72,6 +72,16 @@ MSG_KEEPALIVE = CWS_FIRSTCMDNO + 0x1d } net_msg_type_t; +typedef enum { + CARD_IRDETO, + CARD_SECA, + CARD_CONAX, + CARD_NDS, + CARD_VIA, + CARD_CRYPTOWORKS, + CARD_NAGRA2, + CARD_UNKNOWN +} card_type_t; /** * @@ -194,6 +204,9 @@ /* Emm forwarding */ int cwc_forward_emm; + + /* Card type */ + card_type_t cwc_card_type; /* From configuration */ @@ -222,6 +235,10 @@ static void cwc_transport_destroy(th_descrambler_t *td); extern char *cwc_krypt(const char *key, const char *salt); +static void cwc_detect_card_type(cwc_t *cwc); + +void cwc_emm_conax(cwc_t *cwc, uint8_t *data, int len); +void cwc_emm_irdeto(cwc_t *cwc, uint8_t *data, int len); /** * @@ -374,6 +391,68 @@ } /** + * Detects the cam card type + * Card bytes are from sasc-ng + */ +static void +cwc_detect_card_type(cwc_t *cwc) +{ + unsigned short c_sys = cwc->cwc_caid >> 8; + + tvhlog(LOG_INFO, "cwc", "%s: Checking card type", + cwc->cwc_hostname); + + switch (c_sys) + { + case 0x17: + case 0x06: + cwc->cwc_card_type = CARD_IRDETO; + tvhlog(LOG_INFO, "cwc", "%s: irdeto card", + cwc->cwc_hostname); + break; + case 0x01: + cwc->cwc_card_type = CARD_SECA; + tvhlog(LOG_INFO, "cwc", "%s: seca card", + cwc->cwc_hostname); + break; + case 0x0b: + cwc->cwc_card_type = CARD_CONAX; + tvhlog(LOG_INFO, "cwc", "%s: conax card", + cwc->cwc_hostname); + break; + case 0x09: + cwc->cwc_card_type = CARD_NDS; + tvhlog(LOG_INFO, "cwc", "%s: nds card", + cwc->cwc_hostname); + break; + case 0x05: + cwc->cwc_card_type = CARD_VIA; + tvhlog(LOG_INFO, "cwc", "%s: via card", + cwc->cwc_hostname); + break; + case 0x0d: + cwc->cwc_card_type = CARD_CRYPTOWORKS; + tvhlog(LOG_INFO, "cwc", "%s: cryptoworks card", + cwc->cwc_hostname); + break; + case 0x12: + case 0x18: + if(cwc->cwc_caid >= 0x1801 || cwc->cwc_caid == 0x1234) + { + cwc->cwc_card_type = CARD_NAGRA2; + tvhlog(LOG_INFO, "cwc", "%s: nagra2 card", + cwc->cwc_hostname); + break; + } + // not a nagra2 card; defaulting to unknown + default: + cwc->cwc_card_type = CARD_UNKNOWN; + tvhlog(LOG_INFO, "cwc", "%s: unknown card", + cwc->cwc_hostname); + } +} + +/** * Note, this function is called from multiple threads so beware of * locking / race issues (Note how we use atomic_add() to generate * the ID) @@ -542,25 +621,38 @@ msg += 11; } - cwc->cwc_forward_emm = 0; - if (cwc->cwc_emm) { - int emm_allowed = (cwc->cwc_ua[0] || cwc->cwc_ua[1] || + cwc_detect_card_type(cwc); + + cwc->cwc_forward_emm = 0; + if (cwc->cwc_emm) + { + int emm_allowed = (cwc->cwc_ua[0] || cwc->cwc_ua[1] || cwc->cwc_ua[2] || cwc->cwc_ua[3] || cwc->cwc_ua[4] || cwc->cwc_ua[5] || cwc->cwc_ua[6] || cwc->cwc_ua[7]); - if (!emm_allowed) - tvhlog(LOG_INFO, "cwc", "%s: Will not forward EMMs (not allowed by server)", - cwc->cwc_hostname); - else if ((cwc->cwc_caid>>8) != 0x0b) - tvhlog(LOG_INFO, "cwc", "%s: Will not forward EMMs (unsupported ca system)", - cwc->cwc_hostname); - else { - tvhlog(LOG_INFO, "cwc", "%s: Will forward EMMs", - cwc->cwc_hostname); - cwc->cwc_forward_emm = 1; - } - } + if (!emm_allowed) + { + tvhlog(LOG_INFO, "cwc", "%s: Will not forward EMMs (not allowed by server)", + cwc->cwc_hostname); + } + else + { + if (cwc->cwc_card_type == CARD_CONAX || + cwc->cwc_card_type == CARD_IRDETO) + { + cwc->cwc_forward_emm = 1; + + tvhlog(LOG_INFO, "cwc", "%s: Will forward EMMs", + cwc->cwc_hostname); + } + else + { + tvhlog(LOG_INFO, "cwc", "%s: Will not forward EMMs (unsupported ca system)", + cwc->cwc_hostname); + } + } + } return 0; } @@ -1022,25 +1114,48 @@ /** - * + * conax emm handler + */ +void cwc_emm_conax(cwc_t *cwc, uint8_t *data, int len) +{ + if (data[0] == 0x82) + { + int i; + for (i=0; i < cwc->cwc_num_providers; i++) + if (memcmp(&data[3], &cwc->cwc_providers[i].sa[1], 7) == 0) + { + cwc_send_msg(cwc, data, len, 0, 1); + break; + } + } +} + +/** + * conax emm handler + */ +void cwc_emm_irdeto(cwc_t *cwc, uint8_t *data, int len) +{ + // TODO: stub! +} + +/** + * Handles emm data received from the dvb stream */ void cwc_emm(uint8_t *data, int len) { - cwc_t *cwc; + cwc_t *cwc; - lock_assert(&global_lock); + lock_assert(&global_lock); - TAILQ_FOREACH(cwc, &cwcs, cwc_link) - if(cwc->cwc_forward_emm && cwc->cwc_writer_running && - data[0] == 0x82 /* Conax */ ) { - int i; - for (i=0; i < cwc->cwc_num_providers; i++) - if (memcmp(&data[3], &cwc->cwc_providers[i].sa[1], 7) == 0) { - cwc_send_msg(cwc, data, len, 0, 1); - break; - } - } + TAILQ_FOREACH(cwc, &cwcs, cwc_link) + if(cwc->cwc_forward_emm && cwc->cwc_writer_running) + { + if (cwc->cwc_card_type == CARD_CONAX) + cwc_emm_conax(cwc, data, len); + else if (cwc->cwc_card_type == CARD_IRDETO) + cwc_emm_irdeto(cwc, data, len); + } }