Browse Source

Move camd communication into thread

Georgi Chorbadzhiyski 13 years ago
parent
commit
4f99f75470
6 changed files with 110 additions and 20 deletions
  1. 80
    6
      camd.c
  2. 6
    4
      camd.h
  3. 20
    0
      data.h
  4. 2
    2
      tables.c
  5. 2
    2
      tsdecrypt.c
  6. 0
    6
      udp.c

+ 80
- 6
camd.c View File

@@ -1,8 +1,7 @@
1
+#include <stdlib.h>
1 2
 #include <unistd.h>
2
-
3 3
 #include <string.h>
4 4
 #include <sys/errno.h>
5
-
6 5
 #include <sys/socket.h>
7 6
 #include <netinet/in.h>
8 7
 #include <arpa/inet.h>
@@ -55,13 +54,13 @@ static void camd35_init_auth(struct camd35 *c) {
55 54
 	AES_set_decrypt_key(dump, 128, &c->aes_decrypt_key);
56 55
 }
57 56
 
58
-int camd35_connect(struct camd35 *c) {
57
+static int camd35_connect(struct camd35 *c) {
59 58
 	if (c->server_fd < 0)
60 59
 		c->server_fd = connect_to(c->server_addr, c->server_port);
61 60
 	return c->server_fd;
62 61
 }
63 62
 
64
-void camd35_disconnect(struct camd35 *c) {
63
+static void camd35_disconnect(struct camd35 *c) {
65 64
 	shutdown_fd(&c->server_fd);
66 65
 }
67 66
 
@@ -158,7 +157,7 @@ static void camd35_buf_init(struct camd35 *c, uint8_t *data, int data_len) {
158 157
 	memcpy(c->buf + CAMD35_HDR_LEN, data, data_len); // Copy data to buf
159 158
 }
160 159
 
161
-int camd35_send_ecm(struct camd35 *c, uint16_t service_id, uint16_t ca_id, uint16_t idx, uint8_t *data, uint8_t data_len) {
160
+static int camd35_send_ecm(struct camd35 *c, uint16_t ca_id, uint16_t service_id, uint16_t idx, uint8_t *data, uint8_t data_len) {
162 161
 	uint32_t provider_id = 0;
163 162
 	int to_send = boundary(4, CAMD35_HDR_LEN + data_len);
164 163
 
@@ -183,7 +182,7 @@ int camd35_send_ecm(struct camd35 *c, uint16_t service_id, uint16_t ca_id, uint1
183 182
 	return 0;
184 183
 }
185 184
 
186
-int camd35_send_emm(struct camd35 *c, uint16_t ca_id, uint8_t *data, uint8_t data_len) {
185
+static int camd35_send_emm(struct camd35 *c, uint16_t ca_id, uint8_t *data, uint8_t data_len) {
187 186
 	uint32_t prov_id = 0;
188 187
 	int to_send = boundary(4, CAMD35_HDR_LEN + data_len);
189 188
 
@@ -200,3 +199,78 @@ int camd35_send_emm(struct camd35 *c, uint16_t ca_id, uint8_t *data, uint8_t dat
200 199
 
201 200
 	return camd35_send_buf(c, to_send);
202 201
 }
202
+
203
+static void camd_do_msg(struct camd_msg *msg) {
204
+	if (msg->type == EMM_MSG)
205
+		camd35_send_emm(&msg->ts->camd35, msg->ca_id, msg->data, msg->data_len);
206
+	if (msg->type == ECM_MSG)
207
+		camd35_send_ecm(&msg->ts->camd35, msg->ca_id, msg->service_id, msg->idx, msg->data, msg->data_len);
208
+	camd_msg_free(&msg);
209
+}
210
+
211
+struct camd_msg *camd_msg_alloc_emm(uint16_t ca_id, uint8_t *data, uint8_t data_len) {
212
+	struct camd_msg *c = calloc(1, sizeof(struct camd_msg));
213
+	c->type       = EMM_MSG;
214
+	c->ca_id      = ca_id;
215
+	c->data_len   = data_len;
216
+	memcpy(c->data, data, data_len);
217
+	return c;
218
+}
219
+
220
+struct camd_msg *camd_msg_alloc_ecm(uint16_t ca_id, uint16_t service_id, uint16_t idx, uint8_t *data, uint8_t data_len) {
221
+	struct camd_msg *c = calloc(1, sizeof(struct camd_msg));
222
+	c->type       = ECM_MSG;
223
+	c->idx        = idx;
224
+	c->ca_id      = ca_id;
225
+	c->service_id = service_id;
226
+	c->data_len   = data_len;
227
+	memcpy(c->data, data, data_len);
228
+	return c;
229
+}
230
+
231
+void camd_msg_free(struct camd_msg **pmsg) {
232
+	struct camd_msg *m = *pmsg;
233
+	if (m) {
234
+		FREE(*pmsg);
235
+	}
236
+}
237
+
238
+static void *camd_thread(void *in_ts) {
239
+	struct ts *ts = in_ts;
240
+	while (1) {
241
+		struct camd_msg *msg = queue_get(ts->camd35.queue); // Waits...
242
+		if (!msg || ts->camd_stop)
243
+			break;
244
+		camd_do_msg(msg);
245
+	}
246
+	pthread_exit(0);
247
+}
248
+
249
+void camd_msg_process(struct ts *ts, struct camd_msg *msg) {
250
+	msg->ts = ts;
251
+	if (ts->camd35.thread) {
252
+		queue_add(ts->camd35.queue, msg);
253
+	} else {
254
+		camd_do_msg(msg);
255
+	}
256
+}
257
+
258
+void camd_start(struct ts *ts) {
259
+	camd35_connect(&ts->camd35);
260
+	// The input is not file, process messages using async thread
261
+	if (!(ts->input.type == FILE_IO && ts->input.fd != 0)) {
262
+		ts->camd35.queue = queue_new();
263
+		pthread_create(&ts->camd35.thread, NULL , &camd_thread, ts);
264
+	}
265
+}
266
+
267
+void camd_stop(struct ts *ts) {
268
+	ts->camd_stop = 1;
269
+	if (ts->camd35.thread) {
270
+		queue_wakeup(ts->camd35.queue);
271
+		pthread_join(ts->camd35.thread, NULL);
272
+		queue_free(&ts->camd35.queue);
273
+		ts->camd35.thread = 0;
274
+	}
275
+	camd35_disconnect(&ts->camd35);
276
+}

+ 6
- 4
camd.h View File

@@ -3,10 +3,12 @@
3 3
 
4 4
 #include "data.h"
5 5
 
6
-int camd35_connect		(struct camd35 *c);
7
-void camd35_disconnect	(struct camd35 *c);
6
+struct camd_msg *		camd_msg_alloc_emm	(uint16_t ca_id, uint8_t *emm_data, uint8_t emm_data_len);
7
+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);
8
+void					camd_msg_free   	(struct camd_msg **pmsg);
8 9
 
9
-int camd35_send_ecm		(struct camd35 *c, uint16_t service_id, uint16_t ca_id, uint16_t idx, uint8_t *data, uint8_t data_len);
10
-int camd35_send_emm		(struct camd35 *c, uint16_t ca_id, uint8_t *data, uint8_t data_len);
10
+void					camd_start			(struct ts *ts);
11
+void					camd_stop			(struct ts *ts);
12
+void					camd_msg_process	(struct ts *ts, struct camd_msg *msg);
11 13
 
12 14
 #endif

+ 20
- 0
data.h View File

@@ -1,11 +1,14 @@
1 1
 #ifndef DATA_H
2 2
 #define DATA_H
3 3
 
4
+#include <pthread.h>
5
+
4 6
 #include <openssl/aes.h>
5 7
 #include <openssl/md5.h>
6 8
 
7 9
 #include <dvbcsa/dvbcsa.h>
8 10
 
11
+#include "libfuncs/libfuncs.h"
9 12
 #include "libts/tsfuncs.h"
10 13
 
11 14
 struct key {
@@ -33,6 +36,9 @@ struct camd35 {
33 36
 	uint32_t		auth_token;
34 37
 
35 38
 	struct key		*key;
39
+
40
+	pthread_t		thread;
41
+	QUEUE			*queue;
36 42
 };
37 43
 
38 44
 enum io_type {
@@ -80,6 +86,20 @@ struct ts {
80 86
 	struct io			output;
81 87
 
82 88
 	int					debug_level;
89
+
90
+	int					camd_stop;
91
+};
92
+
93
+enum msg_type { EMM_MSG, ECM_MSG };
94
+
95
+struct camd_msg {
96
+	enum msg_type	type;
97
+	uint16_t		idx;
98
+	uint16_t		ca_id;
99
+	uint16_t		service_id;
100
+	uint8_t			data_len;
101
+	uint8_t			data[255];
102
+	struct ts		*ts;
83 103
 };
84 104
 
85 105
 void data_init(struct ts *ts);

+ 2
- 2
tables.c View File

@@ -106,7 +106,7 @@ void process_emm(struct ts *ts, uint16_t pid, uint8_t *ts_packet) {
106 106
 			sec->section_data_len,
107 107
 			dump);
108 108
 	}
109
-	camd35_send_emm(&ts->camd35, ts->emm_caid, sec->section_data, sec->section_data_len);
109
+	camd_msg_process(ts, camd_msg_alloc_emm(ts->emm_caid, sec->section_data, sec->section_data_len));
110 110
 	ts_privsec_copy(ts->emm, ts->last_emm);
111 111
 	ts_privsec_clear(ts->emm);
112 112
 }
@@ -132,7 +132,7 @@ void process_ecm(struct ts *ts, uint16_t pid, uint8_t *ts_packet) {
132 132
 			sec->section_data_len,
133 133
 			ts->ecm_counter,
134 134
 			dump);
135
-		camd35_send_ecm(&ts->camd35, ts->service_id, ts->ecm_caid, ts->ecm_counter++, sec->section_data, sec->section_data_len);
135
+		camd_msg_process(ts, camd_msg_alloc_ecm(ts->ecm_caid, ts->service_id, ts->ecm_counter++, sec->section_data, sec->section_data_len));
136 136
 	} else if (ts->debug_level >= 3) {
137 137
 		ts_LOGf("ECM | CAID: 0x%04x PID 0x%04x Table: 0x%02x Length: %3d IDX: 0x%04x Data: -dup-\n",
138 138
 			ts->ecm_caid,

+ 2
- 2
tsdecrypt.c View File

@@ -299,7 +299,7 @@ int main(int argc, char **argv) {
299 299
 	if (ts.output.type == NET_IO && udp_connect_output(&ts.output) < 1)
300 300
 		goto EXIT;
301 301
 
302
-	camd35_connect(&ts.camd35);
302
+	camd_start(&ts);
303 303
 	do {
304 304
 		readen = read(ts.input.fd, ts_packet, FRAME_SIZE);
305 305
 		if (readen > 0) {
@@ -308,7 +308,7 @@ int main(int argc, char **argv) {
308 308
 		}
309 309
 	} while (readen > 0);
310 310
 EXIT:
311
-	camd35_disconnect(&ts.camd35);
311
+	camd_stop(&ts);
312 312
 
313 313
 	data_free(&ts);
314 314
 

+ 0
- 6
udp.c View File

@@ -12,12 +12,6 @@
12 12
 
13 13
 #include "udp.h"
14 14
 
15
-static void set_sock_nonblock(int sockfd) {
16
-	int arg = fcntl(sockfd, F_GETFL, NULL);
17
-	arg |= O_NONBLOCK;
18
-	fcntl(sockfd, F_SETFL, arg);
19
-}
20
-
21 15
 int udp_connect_input(struct io *io) {
22 16
 	int sock = socket(AF_INET, SOCK_DGRAM, 0);
23 17
 	if (sock < 0) {

Loading…
Cancel
Save