Browse Source

Abstract libdvbcsa calls and move all CSA code in csa.c

Georgi Chorbadzhiyski 12 years ago
parent
commit
a382b55712
8 changed files with 145 additions and 51 deletions
  1. 1
    0
      Makefile
  2. 6
    11
      camd.c
  3. 1
    1
      camd.h
  4. 56
    2
      csa.c
  5. 46
    0
      csa.h
  6. 5
    13
      data.c
  7. 3
    4
      data.h
  8. 27
    20
      process.c

+ 1
- 0
Makefile View File

@@ -20,6 +20,7 @@ CFLAGS ?= -O2 -ggdb \
20 20
 
21 21
 DEFS = -DBUILD_ID=\"$(BUILD_ID)\" \
22 22
  -DVERSION=\"$(VERSION)\" -DGIT_VER=\"$(GIT_VER)\"
23
+DEFS += -DUSE_LIBDVBCSA=1
23 24
 
24 25
 PREFIX ?= /usr/local
25 26
 

+ 6
- 11
camd.c View File

@@ -24,11 +24,10 @@
24 24
 #include <netinet/tcp.h>
25 25
 #include <arpa/inet.h>
26 26
 
27
-#include <dvbcsa/dvbcsa.h>
28
-
29 27
 #include "libfuncs/libfuncs.h"
30 28
 
31 29
 #include "data.h"
30
+#include "csa.h"
32 31
 #include "util.h"
33 32
 #include "camd.h"
34 33
 #include "notify.h"
@@ -62,7 +61,7 @@ int camd_tcp_connect(struct in_addr ip, int port) {
62 61
 	return fd;
63 62
 }
64 63
 
