Browse Source

Split cs378x protocol from generic camd code.

Georgi Chorbadzhiyski 12 years ago
parent
commit
d8bad87e7d
7 changed files with 238 additions and 174 deletions
  1. 1
    1
      Makefile
  2. 0
    1
      TODO
  3. 186
    0
      camd-cs378x.c
  4. 26
    166
      camd.c
  5. 4
    0
      camd.h
  6. 19
    6
      data.h
  7. 2
    0
      tsdecrypt.c

+ 1
- 1
Makefile View File

@@ -30,7 +30,7 @@ FUNCS_LIB = $(FUNCS_DIR)/libfuncs.a
30 30
 TS_DIR = libtsfuncs
31 31
 TS_LIB = $(TS_DIR)/libtsfuncs.a
32 32
 
33
-tsdecrypt_SRC  = data.c udp.c util.c camd.c process.c tables.c notify.c tsdecrypt.c
33
+tsdecrypt_SRC  = data.c udp.c util.c camd.c camd-cs378x.c process.c tables.c notify.c tsdecrypt.c
34 34
 tsdecrypt_LIBS = -lcrypto -ldvbcsa -lpthread
35 35
 tsdecrypt_OBJS = $(FUNCS_LIB) $(TS_LIB) $(tsdecrypt_SRC:.c=.o)
36 36
 

+ 0
- 1
TODO View File

@@ -1 +0,0 @@
1
-- Make camd comm code modular in order to add more protocols.

+ 186
- 0
camd-cs378x.c View File

