/decrypt/decrypt.c
C | 740 lines | 666 code | 54 blank | 20 comment | 171 complexity | 33ac1a858f6f023fb3e846a35a15e7a3 MD5 | raw file
Possible License(s): GPL-2.0
- /*
- * Author: 2010 Andrey Dyldin <and@andmicro.com>
- * 2010 Santa77 <santa77@fibercom.sk>
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdint.h>
- #include <unistd.h>
- #include "decrypt.h"
- #include "config.h"
- #include "../getstream.h"
- void getEmmPid(struct decrypt_s *decrypt, uint8_t *payload, uint16_t pid)
- {
- if(!payload || !decrypt->cam->loginOk)
- return;
- struct pid_s *pids = decrypt->stream->pids;
- struct ca_s *t = (struct ca_s *)pids[pid].data;
- if(t->caid == decrypt->cam->caId)
- pids[pid].type = MYEMM;
- else
- pids[pid].type = XEMM;
- }
- uint8_t viaccess_emm_check(struct decrypt_s *decrypt, uint8_t *payload)
- {
- switch(payload[0])
- {
- case 0x8E: // EMM-S (part2)
- return !memcmp(&payload[3], &decrypt->prov_id[4], 3);
- case 0x8C:
- case 0x8D: // EMM-GH (part1)
- return ((payload[3] == 0x90 || payload[3] == 0x40) && payload[4] == 0x03)
- && payload[5] == decrypt->prov_ident[0]
- && payload[6] == decrypt->prov_ident[1]
- && (payload[7] & 0xF0) == decrypt->prov_ident[2];
- case 0x88: // EMM-Unique
- return !memcmp(&payload[3], &decrypt->cam->ua[3], 5);
- case 0x8a: // EMM-Global
- case 0x8b: // EMM-Global
- return 1;
- default:
- break;
- }
- return 0; // false
- }
- uint8_t dre_emm_check(struct decrypt_s *decrypt, uint8_t *payload)
- {
- switch(payload[0])
- {
- case 0x87: // EMM-Unique
- {
- if(!memcmp(&payload[3], &decrypt->cam->ua[4], 4)
- && (payload[39] == 0x3d || payload[39] == 0x3b || payload[39] == 0x3a))
- {
- return 1; // true
- }
- break;
- }
- case 0x86: // EMM-Group
- case 0x88: // EMM-Group
- case 0x89: // EMM-Group
- {
- if(payload[3] == decrypt->cam->ua[4])
- return 1; // true
- break;
- }
- // case 0x89: // EMM-Shared
- default:
- break;
- }
- return 0; // false
- }
- uint8_t irdeto_emm_check(struct decrypt_s *decrypt, uint8_t *payload)
- {
- uint8_t len = payload[3] & 0x07; // 0
- int base = payload[3] >> 3; // 1C (28)
- if(base < 0x10)
- { // provider
- return (len <= 3 &&
- base == decrypt->prov_id[4] &&
- (!len || !memcmp(&payload[4],
- &decrypt->prov_id[5],
- len)) );
- }
- else
- { // card
- return (len <= 3 &&
- base == decrypt->cam->ua[4] &&
- (!len || !memcmp(&payload[4],
- &decrypt->cam->ua[5],
- len)) );
- }
- return 0;
- }
- uint8_t conax_emm_check(struct decrypt_s *decrypt, uint8_t *payload)
- {
- int ok = 0;
- ok = (!memcmp(&payload[6],&decrypt->prov_id[4],4));
- if (ok) { // provider, shared
- logwrite(G_LOG_INFO,
- "[Stream:%s] CONAX EMM: SHARED IS MINE. %02X%02X%02X%02X\n", decrypt->stream->name,
- payload[6],
- payload[7],
- payload[8],
- payload[9]);
- return 1;
- }else{ // unique, card
- if (!memcmp(&payload[6],&decrypt->cam->ua[4],4)) {
- logwrite(G_LOG_INFO,
- "[Stream:%s] CONAX EMM: UNIQUE IS MINE. %02X%02X%02X%02X\n", decrypt->stream->name,
- payload[6],
- payload[7],
- payload[8],
- payload[9]);
- return 1;
- }
- } // there are not global at conax? (no info found)
- return 0; // false
- }
- uint8_t cryptoworks_emm_check(struct decrypt_s *decrypt, uint8_t *payload)
- {
- switch(payload[0])
- {
- case 0x82: // CRYPTOWORKS EMM: UNIQUE
- {
- if(payload[3]==0xA9 && payload[4]==0xFF && payload[13]==0x80 && payload[14]==0x05) { // EMM is OK
- if (!memcmp(&payload[5],&decrypt->cam->ua[3],5)){
- logwrite(G_LOG_DEBUG,"CRYPTOWORKS EMM: UNIQUE MINE");
- return 1;
- }
- }
- break;
- }
- case 0x84: // CRYPTOWORKS EMM: SHARED
- {
- if(payload[3]==0xA9 && payload[4]==0xFF && payload[12]==0x80 && payload[13]==0x04) {
- if (!memcmp(&payload[5],&decrypt->cam->ua[3],4)){
- logwrite(G_LOG_DEBUG,"[Stream:%s] CRYPTOWORKS EMM: SHARED IS MINE. %02X%02X%02X%02X%02X", decrypt->stream->name,
- payload[5],
- payload[6],
- payload[7],
- payload[8],
- payload[9]);
- return 1;
- }
- }
- break;
- }
- case 0x86: // CRYPTOWORKS EMM: GLOBAL
- if(payload[3]==0xA9 && payload[4]==0xFF && payload[5]==0x83 && payload[6]==0x01 && payload[8]==0x85) {
- logwrite(G_LOG_DEBUG,"[Stream:%s] CRYPTOWORKS EMM: GLOBAL 0x86 v 0x85", decrypt->stream->name);
- return 1;
- }
- if(payload[3]==0xA9 && payload[4]==0xFF && payload[5]==0x83 && payload[6]==0x01 && payload[8]==0x84) {
- logwrite(G_LOG_DEBUG,"[Stream:%s] CRYPTOWORKS EMM: GLOBAL 0x86 v 0x84 not sent. not known.", decrypt->stream->name);
- return 0;
- }
- case 0x88:
- case 0x89:
- {
- if(payload[3]==0xA9 && payload[4]==0xFF && payload[8]==0x83 && payload[9]==0x01) {
- logwrite(G_LOG_DEBUG,"[Stream:%s] CRYPTOWORKS EMM: GLOBAL 0x%02X", decrypt->stream->name, payload[0]);
- return 1;
- }
- break;
- }
- case 0x8F:
- {
- logwrite(G_LOG_DEBUG,"[Stream:%s] CRYPTOWORKS EMM: GLOBAL 0x8F via camd3 %02X. Should it TODO?!", decrypt->stream->name, payload[0]);
- break;
- }
- default:
- logwrite(G_LOG_DEBUG,"[Stream:%s] CRYPTOWORKS EMM: UNKNOWN %02X", decrypt->stream->name, payload[0]);
- break;
- }
- return 0; // false
- }
- uint8_t videoguard_emm_check(struct decrypt_s *decrypt, uint8_t *payload) {
- unsigned char emm_type = (payload[3] & 0xC0) >> 6;
- switch(emm_type) {
- case 0: // global
- return 1; // true
- case 1: // unique
- case 2: // shared
- {
- unsigned char serial_count = ((payload[3] >> 4) & 3) + 1;
- unsigned char serial_len = (payload[3] & 0x80) ? 3 : 4;
- if(payload[0] == 0) return 1; // true
- int i;
- for(i = 0; i < serial_count; i++) {
- if(!memcmp(&payload[i * 4 + 4], &decrypt->cam->ua[4], serial_len)) {
- return 1; // true
- }
- }
- break;
- }
- default:
- break;
- }
- return 0; // false
- }
- uint8_t nagra_emm_check(struct decrypt_s *decrypt, uint8_t *payload) {
- switch(payload[0]) {
- case 0x83: {
- if(payload[7] == 0x10) { // shared
- return ( (payload[5] == decrypt->cam->ua[4])
- && (payload[4] == decrypt->cam->ua[5])
- && (payload[3] == decrypt->cam->ua[6])
- );
- }
- else { // unique
- return ( (payload[5] == decrypt->cam->ua[4])
- && (payload[4] == decrypt->cam->ua[5])
- && (payload[3] == decrypt->cam->ua[6])
- && (payload[6] == decrypt->cam->ua[7])
- );
- }
- break;
- }
- case 0x82: // global
- default:
- return 1; // true
- }
- return 0; // false
- }
- void emm_callback(void *arg, cam_packet_t *packet, uint8_t *result)
- {
- struct decrypt_s *decrypt = (struct decrypt_s *)arg;
- if(result != NULL)
- decrypt->stream->mon_err_code |= MERR_DECRYPT_EMM;
- }
- uint8_t isNull(uint8_t *data, size_t len) {
- while(len-- > 0) if(data[len]) return 0; // false
- return 1; // true
- }
- // from sasc :)
- static void SortNanos(unsigned char *dest, const unsigned char *src, int len)
- {
- int w=0, c=-1;
- while(1) {
- int n=0x100;
- for(int j=0; j<len;) {
- int l=src[j+1]+2;
- if(src[j]==c) {
- if(w+l>len) {
- printf("sortnanos: sanity check failed. Exceeding memory area. Probably corrupted nanos!");
- memset(dest,0,len); // zero out everything
- return;
- }
- memcpy(&dest[w],&src[j],l);
- w+=l;
- }
- else if(src[j]>c && src[j]<n)
- n=src[j];
- j+=l;
- }
- if(n==0x100) break;
- c=n;
- }
- }
- void processEMM(struct decrypt_s *decrypt, uint8_t *payload)
- {
- if(payload[0] < 0x82 || payload[0] > 0x8F) return;
- if(!payload || !decrypt->cam->loginOk || !decrypt->prov_id)
- return;
- uint8_t caid8 = decrypt->cam->caId >> 8;
- switch(caid8)
- {
- case 0x05: // Viaccess
- if(!viaccess_emm_check(decrypt, payload))
- return;
- if(isNull(&payload[3], 16)) return;
- break;
- case 0x4A: // DRE
- if(!dre_emm_check(decrypt, payload))
- return;
- break;
- case 0x06: // Irdeto
- if(!irdeto_emm_check(decrypt, payload))
- return;
- break;
- case 0x0B: // Conax
- if(!conax_emm_check(decrypt, payload))
- return;
- break;
- case 0x0D: // CryptoWorks
- if(!cryptoworks_emm_check(decrypt, payload))
- return;
- break;
- case 0x09: // VideoGuard
- if(!videoguard_emm_check(decrypt, payload))
- return;
- break;
- case 0x18: // nagra
- if(!nagra_emm_check(decrypt, payload))
- return;
- break;
- default: // not handled CAS
- /* It's spammy on streams where are more providers and more CAS used */
- // printf("[Stream:%s] unknown CAS in %s: %02X\n",
- // decrypt->stream->name, __func__, t->caid >> 8);
- return;
- break;
- }
- uint16_t emm_len = SCT_LEN(payload);
- if (emm_len>CWS_NETMSGSIZE-7){
- return; //Seems to be broken EMM.
- }
- uint8_t buffer[CWS_NETMSGSIZE];
- if(caid8 == 0x05) {
- switch(payload[0]) {
- case 0x8C:
- case 0x8D: {
- // EMM-GH
- if (decrypt->viaccess.sharedEmm && !memcmp(decrypt->viaccess.sharedEmm, payload, emm_len)){
- //new packet is equal to previous
- return;
- }
- if(payload[0] != decrypt->viaccess.sharedToggle) {
- if(decrypt->viaccess.sharedEmm) free(decrypt->viaccess.sharedEmm);
- decrypt->viaccess.sharedLen = emm_len;
- decrypt->viaccess.sharedEmm = (uint8_t *)malloc(emm_len);
- memcpy(decrypt->viaccess.sharedEmm, payload, emm_len);
- decrypt->viaccess.sharedToggle = payload[0];
- }
- return;
- }
- case 0x8E: {
- // EMM-S
- if(!decrypt->viaccess.sharedEmm) break;
- uint8_t tmp[CWS_NETMSGSIZE];
- int len = emm_len - 7; // emm header size
- if((payload[6] & 0x02) == 0x00) {
- uint8_t addrlen = len - 8;
- len = 0;
- tmp[len++] = 0x9E; // adf
- tmp[len++] = addrlen;
- memcpy(&tmp[len], &payload[7], addrlen); // &payload[7] - viaccess payload
- len += addrlen;
- tmp[len++] = 0xF0;
- tmp[len++] = 0x08;
- memcpy(&tmp[len], &payload[7+addrlen], 8);
- len += 8;
- }
- else {
- memcpy(tmp, &payload[7], len);
- }
- int len_s = 3; // shared emm header size
- int l = decrypt->viaccess.sharedLen - len_s;
- memcpy(&tmp[len], &decrypt->viaccess.sharedEmm[len_s], l);
- len += l;
- memcpy(buffer, payload, 7);
- SortNanos(&buffer[7], tmp, len);
- buffer[2] = len + 4;
- emm_len = SCT_LEN(buffer);
- payload = buffer;
- break;
- }
- }
- }
- if (decrypt->cam->log_emm){
- monitor_send_msg(decrypt->stream->config->monitor,
- "[CAM: %d] Add EMM from stream \"%s\", type:%02X, length: %d(0x%02X)"
- ,decrypt->cam->id,decrypt->stream->name,payload[0],emm_len,emm_len
- );
- }
- cam_packet_t packet;
- packet.type = PACKET_EMM;
- memcpy(packet.data, payload, emm_len);
- packet.len = emm_len;
- packet.prg_id = 0;
- packet.response_time = 0;
- packet.callback = emm_callback;
- packet.callback_arg = decrypt;
- cam_add_packet(decrypt->cam, &packet);
- }
- void _processEMM_callback(void *arg, mpeg2_psi_t *psi) {
- processEMM((struct decrypt_s *)arg, psi->payload);
- }
- void getEcmPid(struct decrypt_s *decrypt, uint8_t *payload, uint16_t pid)
- {
- if(!payload || !decrypt->cam->loginOk)
- return;
- struct pid_s *pids = decrypt->stream->pids;
- struct ca_s *t = (struct ca_s *)pids[pid].data;
- int i;
- switch(t->caid >> 8)
- {
- case 0x05: // Viaccess
- {
- if(decrypt->prov_id != NULL)
- {
- pids[pid].type = XECM;
- return;
- }
- payload += 4; // skip first bytes of ecm
- if(payload[0] == 0xD2) payload += (payload[1] + 2); // skip tps
- for(i = 0; i < decrypt->cam->num_of_provs; i++)
- {
- if(decrypt->cam->provs_ident[i][2] == (payload[4] & 0xF0) &&
- decrypt->cam->provs_ident[i][1] == payload[3] &&
- decrypt->cam->provs_ident[i][0] == payload[2])
- {
- pids[pid].type = MYECM;
- decrypt->prov_id = decrypt->cam->provs_id[i];
- decrypt->prov_ident = decrypt->cam->provs_ident[i];
- return;
- }
- }
- break;
- }
- case 0x4A: // DRE
- if(t->caid == decrypt->cam->caId)
- {
- pids[pid].type = MYECM;
- decrypt->prov_id = decrypt->cam->provs_id[0];
- decrypt->prov_ident = decrypt->cam->provs_ident[0];
- return;
- }
- break;
- case 0x06: // Irdeto
- if(t->caid == decrypt->cam->caId)
- {
- pids[pid].type = MYECM;
- decrypt->prov_id = decrypt->cam->provs_id[0];
- decrypt->prov_ident = decrypt->cam->provs_ident[0];
- return;
- }
- break;
- case 0x0B: // Conax
- if(t->caid == decrypt->cam->caId)
- {
- pids[pid].type = MYECM;
- decrypt->prov_id = decrypt->cam->provs_id[0];
- decrypt->prov_ident = decrypt->cam->provs_ident[0];
- return;
- }
- break;
- case 0x0D: // CryptoWorks
- if(t->caid == decrypt->cam->caId)
- {
- logwrite(G_LOG_DEBUG,"[Stream:%s] CryptoWorks was chosen\n", decrypt->stream->name);
- pids[pid].type = MYECM;
- decrypt->prov_id = decrypt->cam->provs_id[0];
- decrypt->prov_ident = decrypt->cam->provs_ident[0];
- return;
- }
- break;
- case 0x09: // VideoGuard
- if(t->caid == decrypt->cam->caId)
- {
- pids[pid].type = MYECM;
- decrypt->prov_id = decrypt->cam->provs_id[0];
- decrypt->prov_ident = decrypt->cam->provs_ident[0];
- return;
- }
- break;
- case 0x18: // nagra
- if(t->caid == decrypt->cam->caId)
- {
- pids[pid].type = MYECM;
- decrypt->prov_id = decrypt->cam->provs_id[0];
- decrypt->prov_ident = decrypt->cam->provs_ident[0];
- return;
- }
- default:
- /* It's spammy on streams where are more providers and more CAS used */
- // printf("[Stream:%s] unknown CAS in %s: %02X\n",
- // decrypt->stream->name, __func__, t->caid >> 8);
- break;
- }
- }
- void ecm_callback(void *arg, cam_packet_t *packet, uint8_t *keys)
- {
- struct decrypt_s *decrypt = (struct decrypt_s *)arg;
- if ( (decrypt->cam->log_ecm_mintime > 0 && packet->response_time <= (uint16_t)decrypt->cam->log_ecm_mintime)
- || (decrypt->cam->log_ecm_maxtime > 0 && packet->response_time >= (uint16_t)decrypt->cam->log_ecm_maxtime)) {
- monitor_send_msg(decrypt->stream->config->monitor,
- "[Stream:%s] ecm response time: %dms", decrypt->stream->name,
- packet->response_time);
- }
- if(keys != NULL)
- {
- struct timeval nowTime;
- uint32_t lastCWTimeDiff ;
- gettimeofday(&nowTime, NULL);
- if (decrypt->lastCWTime.tv_usec>0){
- lastCWTimeDiff = ((nowTime.tv_sec - decrypt->lastCWTime.tv_sec) * 1000) +
- ((nowTime.tv_usec - decrypt->lastCWTime.tv_usec) / 1000);
- if ( !memcmp(&decrypt->lastCW[0],&keys[0],8)
- || !memcmp(&decrypt->lastCW[8],&keys[8],8)
- //One of the keys is equal to previous - seems good CW
- ){
- } else {
- monitor_send_msg(decrypt->stream->config->monitor
- , "[Stream:%s] WARNING: different CW,"
- " PREV: %02X%02X%02X%02X%02X%02X%02X%02X:%02X%02X%02X%02X%02X%02X%02X%02X"
- " NOW: %02X%02X%02X%02X%02X%02X%02X%02X:%02X%02X%02X%02X%02X%02X%02X%02X (%dms)"
- , decrypt->stream->name,
- decrypt->lastCW[0],decrypt->lastCW[1],decrypt->lastCW[2],decrypt->lastCW[3],
- decrypt->lastCW[4],decrypt->lastCW[5],decrypt->lastCW[6],decrypt->lastCW[7],
- decrypt->lastCW[8],decrypt->lastCW[9],decrypt->lastCW[10],decrypt->lastCW[11],
- decrypt->lastCW[12],decrypt->lastCW[13],decrypt->lastCW[14],decrypt->lastCW[15],
- keys[0],keys[1],keys[2],keys[3], keys[4],keys[5],keys[6],keys[7],
- keys[8],keys[9],keys[10],keys[11], keys[12],keys[13],keys[14],keys[15],
- lastCWTimeDiff
- );
- }
- }
- memcpy(decrypt->lastCW,keys,16);
- gettimeofday(&decrypt->lastCWTime, NULL);
- decrypt->lastParity = packet->data[0];
- if(decrypt->ecm_number == 0xFF
- && (decrypt->cam->caId >> 8) == 0x06) { // irdeto
- decrypt->ecm_number = packet->data[4];
- }
- memcpy(decrypt->ckeys, keys, 16);
- }
- else
- decrypt->stream->mon_err_code |= MERR_DECRYPT_ECM;
- }
- void processECM(struct decrypt_s *decrypt, uint8_t *payload)
- {
- if(!payload || payload[0] == decrypt->lastParity)
- return; // keys not change
- decrypt->lastParity = payload[0];
- cam_packet_t packet;
- packet.type = PACKET_ECM;
- packet.prg_id = decrypt->prg_id;
- packet.response_time = 0;
- packet.callback = ecm_callback;
- packet.callback_arg = decrypt;
- switch(payload[0])
- {
- case 0x80: // ecm odd
- case 0x81: // ecm even
- {
- packet.len = SCT_LEN(payload);
- memcpy(packet.data, payload, packet.len);
- cam_add_packet(decrypt->cam, &packet);
- break;
- }
- // case MSG_KEEPALIVE:
- default:
- break;
- }
- }
- void _processECM_callback(void *arg, mpeg2_psi_t *psi) {
- struct decrypt_s *decrypt = (struct decrypt_s *)arg;
- int caid8 = decrypt->cam->caId & 0xFF00;
- if(caid8 == 0x0600) {
- if(decrypt->stream->ecm_group > 0) {
- if(decrypt->stream->ecm_group != psi->payload[7]) return;
- }
- else {
- if(decrypt->ecm_number == 0xFF) {
- decrypt->lastParity = 0;
- }
- else {
- if(decrypt->ecm_number != psi->payload[4]) return;
- }
- }
- }
- processECM(decrypt, psi->payload);
- }
- uint8_t *get_payload(uint8_t *ts)
- {
- uint8_t afield = 0;
- switch(ts[3] & 0x30)
- {
- case 0x30: // ts[4] - adaptation length; 1 - length of ts[4]
- afield = ts[4] + 1;
- break;
- case 0x10: // no adaptation field
- break;
- case 0x20: // adaptation field, no payload
- default: // no payload
- return NULL;
- }
- uint8_t pusi = (ts[1] & 0x40)?(ts[4 + afield] + 1):0;
- uint8_t i_hdr = 4 + pusi + afield;
- return &ts[i_hdr];
- }
- void parse_tspacket(struct decrypt_s *decrypt, void *data, int len)
- {
- if(!decrypt->cam->loginOk)
- return;
- uint8_t *ts = (uint8_t *)data;
- struct pid_s *pids = decrypt->stream->pids;
- uint16_t pid = ((ts[1] & 0x1F) << 8) | ts[2];
- switch(pids[pid].type)
- {
- case PAT:
- case CAT:
- case PMT:
- case NIT:
- case XEMM:
- case XECM:
- return;
- case EMM:
- {
- if(decrypt->cam->disable_emm > 0) {
- pids[pid].type = XEMM;
- return;
- }
- getEmmPid(decrypt, get_payload(ts), pid);
- if(pids[pid].type == MYEMM) {
- monitor_send_msg(decrypt->stream->config->monitor
- , "[Stream:%s] Select EMM: pid=%d"
- , decrypt->stream->name, pid);
- }
- return;
- }
- case MYEMM:
- {
- mpegts_mux_psi(&decrypt->psi_emm, ts, _processEMM_callback, decrypt);
- return;
- }
- case ECM:
- {
- getEcmPid(decrypt, get_payload(ts), pid);
- if(pids[pid].type == MYECM) {
- monitor_send_msg(decrypt->stream->config->monitor
- , "[Stream:%s] Select ECM: pid=%d"
- , decrypt->stream->name, pid);
- }
- return;
- }
- case MYECM:
- {
- mpegts_mux_psi(&decrypt->psi_ecm, ts, _processECM_callback, decrypt);
- return;
- }
- default:
- break;
- }
- }
- int decrypt_init(struct decrypt_s *decrypt)
- {
- decrypt->keys = get_key_struct();
- memset(decrypt->lastCW,0,sizeof(decrypt->lastCW));
- switch(decrypt->type)
- {
- case DECRYPT_BISS:
- {
- if(decrypt->ckeys[3] == 0x00) {
- decrypt->ckeys[3] = (decrypt->ckeys[0]
- + decrypt->ckeys[1]
- + decrypt->ckeys[2]) & 0xFF;
- }
- if(decrypt->ckeys[7] == 0x00) {
- decrypt->ckeys[7] = (decrypt->ckeys[4]
- + decrypt->ckeys[5]
- + decrypt->ckeys[6]) & 0xFF;
- }
- #ifdef DEBUG
- printf("Set BISS key: %02X%02X%02X%02X%02X%02X%02X%02X\n",
- decrypt->ckeys[0], decrypt->ckeys[1],
- decrypt->ckeys[2], decrypt->ckeys[3],
- decrypt->ckeys[4], decrypt->ckeys[5],
- decrypt->ckeys[6], decrypt->ckeys[7]);
- #endif
- set_control_words(decrypt->keys, decrypt->ckeys, decrypt->ckeys);
- break;
- }
- case DECRYPT_NEWCAMD:
- {
- // bug#66
- // while(decrypt->cam->loginOk <= 0)
- // sleep(1);
- switch(decrypt->cam->caId >> 8) {
- case 0x06: { // irdeto
- decrypt->ecm_number = 0xFF;
- break;
- }
- default:
- break;
- }
- memset(decrypt->ckeys, 0, sizeof(decrypt->ckeys));
- break;
- }
- default:
- return 0;
- }
- return 1; // true
- }