Project

General

Profile

Feature #159 » tvheadend-irdeto-emm.patch

irdeto emm handling - Lars Op den Kamp -, 2010-03-20 12:39

View differences:

tvheadend.odk/src/cwc.c 2010-03-20 12:39:09.980444449 +0100
49 49
#define CWS_NETMSGSIZE 256
50 50
#define CWS_FIRSTCMDNO 0xe0
51 51

  
52
/**
53
 * cards for which emm updates are handled
54
 */
55
typedef enum {
56
  CARD_IRDETO,
57
  CARD_CONAX,
58
  CARD_UNKNOWN
59
} card_type_t;
60

  
52 61
typedef enum {
53 62
  MSG_CLIENT_2_SERVER_LOGIN = CWS_FIRSTCMDNO,
54 63
  MSG_CLIENT_2_SERVER_LOGIN_ACK,
......
195 204
  /* Emm forwarding */
196 205
  int cwc_forward_emm;
197 206

  
207
  /* Card type */
208
  card_type_t cwc_card_type;
209
  
198 210
  /* From configuration */
199 211

  
200 212
  uint8_t cwc_confedkey[14];
......
221 233

  
222 234
static void cwc_transport_destroy(th_descrambler_t *td);
223 235
extern char *cwc_krypt(const char *key, const char *salt);
224

  
236
static void cwc_detect_card_type(cwc_t *cwc);
237
void cwc_emm_conax(cwc_t *cwc, uint8_t *data, int len);
238
void cwc_emm_irdeto(cwc_t *cwc, uint8_t *data, int len);
225 239

  
226 240
/**
227 241
 *
......
516 530
	 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],
517 531
	 nprov);
518 532

  
533
  cwc_detect_card_type(cwc);
534

  
519 535
  msg  += 15;
520 536
  plen -= 12;
521 537

  
......
557 573
    if (!emm_allowed)
558 574
      tvhlog(LOG_INFO, "cwc", "%s: Will not forward EMMs (not allowed by server)",
559 575
	     cwc->cwc_hostname);
560
    else if ((cwc->cwc_caid>>8) != 0x0b)
561
      tvhlog(LOG_INFO, "cwc", "%s: Will not forward EMMs (unsupported ca system)",
562
	     cwc->cwc_hostname);
563
    else {
576
    else if (cwc->cwc_card_type != CARD_UNKNOWN) {
564 577
      tvhlog(LOG_INFO, "cwc", "%s: Will forward EMMs",
565 578
	     cwc->cwc_hostname);
566 579
      cwc->cwc_forward_emm = 1;
567
    }
580
    } else
581
      tvhlog(LOG_INFO, "cwc", "%s: Will not forward EMMs (unsupported ca system)",
582
         cwc->cwc_hostname);
568 583
  }
569 584

  
570 585
  return 0;
571 586
}
572 587

  
588
/**
589
 * Detects the cam card type
590
 * If you want to add another card, have a look at
591
 * http://www.dvbservices.com/identifiers/ca_system_id?page=3
592
 * 
593
 * based on the equivalent in sasc-ng
594
 */
595
static void
596
cwc_detect_card_type(cwc_t *cwc)
597
{
598
  uint8_t c_sys = cwc->cwc_caid >> 8;
599
		
600
  switch (c_sys)
601
  {
602
    case 0x17:
603
    case 0x06: 
604
      cwc->cwc_card_type = CARD_IRDETO;
605
        tvhlog(LOG_INFO, "cwc", "%s: irdeto card",
606
          cwc->cwc_hostname);
607
        break;
608
    case 0x0b:
609
      cwc->cwc_card_type = CARD_CONAX;
610
      tvhlog(LOG_INFO, "cwc", "%s: conax card",
611
        cwc->cwc_hostname);
612
      break;
613
    default:
614
      cwc->cwc_card_type = CARD_UNKNOWN;
615
      tvhlog(LOG_INFO, "cwc", "%s: unknown card",
616
        cwc->cwc_hostname);
617
  }
618
}
573 619

  
574 620
/**
575 621
 * Login command
......
1037 1083
  lock_assert(&global_lock);
1038 1084

  
1039 1085
  TAILQ_FOREACH(cwc, &cwcs, cwc_link)
1040
    if(cwc->cwc_forward_emm && cwc->cwc_writer_running &&
1041
       data[0] == 0x82 /* Conax */ ) {
1042
      int i;
1043
      for (i=0; i < cwc->cwc_num_providers; i++)
1044
	if (memcmp(&data[3], &cwc->cwc_providers[i].sa[1], 7) == 0) {
1045
	  cwc_send_msg(cwc, data, len, 0, 1);
1046
	  break;
1047
	}
1086
    if(cwc->cwc_forward_emm && cwc->cwc_writer_running)
1087
    {
1088
      switch (cwc->cwc_card_type)
1089
      {
1090
        case CARD_CONAX:
1091
          cwc_emm_conax(cwc, data, len);
1092
          break;
1093
        case CARD_IRDETO:
1094
          cwc_emm_irdeto(cwc, data, len);
1095
          break;
1096
        case CARD_UNKNOWN:
1097
          break;
1098
      }
1099
    }
1100
}
1101

  
1102

  
1103
/**
1104
 * conax emm handler
1105
 */
1106
void
1107
cwc_emm_conax(cwc_t *cwc, uint8_t *data, int len)
1108
{
1109
  if (data[0] == 0x82)
1110
  {
1111
    int i;
1112
    for (i=0; i < cwc->cwc_num_providers; i++)
1113
    {
1114
      if (memcmp(&data[3], &cwc->cwc_providers[i].sa[1], 7) == 0)
1115
      {
1116
        cwc_send_msg(cwc, data, len, 0, 1);
1117
        break;
1118
      }
1119
    }
1120
  }
1121
}
1122

  
1123

  
1124
/**
1125
 * irdeto emm handler
1126
 * inspired by opensasc-ng, https://opensvn.csie.org/traccgi/opensascng/
1127
 */
1128
void
1129
cwc_emm_irdeto(cwc_t *cwc, uint8_t *data, int len)
1130
{
1131
  int emm_mode = data[3] >> 3;
1132
  int emm_len = data[3] & 0x07;
1133
  int match = 0;
1134
  
1135
  if (emm_mode & 0x10)
1136
  {
1137
    // try to match card
1138
    match = (emm_mode == cwc->cwc_ua[4] && 
1139
      (!emm_len || // zero length
1140
      !memcmp(&data[4], &cwc->cwc_ua[5], emm_len))); // exact match
1141
  }
1142
  else
1143
  {
1144
    // try to match provider
1145
    int i;
1146
    for(i=0; i < cwc->cwc_num_providers; i++)
1147
    {
1148
    	match = (emm_mode == cwc->cwc_providers[i].sa[4] && 
1149
          (!emm_len || // zero length
1150
          !memcmp(&data[4], &cwc->cwc_providers[i].sa[5], emm_len))); // exact match
1151
    	
1152
    	if (match) break;
1048 1153
    }
1154
  }
1155
  
1156
  if (match)
1157
	cwc_send_msg(cwc, data, len, 0, 1);
1049 1158
}
1050 1159

  
1051 1160

  
(2-2/3)