|
@@ -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
|
+}
|