@@ -0,0 +1,186 @@
1
+/*
2
+ * cs378x protocol
3
+ * Copyright (C) 2011 Unix Solutions Ltd.
4
+ *
5
+ * This program is free software; you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License version 2
7
+ * as published by the Free Software Foundation.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
+ * GNU General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
17
+ */
18
+#include <stdlib.h>
19
+#include <unistd.h>
20
+#include <string.h>
21
+
22
+#include <openssl/aes.h>
23
+#include <openssl/md5.h>
24
+
25
+#include "libfuncs/libfuncs.h"
26
+
27
+#include "data.h"
28
+#include "util.h"
29
+#include "camd.h"
30
+
31
+static int cs378x_connect(struct camd35 *c) {
32
+	if (c->server_fd < 0)
33
+		c->server_fd = camd_tcp_connect(c->server_addr, c->server_port);
34
+	return c->server_fd;
35
+}
36
+
37
+static void cs378x_disconnect(struct camd35 *c) {
38
+	shutdown_fd(&c->server_fd);
39
+}
40
+
41
+static int cs378x_reconnect(struct camd35 *c) {
42
+	cs378x_disconnect(c);
43
+	return cs378x_connect(c);
44
+}
45
+
46
+static int cs378x_recv(struct camd35 *c, uint8_t *data, int *data_len) {
47
+	int i;
48
+
49
+	// Read AUTH token
50
+	ssize_t r = fdread(c->server_fd, (char *)data, 4);
51
+	if (r < 4)
52
+		return -1;
53
+	uint32_t auth_token = (((data[0] << 24) | (data[1] << 16) | (data[2]<<8) | data[3]) & 0xffffffffL);
54
+	if (auth_token != c->auth_token)
55
+		ts_LOGf("WARN: recv auth 0x%08x != camd35_auth 0x%08x\n", auth_token, c->auth_token);
56
+
57
+	*data_len = 256;
58
+	for (i = 0; i < *data_len; i += 16) { // Read and decrypt payload
59
+		fdread(c->server_fd, (char *)data + i, 16);
60
+		AES_decrypt(data + i, data + i, &c->aes_decrypt_key);
61
+		if (i == 0)
62
+			*data_len = boundary(4, data[1] + 20); // Initialize real data length
63
+	}
64
+	return *data_len;
65
+}
66
+
67
+static int cs378x_send_buf(struct camd35 *c, int data_len) {
68
+	int i;
69
+	unsigned char dump[16];
70
+
71
+	cs378x_connect(c);
72
+
73
+	// Prepare auth token (only once)
74
+	if (!c->auth_token) {
75
+		c->auth_token = crc32(0L, MD5((unsigned char *)c->user, strlen(c->user), dump), 16);
76
+
77
+		MD5((unsigned char *)c->pass, strlen(c->pass), dump);
78
+
79
+		AES_set_encrypt_key(dump, 128, &c->aes_encrypt_key);
80
+		AES_set_decrypt_key(dump, 128, &c->aes_decrypt_key);
81
+	}
82
+
83
+	uint8_t *bdata = c->buf + 4; // Leave space for auth token
84
+	memmove(bdata, c->buf, data_len); // Move data
85
+	init_4b(c->auth_token, c->buf); // Put authentication token
86
+
87
+	for (i = 0; i < data_len; i += 16) // Encrypt payload
88
+		AES_encrypt(bdata + i, bdata + i, &c->aes_encrypt_key);
89
+
90
+	return fdwrite(c->server_fd, (char *)c->buf, data_len + 4);
91
+}
92
+
93
+static void cs378x_buf_init(struct camd35 *c, uint8_t *data, int data_len) {
94
+	memset(c->buf, 0, CAMD35_HDR_LEN); // Reset header
95
+	memset(c->buf + CAMD35_HDR_LEN, 0xff, CAMD35_BUF_LEN - CAMD35_HDR_LEN); // Reset data
96
+	c->buf[1] = data_len; // Data length
97
+	init_4b(crc32(0L, data, data_len), c->buf + 4); // Data CRC is at buf[4]
98
+	memcpy(c->buf + CAMD35_HDR_LEN, data, data_len); // Copy data to buf
99
+}
100
+
101
+static int cs378x_do_ecm(struct camd35 *c, uint16_t ca_id, uint16_t service_id, uint16_t idx, uint8_t *data, uint8_t data_len) {
102
+	uint32_t provider_id = 0;
103
+	int to_send = boundary(4, CAMD35_HDR_LEN + data_len);
104
+
105
+	cs378x_buf_init(c, data, (int)data_len);
106
+
107
+	c->buf[0] = 0x00; // CMD ECM request
108
+	init_2b(service_id , c->buf + 8);
109
+	init_2b(ca_id      , c->buf + 10);
110
+	init_4b(provider_id, c->buf + 12);
111
+	init_2b(idx        , c->buf + 16);
112
+	c->buf[18] = 0xff;
113
+	c->buf[19] = 0xff;
114
+
115
+	return cs378x_send_buf(c, to_send);
116
+}
117
+
118
+static int cs378x_do_emm(struct camd35 *c, uint16_t ca_id, uint8_t *data, uint8_t data_len) {
119
+	uint32_t prov_id = 0;
120
+	int to_send = boundary(4, CAMD35_HDR_LEN + data_len);
121
+
122
+	cs378x_buf_init(c, data, (int)data_len);
123
+
124
+	c->buf[0] = 0x06; // CMD incomming EMM
125
+	init_2b(ca_id  , c->buf + 10);
126
+	init_4b(prov_id, c->buf + 12);
127
+
128
+	return cs378x_send_buf(c, to_send);
129
+}
130
+
131
+static int cs378x_get_cw(struct camd35 *c, uint16_t *ca_id, uint16_t *idx, uint8_t *cw) {
132
+	uint8_t *data = c->buf;
133
+	int data_len = 0;
134
+	int ret = 0;
135
+
136
+READ:
137
+	ret = cs378x_recv(c, data, &data_len);
138
+	if (ret < 0) {
139
+		ts_LOGf("ERR | No code word has been received (ret = %d)\n", ret);
140
+		cs378x_reconnect(c);
141
+		return ret;
142
+	}
143
+
144
+	// EMM request, ignore it. Sometimes OSCAM sends two EMM requests after CW
145
+	if (data[0] == 0x05)
146
+		goto READ;
147
+
148
+	if (data[0] != 0x01) {
149
+		ts_LOGf("ERR | Unexpected server response on code word request (ret data[0] == 0x%02x /%s/)\n",
150
+			data[0],
151
+			data[0] == 0x08 ? "No card" :
152
+			data[0] == 0x44 ? "No code word found" : "Unknown err");
153
+		c->ecm_recv_errors++;
154
+		usleep(10000);
155
+		if (c->ecm_recv_errors >= ECM_RECV_ERRORS_LIMIT) {
156
+			c->key->is_valid_cw = 0;
157
+			memset(cw, 0, 16); // Invalid CW
158
+		}
159
+		return 0;
160
+	}
161
+
162
+	if (data_len < 48) {
163
+		ts_LOGf("ERR | Code word data_len (%d) mismatch != 48\n", data_len);
164
+		return 0;
165
+	}
166
+
167
+	if (data[1] < 0x10) {
168
+		ts_LOGf("ERR | Code word len (%d) mismatch != 16\n", data[1]);
169
+		return 0;
170
+	}
171
+
172
+	*ca_id = (data[10] << 8) | data[11];
173
+	*idx   = (data[16] << 8) | data[17];
174
+	memcpy(cw, data + 20, 16);
175
+
176
+	return ret;
177
+}
178
+
179
+void camd_proto_cs378x(struct camd_ops *ops) {
180
+	ops->connect	= cs378x_connect;
181
+	ops->disconnect	= cs378x_disconnect;
182
+	ops->reconnect	= cs378x_reconnect;
183
+	ops->do_emm		= cs378x_do_emm;
184
+	ops->do_ecm		= cs378x_do_ecm;
185
+	ops->get_cw		= cs378x_get_cw;
186
+}