65
-void camd_set_cw(struct ts *ts, unsigned char *new_cw, int check_validity) {
64
+void camd_set_cw(struct ts *ts, uint8_t *new_cw, int check_validity) {
66 65
 	struct camd *c = &ts->camd;
67 66
 
68 67
 	c->ecm_recv_errors = 0;
@@ -71,15 +70,11 @@ void camd_set_cw(struct ts *ts, unsigned char *new_cw, int check_validity) {
71 70
 	c->key->ts = c->key->ts_keyset.tv_sec;
72 71
 	ts->cw_last_warn = c->key->ts;
73 72
 
74
-	if (!check_validity || memcmp(c->key->cw, invalid_cw, 8) != 0) {
75
-		dvbcsa_key_set   (new_cw, c->key->s_csakey[0]);
76
-		dvbcsa_bs_key_set(new_cw, c->key->bs_csakey[0]);
77
-	}
73
+	if (!check_validity || memcmp(c->key->cw, invalid_cw, 8) != 0)
74
+		csa_set_even_cw(c->key->csakey, new_cw);
78 75
 
79
-	if (!check_validity || memcmp(c->key->cw + 8, invalid_cw, 8) != 0) {
80
-		dvbcsa_key_set(new_cw + 8, c->key->s_csakey[1]);
81
-		dvbcsa_bs_key_set(new_cw + 8, c->key->bs_csakey[1]);
82
-	}
76
+	if (!check_validity || memcmp(c->key->cw + 8, invalid_cw, 8) != 0)
77
+		csa_set_odd_cw(c->key->csakey, new_cw + 8);
83 78
 }
84 79
 
85 80
 static int camd_recv_cw(struct ts *ts) {

+ 1
- 1
camd.h View File

@@ -25,7 +25,7 @@ int						camd_tcp_connect	(struct in_addr ip, int port);
25 25
 struct camd_msg *		camd_msg_alloc		(enum msg_type msg_type, uint16_t ca_id, uint16_t service_id, uint8_t *data, uint8_t data_len);
26 26
 void					camd_msg_free   	(struct camd_msg **pmsg);
27 27
 
28
-void					camd_set_cw			(struct ts *ts, unsigned char *new_cw, int check_validity);
28
+void					camd_set_cw			(struct ts *ts, uint8_t *new_cw, int check_validity);
29 29
 
30 30
 void					camd_start			(struct ts *ts);
31 31
 void					camd_stop			(struct ts *ts);

+ 56
- 2
csa.c View File

@@ -22,10 +22,64 @@
22 22
 #include <inttypes.h>
23 23
 #include <sys/time.h>
24 24
 
25
-#include <dvbcsa/dvbcsa.h>
26
-
27 25
 #include "libfuncs/libfuncs.h"
28 26
 
27
+#include "csa.h"
28
+
29
+csakey_t *csa_key_alloc(void) {
30
+	struct csakey *key = calloc(1, sizeof(struct csakey));
31
+	key->s_csakey[0] = dvbcsa_key_alloc();
32
+	key->s_csakey[1] = dvbcsa_key_alloc();
33
+	key->bs_csakey[0] = dvbcsa_bs_key_alloc();
34
+	key->bs_csakey[1] = dvbcsa_bs_key_alloc();
35
+	return (csakey_t *)key;
36
+}
37
+
38
+void csa_key_free(csakey_t **pcsakey) {
39
+	struct csakey *key = *((struct csakey **)pcsakey);
40
+	if (key) {
41
+		dvbcsa_key_free(key->s_csakey[0]);
42
+		dvbcsa_key_free(key->s_csakey[1]);
43
+		dvbcsa_bs_key_free(key->bs_csakey[0]);
44
+		dvbcsa_bs_key_free(key->bs_csakey[1]);
45
+		FREE(*pcsakey);
46
+	}
47
+}
48
+
49
+inline unsigned int csa_get_batch_size(void) {
50
+	if (use_dvbcsa) {
51
+		return dvbcsa_bs_batch_size(); // 32?
52
+	}
53
+	return 0;
54
+}
55
+
56
+inline void csa_set_even_cw(csakey_t *csakey, uint8_t *even_cw) {
57
+	struct csakey *key = (struct csakey *)csakey;
58
+	dvbcsa_key_set(even_cw, key->s_csakey[0]);
59
+	dvbcsa_bs_key_set(even_cw, key->bs_csakey[0]);
60
+}
61
+
62
+inline void csa_set_odd_cw(csakey_t *csakey, uint8_t *odd_cw) {
63
+	struct csakey *key = (struct csakey *)csakey;
64
+	dvbcsa_key_set(odd_cw, key->s_csakey[1]);
65
+	dvbcsa_bs_key_set(odd_cw, key->bs_csakey[1]);
66
+}
67
+
68
+inline void csa_decrypt_single_packet(csakey_t *csakey, uint8_t *payload_start, unsigned int payload_len, unsigned int key_idx) {
69
+	struct csakey *key = (struct csakey *)csakey;
70
+	dvbcsa_decrypt(key->s_csakey[key_idx], payload_start, payload_len);
71
+}
72
+
73
+inline void csa_decrypt_multiple_even(csakey_t *csakey, struct csa_batch *batch) {
74
+	struct csakey *key = (struct csakey *)csakey;
75
+	dvbcsa_bs_decrypt(key->bs_csakey[0], (struct dvbcsa_bs_batch_s *)batch, 184);
76
+}
77
+
78
+inline void csa_decrypt_multiple_odd(csakey_t *csakey, struct csa_batch *batch) {
79
+	struct csakey *key = (struct csakey *)csakey;
80
+	dvbcsa_bs_decrypt(key->bs_csakey[1], (struct dvbcsa_bs_batch_s *)batch, 184);
81
+}
82
+
29 83
 /* The following routine is taken from benchbitslice in libdvbcsa */
30 84
 void csa_benchmark(void) {
31 85
 	struct timeval t0, t1;

+ 46
- 0
csa.h View File

@@ -18,6 +18,52 @@
18 18
 #ifndef CSA_H
19 19
 #define CSA_H
20 20
 
21
+// The following *MUST* be the same as struct dvbcsa_bs_batch_s from libdvbcsa
22
+struct csa_batch {
23
+	uint8_t			*data;	// Pointer to payload
24
+	unsigned int	len;	// Payload bytes lenght
25
+};
26
+
27
+#if USE_LIBDVBCSA
28
+#include <dvbcsa/dvbcsa.h>
29
+#define use_dvbcsa 1
30
+#else
31
+#define use_dvbcsa 0
32
+#define dvbcsa_key_t void
33
+#define dvbcsa_bs_key_t void
34
+#define dvbcsa_bs_batch_s csa_batch
35
+static inline dvbcsa_key_t *	dvbcsa_key_alloc(void) { return NULL; }
36
+static inline void				dvbcsa_key_free(dvbcsa_key_t *key) { (void)key; }
37
+static inline void				dvbcsa_key_set(const uint8_t *cw, dvbcsa_key_t *key) { (void)cw; (void)key; }
38
+static inline void				dvbcsa_decrypt(const uint8_t *key, uint8_t *data, unsigned int len) { (void)key; (void)data; (void)len; }
39
+static inline unsigned int		dvbcsa_bs_batch_size(void) { return 0; }
40
+static inline dvbcsa_bs_key_t *	dvbcsa_bs_key_alloc(void) { return NULL; }
41
+static inline void				dvbcsa_bs_key_free(dvbcsa_bs_key_t *key) { (void)key; }
42
+static inline void				dvbcsa_bs_key_set(uint8_t *cw, dvbcsa_bs_key_t *key) { (void)cw; (void)key; }
43
+static inline void				dvbcsa_bs_decrypt(const dvbcsa_bs_key_t *key, const struct dvbcsa_bs_batch_s *pcks, unsigned int maxlen) { (void)key; (void)pcks; (void)maxlen; }
44
+#endif
45
+
46
+#include "data.h"
47
+
48
+struct csakey {
49
+	dvbcsa_key_t		*s_csakey[2];
50
+	dvbcsa_bs_key_t		*bs_csakey[2];
51
+};
52
+
53
+csakey_t *		csa_key_alloc		(void);
54
+void			csa_key_free		(csakey_t **pcsakey);
55
+
56
+unsigned int	csa_get_batch_size	(void);
57
+
58
+void			csa_set_even_cw		(csakey_t *csakey, uint8_t *even_cw);
59
+void			csa_set_odd_cw		(csakey_t *csakey, uint8_t *odd_cw);
60
+
61
+// key_idx 0 == even key
62
+// key_idx 1 == odd key
63
+void			csa_decrypt_single_packet	(csakey_t *csakey, uint8_t *payload, unsigned int payload_len, unsigned int key_idx);
64
+void			csa_decrypt_multiple_even	(csakey_t *csakey, struct csa_batch *batch);
65
+void			csa_decrypt_multiple_odd	(csakey_t *csakey, struct csa_batch *batch);
66
+
21 67
 void csa_benchmark(void);
22 68
 
23 69
 #endif

+ 5
- 13
data.c View File

@@ -20,6 +20,7 @@
20 20
 #include <string.h>
21 21
 
22 22
 #include "data.h"
23
+#include "csa.h"
23 24
 #include "camd.h"
24 25
 
25 26
 void data_init(struct ts *ts) {
@@ -52,12 +53,7 @@ void data_init(struct ts *ts) {
52 53
 
53 54
 	// Key
54 55
 	memset(&ts->key, 0, sizeof(ts->key));
55
-	ts->key.s_csakey[0] = dvbcsa_key_alloc();
56
-	ts->key.s_csakey[1] = dvbcsa_key_alloc();
57
-
58
-	ts->key.bs_csakey[0] = dvbcsa_bs_key_alloc();
59
-	ts->key.bs_csakey[1] = dvbcsa_bs_key_alloc();
60
-
56
+	ts->key.csakey = csa_key_alloc();
61 57
 	gettimeofday(&ts->key.ts_keyset, NULL);
62 58
 
63 59
 	// CAMD
@@ -101,8 +97,8 @@ void data_init(struct ts *ts) {
101 97
 	ts->output.ttl  = 1;
102 98
 	ts->output.tos  = -1;
103 99
 
104
-	ts->decode_buf  = cbuf_init((7 * dvbcsa_bs_batch_size() * 188) * 16, "decode"); // ~658Kb
105
-	ts->write_buf   = cbuf_init((7 * dvbcsa_bs_batch_size() * 188) *  8, "write");  // ~324Kb
100
+	ts->decode_buf  = cbuf_init((7 * csa_get_batch_size() * 188) * 16, "decode"); // ~658Kb
101
+	ts->write_buf   = cbuf_init((7 * csa_get_batch_size() * 188) *  8, "write");  // ~324Kb
106 102
 
107 103
 	ts->input_buffer= list_new("input");
108 104
 
@@ -130,11 +126,7 @@ void data_free(struct ts *ts) {
130 126
 	ts_privsec_free(&ts->last_ecm);
131 127
 	ts_privsec_free(&ts->tmp_ecm);
132 128
 
133
-	dvbcsa_key_free(ts->key.s_csakey[0]);
134
-	dvbcsa_key_free(ts->key.s_csakey[1]);
135
-
136
-	dvbcsa_bs_key_free(ts->key.bs_csakey[0]);
137
-	dvbcsa_bs_key_free(ts->key.bs_csakey[1]);
129
+	csa_key_free(&ts->key.csakey);
138 130
 
139 131
 	cbuf_free(&ts->decode_buf);
140 132
 	cbuf_free(&ts->write_buf);

+ 3
- 4
data.h View File

@@ -25,8 +25,6 @@
25 25
 #include <openssl/des.h>
26 26
 #include <openssl/md5.h>
27 27
 
28
-#include <dvbcsa/dvbcsa.h>
29
-
30 28
 #include "libfuncs/libfuncs.h"
31 29
 #include "libtsfuncs/tsfuncs.h"
32 30
 
@@ -54,11 +52,12 @@ struct notify {
54 52
 
55 53
 #define CODEWORD_LENGTH 16
56 54
 
55
+typedef void csakey_t;
56
+
57 57
 struct key {
58 58
 	uint8_t				cw[CODEWORD_LENGTH];
59
+	csakey_t			*csakey;
59 60
 	int					is_valid_cw;
60
-	struct dvbcsa_key_s	*s_csakey[2];
61
-	struct dvbcsa_bs_key_s	*bs_csakey[2];
62 61
 	time_t					ts;				// At what time the key is set
63 62
 	struct timeval			ts_keyset;		// At what time the key is set
64 63
 };

+ 27
- 20
process.c View File

@@ -20,6 +20,7 @@
20 20
 #include <sys/uio.h>
21 21
 
22 22
 #include "data.h"
23
+#include "csa.h"
23 24
 #include "tables.h"
24 25
 #include "util.h"
25 26
 
@@ -107,7 +108,7 @@ static void decode_packet(struct ts *ts, uint8_t *ts_packet) {
107 108
 			// scramble_idx 3 == odd key
108 109
 			ts_packet_set_not_scrambled(ts_packet);
109 110
 			uint8_t payload_ofs = ts_packet_get_payload_offset(ts_packet);
110
-			dvbcsa_decrypt(ts->key.s_csakey[scramble_idx - 2], ts_packet + payload_ofs, 188 - payload_ofs);
111
+			csa_decrypt_single_packet(ts->key.csakey, ts_packet + payload_ofs, 188 - payload_ofs, scramble_idx - 2);
111 112
 		} else {
112 113
 			// Can't decrypt the packet just make it NULL packet
113 114
 			if (ts->pid_filter)
@@ -118,11 +119,11 @@ static void decode_packet(struct ts *ts, uint8_t *ts_packet) {
118 119
 
119 120
 static void decode_buffer(struct ts *ts, uint8_t *data, int data_len) {
120 121
 	int i;
121
-	int batch_sz = dvbcsa_bs_batch_size(); // 32?
122
+	int batch_sz = csa_get_batch_size(); // 32?
122 123
 	int even_packets = 0;
123 124
 	int odd_packets  = 0;
124
-	struct dvbcsa_bs_batch_s even_pcks[batch_sz + 1];
125
-	struct dvbcsa_bs_batch_s odd_pcks [batch_sz + 1];
125
+	struct csa_batch even_pcks[batch_sz + 1];
126
+	struct csa_batch odd_pcks [batch_sz + 1];
126 127
 
127 128
 	int scramble_idx_old = 0;
128 129
 
@@ -136,18 +137,20 @@ static void decode_buffer(struct ts *ts, uint8_t *data, int data_len) {
136 137
 				int scramble_idx = ts_packet_get_scrambled(ts_packet);
137 138
 				if (!scramble_idx_old)
138 139
 					scramble_idx_old = scramble_idx;
139
-				uint8_t payload_ofs = ts_packet_get_payload_offset(ts_packet);
140
-				if (scramble_idx == 2) { // scramble_idx 2 == even key
141
-					even_pcks[even_packets].data = ts_packet + payload_ofs;
142
-					even_pcks[even_packets].len  = 188 - payload_ofs;
143
-					even_packets++;
140
+				if (use_dvbcsa) {
141
+					uint8_t payload_ofs = ts_packet_get_payload_offset(ts_packet);
142
+					if (scramble_idx == 2) { // scramble_idx 2 == even key
143
+						even_pcks[even_packets].data = ts_packet + payload_ofs;
144
+						even_pcks[even_packets].len  = 188 - payload_ofs;
145
+						even_packets++;
146
+					}
147
+					if (scramble_idx == 3) { // scramble_idx 3 == odd key
148
+						odd_pcks[odd_packets].data = ts_packet + payload_ofs;
149
+						odd_pcks[odd_packets].len  = 188 - payload_ofs;
150
+						odd_packets++;
151
+					}
152
+					ts_packet_set_not_scrambled(ts_packet);
144 153
 				}
145
-				if (scramble_idx == 3) { // scramble_idx 3 == odd key
146
-					odd_pcks[odd_packets].data = ts_packet + payload_ofs;
147
-					odd_pcks[odd_packets].len  = 188 - payload_ofs;
148
-					odd_packets++;
149
-				}
150
-				ts_packet_set_not_scrambled(ts_packet);
151 154
 				if (scramble_idx_old != scramble_idx && !ts->camd.constant_codeword) {
152 155
 					struct timeval tv;
153 156
 					gettimeofday(&tv, NULL);
@@ -166,12 +169,16 @@ static void decode_buffer(struct ts *ts, uint8_t *data, int data_len) {
166 169
 
167 170
 	// Decode packets
168 171
 	if (even_packets) {
169
-		even_pcks[even_packets].data = NULL; // Last one...
170
-		dvbcsa_bs_decrypt(ts->key.bs_csakey[0], even_pcks, 184);
172
+		if (use_dvbcsa) {
173
+			even_pcks[even_packets].data = NULL; // Last one...
174
+			csa_decrypt_multiple_even(ts->key.csakey, even_pcks);
175
+		}
171 176
 	}
172 177
 	if (odd_packets) {
173
-		odd_pcks[odd_packets].data = NULL; // Last one...
174
-		dvbcsa_bs_decrypt(ts->key.bs_csakey[1], odd_pcks, 184);
178
+		if (use_dvbcsa) {
179
+			odd_pcks[odd_packets].data = NULL; // Last one...
180
+			csa_decrypt_multiple_odd(ts->key.csakey, odd_pcks);
181
+		}
175 182
 	}
176 183
 
177 184
 	// Fill write buffer
@@ -192,7 +199,7 @@ void *decode_thread(void *_ts) {
192 199
 	struct ts *ts = _ts;
193 200
 	uint8_t *data;
194 201
 	int data_size;
195
-	int req_size = 188 * dvbcsa_bs_batch_size();
202
+	int req_size = 188 * csa_get_batch_size();
196 203
 
197 204
 	set_thread_name("tsdec-decode");
198 205
 

Loading…
Cancel
Save