+ 26
- 166
camd.c View File

@@ -24,20 +24,16 @@
24 24
 #include <netinet/tcp.h>
25 25
 #include <arpa/inet.h>
26 26
 
27
-#include <openssl/aes.h>
28
-#include <openssl/md5.h>
29
-
30 27
 #include <dvbcsa/dvbcsa.h>
31 28
 
32 29
 #include "libfuncs/libfuncs.h"
33
-#include "libtsfuncs/tsfuncs.h"
34 30
 
35 31
 #include "data.h"
36 32
 #include "util.h"
37 33
 #include "camd.h"
38 34
 #include "notify.h"
39 35
 
40
-static int connect_to(struct in_addr ip, int port) {
36
+int camd_tcp_connect(struct in_addr ip, int port) {
41 37
 	ts_LOGf("CAM | Connecting to server %s:%d\n", inet_ntoa(ip), port);
42 38
 
43 39
 	int fd = socket(PF_INET, SOCK_STREAM, 0);
@@ -64,112 +60,22 @@ static int connect_to(struct in_addr ip, int port) {
64 60
 	return fd;
65 61
 }
66 62
 
67
-static void camd35_init_auth(struct ts *ts) {
68
-	struct camd35 *c = &ts->camd35;
69
-	unsigned char dump[16];
70
-
71
-	if (c->auth_token)
72
-		return;
73
-
74
-	c->auth_token = crc32(0L, MD5((unsigned char *)c->user, strlen(c->user), dump), 16);
75
-
76
-	MD5((unsigned char *)c->pass, strlen(c->pass), dump);
77
-
78
-	AES_set_encrypt_key(dump, 128, &c->aes_encrypt_key);
79
-	AES_set_decrypt_key(dump, 128, &c->aes_decrypt_key);
80
-}
81
-
82
-static int camd35_connect(struct ts *ts) {
83
-	struct camd35 *c = &ts->camd35;
84
-	if (c->server_fd < 0)
85
-		c->server_fd = connect_to(c->server_addr, c->server_port);
86
-	return c->server_fd;
87
-}
88
-
89
-static void camd35_disconnect(struct ts *ts) {
90
-	struct camd35 *c = &ts->camd35;
91
-	shutdown_fd(&c->server_fd);
92
-}
93
-
94
-static int camd35_reconnect(struct ts *ts) {
95
-	camd35_disconnect(ts);
96
-	return camd35_connect(ts);
97
-}
98
-
99
-static int camd35_recv(struct camd35 *c, uint8_t *data, int *data_len) {
100
-	int i;
101
-
102
-	// Read AUTH token
103
-	ssize_t r = fdread(c->server_fd, (char *)data, 4);
104
-	if (r < 4)
105
-		return -1;
106
-	uint32_t auth_token = (((data[0] << 24) | (data[1] << 16) | (data[2]<<8) | data[3]) & 0xffffffffL);
107
-	if (auth_token != c->auth_token)
108
-		ts_LOGf("WARN: recv auth 0x%08x != camd35_auth 0x%08x\n", auth_token, c->auth_token);
109
-
110
-	*data_len = 256;
111
-	for (i = 0; i < *data_len; i += 16) { // Read and decrypt payload
112
-		fdread(c->server_fd, (char *)data + i, 16);
113
-		AES_decrypt(data + i, data + i, &c->aes_decrypt_key);
114
-		if (i == 0)
115
-			*data_len = boundary(4, data[1] + 20); // Initialize real data length
116
-	}
117
-	return *data_len;
118
-}
119
-
120 63
 static int camd35_recv_cw(struct ts *ts) {
121 64
 	struct camd35 *c = &ts->camd35;
122 65
 	struct timeval tv1, tv2, last_ts_keyset;
123 66
 	static uint8_t invalid_cw[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
124
-	uint8_t *data = c->buf;
125
-	int data_len = 0;
126
-	int ret = 0;
67
+	uint16_t ca_id = 0;
68
+	uint16_t idx = 0;
69
+	int ret;
127 70
 
128 71
 	gettimeofday(&tv1, NULL);
129
-READ:
130
-	ret = camd35_recv(c, data, &data_len);
131
-	if (ret < 0) {
132
-		ts_LOGf("ERR | No code word has been received (ret = %d)\n", ret);
133
-		camd35_reconnect(ts);
72
+	ret = c->ops.get_cw(c, &ca_id, &idx, c->key->cw);
73
+	if (ret <= 0)
134 74
 		return ret;
135
-	}
136
-
137
-	// EMM request, ignore it. Sometimes OSCAM sends two EMM requests after CW
138
-	if (data[0] == 0x05)
139
-		goto READ;
140
-
141
-	if (data[0] != 0x01) {
142
-		ts_LOGf("ERR | Unexpected server response on code word request (ret data[0] == 0x%02x /%s/)\n",
143
-			data[0],
144
-			data[0] == 0x08 ? "No card" :
145
-			data[0] == 0x44 ? "No code word found" : "Unknown err");
146
-		c->ecm_recv_errors++;
147
-		usleep(10000);
148
-		if (c->ecm_recv_errors >= ECM_RECV_ERRORS_LIMIT) {
149
-			c->key->is_valid_cw = 0;
150
-			memcpy(c->key->cw, invalid_cw, 16);
151
-		}
152
-		return 0;
153
-	}
154
-
155
-	if (data_len < 48) {
156
-		ts_LOGf("ERR | Code word data_len (%d) mismatch != 48\n", data_len);
157
-		return 0;
158
-	}
159
-
160
-	if (data[1] < 0x10) {
161
-		ts_LOGf("ERR | Code word len (%d) mismatch != 16\n", data[1]);
162
-		return 0;
163
-	}
164 75
 	gettimeofday(&tv2, NULL);
165 76
 
166
-	uint16_t ca_id = (data[10] << 8) | data[11];
167
-	uint16_t idx   = (data[16] << 8) | data[17];
168
-	uint8_t *cw = data + 20;
169
-	memcpy(c->key->cw, cw, 16);
170
-
171 77
 	char cw_dump[16 * 6];
172
-	ts_hex_dump_buf(cw_dump, 16 * 6, cw, 16, 0);
78
+	ts_hex_dump_buf(cw_dump, 16 * 6, c->key->cw, 16, 0);
173 79
 
174 80
 	int valid_cw = memcmp(c->key->cw, invalid_cw, 16) != 0;
175 81
 	if (!c->key->is_valid_cw && valid_cw) {
@@ -209,52 +115,13 @@ READ:
209 115
 
210 116
 #undef ERR
211 117
 
212
-
213
-static int camd35_send_buf(struct ts *ts, int data_len) {
214
-	struct camd35 *c = &ts->camd35;
215
-	int i;
216
-	uint8_t *bdata = c->buf + 4; // Leave space for auth token
217
-
218
-	camd35_connect(ts);
219
-	camd35_init_auth(ts);
220
-
221
-	memmove(bdata, c->buf, data_len); // Move data
222
-	init_4b(c->auth_token, c->buf); // Put authentication token
223
-
224
-	for (i = 0; i < data_len; i += 16) // Encrypt payload
225
-		AES_encrypt(bdata + i, bdata + i, &c->aes_encrypt_key);
226
-
227
-	return fdwrite(c->server_fd, (char *)c->buf, data_len + 4);
228
-}
229
-
230
-static void camd35_buf_init(struct camd35 *c, uint8_t *data, int data_len) {
231
-	memset(c->buf, 0, CAMD35_HDR_LEN); // Reset header
232
-	memset(c->buf + CAMD35_HDR_LEN, 0xff, CAMD35_BUF_LEN - CAMD35_HDR_LEN); // Reset data
233
-	c->buf[1] = data_len; // Data length
234
-	init_4b(crc32(0L, data, data_len), c->buf + 4); // Data CRC is at buf[4]
235
-	memcpy(c->buf + CAMD35_HDR_LEN, data, data_len); // Copy data to buf
236
-}
237
-
238 118
 static int camd35_send_ecm(struct ts *ts, uint16_t ca_id, uint16_t service_id, uint16_t idx, uint8_t *data, uint8_t data_len) {
239 119
 	struct camd35 *c = &ts->camd35;
240
-	uint32_t provider_id = 0;
241
-	int to_send = boundary(4, CAMD35_HDR_LEN + data_len);
242
-
243
-	camd35_buf_init(c, data, (int)data_len);
244
-
245
-	c->buf[0] = 0x00; // CMD ECM request
246
-	init_2b(service_id , c->buf + 8);
247
-	init_2b(ca_id      , c->buf + 10);
248
-	init_4b(provider_id, c->buf + 12);
249
-	init_2b(idx        , c->buf + 16);
250
-	c->buf[18] = 0xff;
251
-	c->buf[19] = 0xff;
252
-
253
-	int ret = camd35_send_buf(ts, to_send);
120
+	int ret = c->ops.do_ecm(c, ca_id, service_id, idx, data, data_len);
254 121
 	if (ret <= 0) {
255 122
 		ts_LOGf("ERR | Error sending ecm packet, reconnecting to camd.\n");
256 123
 		ts->is_cw_error = 1;
257
-		camd35_reconnect(ts);
124
+		c->ops.reconnect(c);
258 125
 		return ret;
259 126
 	}
260 127
 
@@ -275,21 +142,12 @@ static int camd35_send_ecm(struct ts *ts, uint16_t ca_id, uint16_t service_id, u
275 142
 
276 143
 static int camd35_send_emm(struct ts *ts, uint16_t ca_id, uint8_t *data, uint8_t data_len) {
277 144
 	struct camd35 *c = &ts->camd35;
278
-	uint32_t prov_id = 0;
279
-	int to_send = boundary(4, CAMD35_HDR_LEN + data_len);
280
-
281
-	camd35_buf_init(c, data, (int)data_len);
282
-
283
-	c->buf[0] = 0x06; // CMD incomming EMM
284
-	init_2b(ca_id  , c->buf + 10);
285
-	init_4b(prov_id, c->buf + 12);
286
-
287
-	int ret = camd35_send_buf(ts, to_send);
145
+	int ret = c->ops.do_emm(c, ca_id, data, data_len);
288 146
 	if (ret < 0) {
289 147
 		c->emm_recv_errors++;
290 148
 		if (c->emm_recv_errors >= EMM_RECV_ERRORS_LIMIT) {
291 149
 			ts_LOGf("ERR | Error sending emm packet, reconnecting to camd.\n");
292
-			camd35_reconnect(ts);
150
+			c->ops.reconnect(c);
293 151
 			c->emm_recv_errors = 0;
294 152
 		}
295 153
 	} else {
@@ -374,25 +232,27 @@ void camd_msg_process(struct ts *ts, struct camd_msg *msg) {
374 232
 }
375 233
 
376 234
 void camd_start(struct ts *ts) {
377
-	camd35_connect(ts);
235
+	struct camd35 *c = &ts->camd35;
236
+	c->ops.connect(c);
378 237
 	// The input is not file, process messages using async thread
379 238
 	if (!(ts->input.type == FILE_IO && ts->input.fd != 0)) {
380
-		ts->camd35.req_queue = queue_new();
381
-		ts->camd35.ecm_queue = queue_new();
382
-		ts->camd35.emm_queue = queue_new();
383
-		pthread_create(&ts->camd35.thread, NULL , &camd_thread, ts);
239
+		c->req_queue = queue_new();
240
+		c->ecm_queue = queue_new();
241
+		c->emm_queue = queue_new();
242
+		pthread_create(&c->thread, NULL , &camd_thread, ts);
384 243
 	}
385 244
 }
386 245
 
387 246
 void camd_stop(struct ts *ts) {
247
+	struct camd35 *c = &ts->camd35;
388 248
 	ts->camd_stop = 1;
389
-	if (ts->camd35.thread) {
390
-		queue_wakeup(ts->camd35.req_queue);
391
-		pthread_join(ts->camd35.thread, NULL);
392
-		queue_free(&ts->camd35.req_queue);
393
-		queue_free(&ts->camd35.ecm_queue);
394
-		queue_free(&ts->camd35.emm_queue);
395
-		ts->camd35.thread = 0;
249
+	if (c->thread) {
250
+		queue_wakeup(c->req_queue);
251
+		pthread_join(c->thread, NULL);
252
+		queue_free(&c->req_queue);
253
+		queue_free(&c->ecm_queue);
254
+		queue_free(&c->emm_queue);
255
+		c->thread = 0;
396 256
 	}
397
-	camd35_disconnect(ts);
257
+	c->ops.disconnect(c);
398 258
 }

+ 4
- 0
camd.h View File

@@ -20,6 +20,8 @@
20 20
 
21 21
 #include "data.h"
22 22
 
23
+int						camd_tcp_connect	(struct in_addr ip, int port);
24
+
23 25
 struct camd_msg *		camd_msg_alloc_emm	(uint16_t ca_id, uint8_t *emm_data, uint8_t emm_data_len);
24 26
 struct camd_msg *		camd_msg_alloc_ecm	(uint16_t ca_id, uint16_t service_id, uint16_t idx, uint8_t *ecm_data, uint8_t ecm_data_len);
25 27
 void					camd_msg_free   	(struct camd_msg **pmsg);
@@ -28,4 +30,6 @@ void					camd_start			(struct ts *ts);
28 30
 void					camd_stop			(struct ts *ts);
29 31
 void					camd_msg_process	(struct ts *ts, struct camd_msg *msg);
30 32
 
33
+void					camd_proto_cs378x	(struct camd_ops *ops);
34
+
31 35
 #endif

+ 19
- 6
data.h View File

@@ -61,28 +61,41 @@ struct key {
61 61
 // When this limit is reached camd_reconnect is called.
62 62
 #define EMM_RECV_ERRORS_LIMIT 100
63 63
 
64
+struct camd35;
65
+
66
+struct camd_ops {
67
+	int (*connect)(struct camd35 *c);
68
+	void (*disconnect)(struct camd35 *c);
69
+	int (*reconnect)(struct camd35 *c);
70
+	int (*do_emm)(struct camd35 *c, uint16_t ca_id, uint8_t *data, uint8_t data_len);
71
+	int (*do_ecm)(struct camd35 *c, uint16_t ca_id, uint16_t service_id, uint16_t idx, uint8_t *data, uint8_t data_len);
72
+	int (*get_cw)(struct camd35 *c, uint16_t *ca_id, uint16_t *idx, uint8_t *cw);
73
+};
74
+
64 75
 struct camd35 {
65
-	uint8_t			buf[CAMD35_BUF_LEN];
66
-
67 76
 	int				server_fd;
68 77
 	struct in_addr	server_addr;
69 78
 	unsigned int	server_port;
70 79
 	char			user[64];
71 80
 	char			pass[64];
72
-	AES_KEY			aes_encrypt_key;
73
-	AES_KEY			aes_decrypt_key;
74 81
 
75 82
 	unsigned int	ecm_recv_errors; // Error counter, reset on successful send/recv
76 83
 	unsigned int	emm_recv_errors; // Error counter, reset on successful send/recv
77 84
 
78
-	uint32_t		auth_token;
79
-
80 85
 	struct key		*key;
81 86
 
82 87
 	pthread_t		thread;
83 88
 	QUEUE			*req_queue;
84 89
 	QUEUE			*ecm_queue;
85 90
 	QUEUE			*emm_queue;
91
+
92
+	struct camd_ops ops;
93
+
94
+	// cs378x private data
95
+	uint8_t			buf[CAMD35_BUF_LEN];
96
+	AES_KEY			aes_encrypt_key;
97
+	AES_KEY			aes_decrypt_key;
98
+	uint32_t		auth_token;
86 99
 };
87 100
 
88 101
 enum io_type {

+ 2
- 0
tsdecrypt.c View File

@@ -628,6 +628,8 @@ int main(int argc, char **argv) {
628 628
 
629 629
 	parse_options(&ts, argc, argv);
630 630
 
631
+	camd_proto_cs378x(&ts.camd35.ops);
632
+
631 633
 	if (ts.pidfile[0])
632 634
 		daemonize(ts.pidfile);
633 635
 

Loading…
Cancel
Save