|
@@ -17,6 +17,7 @@
|
17
|
17
|
*/
|
18
|
18
|
#include <stdlib.h>
|
19
|
19
|
#include <unistd.h>
|
|
20
|
+#include <getopt.h>
|
20
|
21
|
#include <string.h>
|
21
|
22
|
#include <sys/types.h>
|
22
|
23
|
#include <sys/stat.h>
|
|
@@ -45,65 +46,93 @@ static void LOG_func(const char *msg) {
|
45
|
46
|
fprintf(stderr, "%s | %s", date, msg);
|
46
|
47
|
}
|
47
|
48
|
|
|
49
|
+static const struct option long_options[] = {
|
|
50
|
+ { "ident", required_argument, NULL, 'i' },
|
|
51
|
+ { "daemon", required_argument, NULL, 'd' },
|
|
52
|
+ { "syslog-host", required_argument, NULL, 'l' },
|
|
53
|
+ { "syslog-port", required_argument, NULL, 'L' },
|
|
54
|
+
|
|
55
|
+ { "input", required_argument, NULL, 'I' },
|
|
56
|
+ { "input-rtp", no_argument, NULL, 'R' },
|
|
57
|
+ { "input-ignore-disc", no_argument, NULL, 'z' },
|
|
58
|
+
|
|
59
|
+ { "output", required_argument, NULL, 'O' },
|
|
60
|
+ { "output-intf", required_argument, NULL, 'o' },
|
|
61
|
+ { "output-ttl", required_argument, NULL, 't' },
|
|
62
|
+ { "output-filter", no_argument, NULL, 'p' },
|
|
63
|
+
|
|
64
|
+ { "ca-system", required_argument, NULL, 'c' },
|
|
65
|
+ { "camd-server", required_argument, NULL, 's' },
|
|
66
|
+ { "camd-user", required_argument, NULL, 'U' },
|
|
67
|
+ { "camd-pass", required_argument, NULL, 'P' },
|
|
68
|
+ { "camd-pkt-delay", required_argument, NULL, 'y' },
|
|
69
|
+
|
|
70
|
+ { "emm", no_argument, NULL, 'e' },
|
|
71
|
+ { "emm-only", no_argument, NULL, 'E' },
|
|
72
|
+ { "emm-report-time", required_argument, NULL, 'f' },
|
|
73
|
+
|
|
74
|
+ { "ecm-irdeto-type", required_argument, NULL, 'G' },
|
|
75
|
+
|
|
76
|
+ { "debug", required_argument, NULL, 'D' },
|
|
77
|
+ { "help", no_argument, NULL, 'h' },
|
|
78
|
+
|
|
79
|
+ { 0, 0, 0, 0 }
|
|
80
|
+};
|
|
81
|
+
|
48
|
82
|
static void show_help(struct ts *ts) {
|
49
|
83
|
printf("%s\n", program_id);
|
50
|
84
|
printf("Copyright (c) 2011 Unix Solutions Ltd.\n");
|
51
|
85
|
printf("\n");
|
52
|
86
|
printf(" Usage: " PROGRAM_NAME " [opts]\n");
|
53
|
87
|
printf("\n");
|
54
|
|
- printf(" Daemon options:\n");
|
55
|
|
- printf(" -i server_ident | Format PROVIDER/CHANNEL (default: %s)\n", ts->ident);
|
56
|
|
- printf(" -d pidfile | Daemonize program with pid file. (default: do not daemonize)\n");
|
57
|
|
- printf(" -l syslog host | Where is the syslog server (default: disabled)\n");
|
58
|
|
- printf(" -L Syslog port | What is the syslog server port (default: %d)\n", ts->syslog_port);
|
59
|
|
- printf("\n");
|
60
|
|
- printf(" Input options:\n");
|
61
|
|
- printf(" -I input | Where to read from. Supports files and multicast\n");
|
62
|
|
- printf(" | -I 224.0.0.1:5000 (multicast receive)\n");
|
63
|
|
- printf(" | -I file.ts (read from file)\n");
|
64
|
|
- printf(" | -I - (read from STDIN, the default)\n");
|
65
|
|
- printf(" -R | Enable RTP input\n");
|
66
|
|
- printf("\n");
|
67
|
|
- printf(" -c ca_system | default: %s valid: IRDETO, CONAX, CRYPTOWORKS\n", ts_get_CA_sys_txt(ts->req_CA_sys));
|
68
|
|
- printf(" -z | Detect discontinuty errors in input stream (default: %s).\n", ts->ts_discont ? "report" : "ignore");
|
69
|
|
- printf("\n");
|
70
|
|
- printf(" Output options:\n");
|
71
|
|
- printf(" -O output | Where to send output. Supports files and multicast\n");
|
72
|
|
- printf(" | -O 239.0.0.1:5000 (multicast send)\n");
|
73
|
|
- printf(" | -O file.ts (write to file)\n");
|
74
|
|
- printf(" | -O - (write to STDOUT, the default)\n");
|
75
|
|
- printf("\n");
|
76
|
|
- printf(" -o output_intf | default: %s\n", inet_ntoa(ts->output.intf));
|
77
|
|
- printf(" -t output_ttl | default: %d\n", ts->output.ttl);
|
78
|
|
- printf("\n");
|
79
|
|
- printf(" CAMD35 server options:\n");
|
80
|
|
- printf(" -s server_addr | default: disabled (format 1.2.3.4:2233)\n");
|
81
|
|
- printf(" -U server_user | default: %s\n", ts->camd35.user);
|
82
|
|
- printf(" -P server_pass | default: %s\n", ts->camd35.pass);
|
83
|
|
- printf(" -y usec_delay | Sleep X usec between sending ECM/EMM packets to OSCAM. Default: %d\n", ts->packet_delay);
|
84
|
|
- printf("\n");
|
85
|
|
- printf(" ECM options:\n");
|
86
|
|
- printf(" -G ecm_type | IRDETO: Process only ECMs with selected type (0,1,2,3). Default: %d\n", ts->irdeto_ecm);
|
87
|
|
- printf("\n");
|
88
|
|
- printf(" EMM options:\n");
|
89
|
|
- printf(" -E | Process only EMMs without decoding input stream. Default: %s\n", ts->emm_only ? "true" : "false");
|
90
|
|
- printf(" -f <seconds> | Report how much EMMs has been send for processing each X seconds.\n");
|
91
|
|
- printf(" | each <seconds> seconds. Set to 0 to disable reporting. Default: %d\n", ts->camd35.emm_count_report_interval);
|
92
|
|
- printf("\n");
|
93
|
|
- printf(" Filtering options:\n");
|
94
|
|
- printf(" -e | EMM send (default: %s).\n", ts->emm_send ? "enabled" : "disabled");
|
95
|
|
- printf(" | - Send EMMs to CAMD server for processing.\n");
|
96
|
|
- printf("\n");
|
97
|
|
- printf(" -p | Output PID filter (default: %s).\n", ts->pid_filter ? "enabled" : "disabled");
|
98
|
|
- printf(" | - When PID filter is enabled only PAT/PMT/SDT/data\n");
|
99
|
|
- printf(" | - packets are left in the output.\n");
|
100
|
|
- printf("\n");
|
101
|
|
- printf(" -D debug_level | Message debug level.\n");
|
102
|
|
- printf(" | 0 - default messages\n");
|
103
|
|
- printf(" | 1 - show PSI tables\n");
|
104
|
|
- printf(" | 2 - show EMMs\n");
|
105
|
|
- printf(" | 3 - show duplicate ECMs\n");
|
106
|
|
- printf(" | 4 - packet debug\n");
|
|
88
|
+ printf("Daemon options:\n");
|
|
89
|
+ printf(" -i --ident <server> | Format PROVIDER/CHANNEL. Default: empty\n");
|
|
90
|
+ printf(" -d --daemon <pidfile> | Daemonize program with pid file. Default: do not daemonize\n");
|
|
91
|
+ printf(" -l --syslog-host <host> | Syslog server address. Default: disabled\n");
|
|
92
|
+ printf(" -L --syslog-port <port> | Syslog server port. Default: %d\n", ts->syslog_port);
|
|
93
|
+ printf("\n");
|
|
94
|
+ printf("Input options:\n");
|
|
95
|
+ printf(" -I --input <source> | Where to read from. Supports files and multicast. Default: stdin\n");
|
|
96
|
+ printf(" | -I 224.0.0.1:5000 (multicast receive)\n");
|
|
97
|
+ printf(" | -I file.ts (read from file)\n");
|
|
98
|
+ printf(" | -I - (read from STDIN)\n");
|
|
99
|
+ printf(" -R --input-rtp | Enable RTP input\n");
|
|
100
|
+ printf(" -z --input-ignore-disc | Report discontinuty errors in input stream. Default: %s\n", ts->ts_discont ? "enabled" : "disabled");
|
|
101
|
+ printf("\n");
|
|
102
|
+ printf("Output options:\n");
|
|
103
|
+ printf(" -O --output <dest> | Where to send output. Supports files and multicast. Default: stdout\n");
|
|
104
|
+ printf(" | -O 239.0.0.1:5000 (multicast send)\n");
|
|
105
|
+ printf(" | -O file.ts (write to file)\n");
|
|
106
|
+ printf(" | -O - (write to STDOUT)\n");
|
|
107
|
+ printf(" -o --output-intf <addr> | Set multicast output interface. Default: %s\n", inet_ntoa(ts->output.intf));
|
|
108
|
+ printf(" -t --output-ttl <ttl> | Set multicast ttl. Default: %d\n", ts->output.ttl);
|
|
109
|
+ printf(" -p --output-filter | Output filter. Default: %s\n", ts->pid_filter ? "enabled" : "disabled");
|
|
110
|
+ printf(" | - When output filter is enabled only PAT/PMT/SDT and data\n");
|
|
111
|
+ printf(" | - packets are left in the output. Everything else (NIT, EIT,\n");
|
|
112
|
+ printf(" | - TDT, etc.) is removed.\n");
|
|
113
|
+ printf("\n");
|
|
114
|
+ printf("CAMD server options:\n");
|
|
115
|
+ printf(" -c --ca-system <ca_sys> | Process input EMM/ECM from <ca_sys>. Default: %s\n", ts_get_CA_sys_txt(ts->req_CA_sys));
|
|
116
|
+ printf(" | Valid idents are: CONAX, CRYPTOWORKS and IRDETO\n");
|
|
117
|
+ printf(" -s --camd-server <addr> | CAMD server address and port. Example: 1.2.3.4:2233. Default: not set\n");
|
|
118
|
+ printf(" -U --camd-user <user> | CAMD server user. Default: %s\n", ts->camd35.user);
|
|
119
|
+ printf(" -P --camd-pass <pass> | CAMD server password. Default: %s\n", ts->camd35.pass);
|
|
120
|
+ printf(" -y --camd-pkt-delay <us> | Sleep <us> usec between sending ECM/EMM packets to CAMD. Default: %d\n", ts->packet_delay);
|
|
121
|
+ printf("\n");
|
|
122
|
+ printf("EMM options:\n");
|
|
123
|
+ printf(" -e --emm | Enable sending EMM's to CAMD for processing. Default: %s\n", ts->emm_send ? "enabled" : "disabled");
|
|
124
|
+ printf(" -E --emm-only | Send only EMMs to CAMD, without decoding input stream. Default: %s\n", ts->emm_only ? "enabled" : "disabled");
|
|
125
|
+ printf(" -f --emm-report-time <sec> | Report how much EMMs has been send for processing each <sec> seconds.\n");
|
|
126
|
+ printf(" | Set <sec> to 0 to disable reporting. Default: %d\n", ts->camd35.emm_count_report_interval);
|
|
127
|
+ printf("\n");
|
|
128
|
+ printf("ECM options:\n");
|
|
129
|
+ printf(" -G --ecm-irdeto-type <int> | Process only IRDETO ECMs with selected type (0,1,2,3). Default: %d\n", ts->irdeto_ecm);
|
|
130
|
+ printf("\n");
|
|
131
|
+ printf("Misc options:\n");
|
|
132
|
+ printf(" -D --debug <level> | Message debug level. Higher levels includes the levels bellow.\n");
|
|
133
|
+ printf(" | 0 = default messages, 1 = show PSI tables, 2 = show EMMs\n");
|
|
134
|
+ printf(" | 3 = show duplicate ECMs, 4 = packet debug\n");
|
|
135
|
+ printf(" -h --help | Show help screen.\n");
|
107
|
136
|
printf("\n");
|
108
|
137
|
}
|
109
|
138
|
|
|
@@ -132,7 +161,7 @@ static int parse_io_param(struct io *io, char *opt, int open_flags, mode_t open_
|
132
|
161
|
|
133
|
162
|
static void parse_options(struct ts *ts, int argc, char **argv) {
|
134
|
163
|
int j, i, ca_err = 0, server_err = 1, input_addr_err = 0, output_addr_err = 0, output_intf_err = 0, ident_err = 0;
|
135
|
|
- while ((j = getopt(argc, argv, "i:d:l:L:c:s:I:O:o:t:U:P:y:f:eEzpD:hRG:")) != -1) {
|
|
164
|
+ while ( (j = getopt_long(argc, argv, "i:d:l:L:I:RzO:o:t:pc:s:U:P:y:eEf:G:D:h", long_options, NULL)) != -1 ) {
|
136
|
165
|
char *p = NULL;
|
137
|
166
|
switch (j) {
|
138
|
167
|
case 'i':
|
|
@@ -153,6 +182,33 @@ static void parse_options(struct ts *ts, int argc, char **argv) {
|
153
|
182
|
ts->syslog_port = atoi(optarg);
|
154
|
183
|
break;
|
155
|
184
|
|
|
185
|
+
|
|
186
|
+ case 'I':
|
|
187
|
+ input_addr_err = parse_io_param(&ts->input, optarg, O_RDONLY, 0);
|
|
188
|
+ break;
|
|
189
|
+ case 'R':
|
|
190
|
+ ts->rtp_input = !ts->rtp_input;
|
|
191
|
+ break;
|
|
192
|
+ case 'z':
|
|
193
|
+ ts->ts_discont = !ts->ts_discont;
|
|
194
|
+ break;
|
|
195
|
+
|
|
196
|
+ case 'O':
|
|
197
|
+ output_addr_err = parse_io_param(&ts->output, optarg,
|
|
198
|
+ O_CREAT | O_WRONLY | O_TRUNC,
|
|
199
|
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
|
200
|
+ break;
|
|
201
|
+ case 'o':
|
|
202
|
+ if (inet_aton(optarg, &ts->output.intf) == 0)
|
|
203
|
+ output_intf_err = 1;
|
|
204
|
+ break;
|
|
205
|
+ case 't':
|
|
206
|
+ ts->output.ttl = atoi(optarg);
|
|
207
|
+ break;
|
|
208
|
+ case 'p':
|
|
209
|
+ ts->pid_filter = !ts->pid_filter;
|
|
210
|
+ break;
|
|
211
|
+
|
156
|
212
|
case 'c':
|
157
|
213
|
if (strcasecmp("IRDETO", optarg) == 0)
|
158
|
214
|
ts->req_CA_sys = CA_IRDETO;
|
|
@@ -163,7 +219,6 @@ static void parse_options(struct ts *ts, int argc, char **argv) {
|
163
|
219
|
else
|
164
|
220
|
ca_err = 1;
|
165
|
221
|
break;
|
166
|
|
-
|
167
|
222
|
case 's':
|
168
|
223
|
p = strrchr(optarg, ':');
|
169
|
224
|
if (p) {
|
|
@@ -175,31 +230,6 @@ static void parse_options(struct ts *ts, int argc, char **argv) {
|
175
|
230
|
else
|
176
|
231
|
server_err = 0;
|
177
|
232
|
break;
|
178
|
|
-
|
179
|
|
- case 'I':
|
180
|
|
- input_addr_err = parse_io_param(&ts->input, optarg, O_RDONLY, 0);
|
181
|
|
- break;
|
182
|
|
- case 'R':
|
183
|
|
- ts->rtp_input = !ts->rtp_input;
|
184
|
|
- break;
|
185
|
|
- case 'O':
|
186
|
|
- output_addr_err = parse_io_param(&ts->output, optarg,
|
187
|
|
- O_CREAT | O_WRONLY | O_TRUNC,
|
188
|
|
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
189
|
|
- break;
|
190
|
|
-
|
191
|
|
- case 'o':
|
192
|
|
- if (inet_aton(optarg, &ts->output.intf) == 0)
|
193
|
|
- output_intf_err = 1;
|
194
|
|
- break;
|
195
|
|
- case 't':
|
196
|
|
- ts->output.ttl = atoi(optarg);
|
197
|
|
- break;
|
198
|
|
-
|
199
|
|
- case 'G':
|
200
|
|
- ts->irdeto_ecm = atoi(optarg);
|
201
|
|
- break;
|
202
|
|
-
|
203
|
233
|
case 'U':
|
204
|
234
|
strncpy(ts->camd35.user, optarg, sizeof(ts->camd35.user) - 1);
|
205
|
235
|
ts->camd35.user[sizeof(ts->camd35.user) - 1] = 0;
|
|
@@ -214,8 +244,12 @@ static void parse_options(struct ts *ts, int argc, char **argv) {
|
214
|
244
|
ts->packet_delay = 0;
|
215
|
245
|
break;
|
216
|
246
|
|
217
|
|
- case 'z':
|
218
|
|
- ts->ts_discont = !ts->ts_discont;
|
|
247
|
+ case 'e':
|
|
248
|
+ ts->emm_send = !ts->emm_send;
|
|
249
|
+ break;
|
|
250
|
+ case 'E':
|
|
251
|
+ ts->emm_only = 1;
|
|
252
|
+ ts->emm_send = 1;
|
219
|
253
|
break;
|
220
|
254
|
case 'f':
|
221
|
255
|
ts->camd35.emm_count_report_interval = atoi(optarg);
|
|
@@ -224,15 +258,9 @@ static void parse_options(struct ts *ts, int argc, char **argv) {
|
224
|
258
|
if (ts->camd35.emm_count_report_interval > 86400)
|
225
|
259
|
ts->camd35.emm_count_report_interval = 86400;
|
226
|
260
|
break;
|
227
|
|
- case 'e':
|
228
|
|
- ts->emm_send = !ts->emm_send;
|
229
|
|
- break;
|
230
|
|
- case 'E':
|
231
|
|
- ts->emm_only = 1;
|
232
|
|
- ts->emm_send = 1;
|
233
|
|
- break;
|
234
|
|
- case 'p':
|
235
|
|
- ts->pid_filter = !ts->pid_filter;
|
|
261
|
+
|
|
262
|
+ case 'G':
|
|
263
|
+ ts->irdeto_ecm = atoi(optarg);
|
236
|
264
|
break;
|
237
|
265
|
|
238
|
266
|
case 'D':
|
|
@@ -253,7 +281,7 @@ static void parse_options(struct ts *ts, int argc, char **argv) {
|
253
|
281
|
if (ca_err)
|
254
|
282
|
fprintf(stderr, "ERROR: Requested CA system is unsupported.\n");
|
255
|
283
|
if (server_err)
|
256
|
|
- fprintf(stderr, "ERROR: Server IP address is not set or it is invalid.\n");
|
|
284
|
+ fprintf(stderr, "ERROR: CAMD server IP address is not set or it is invalid.\n");
|
257
|
285
|
if (input_addr_err)
|
258
|
286
|
fprintf(stderr, "ERROR: Input IP address is invalid.\n");
|
259
|
287
|
if (output_addr_err)
|
|
@@ -294,6 +322,7 @@ static void parse_options(struct ts *ts, int argc, char **argv) {
|
294
|
322
|
} else if (ts->output.type == FILE_IO) {
|
295
|
323
|
ts_LOGf("Output file: %s\n", ts->output.fd == 1 ? "STDOUT" : ts->output.fname);
|
296
|
324
|
}
|
|
325
|
+ ts_LOGf("PID filter : %s\n", ts->pid_filter ? "enabled" : "disabled");
|
297
|
326
|
}
|
298
|
327
|
ts_LOGf("Server addr: tcp://%s:%u/\n", inet_ntoa(ts->camd35.server_addr), ts->camd35.server_port);
|
299
|
328
|
ts_LOGf("Server user: %s\n", ts->camd35.user);
|
|
@@ -310,7 +339,6 @@ static void parse_options(struct ts *ts, int argc, char **argv) {
|
310
|
339
|
ts_LOGf("EMM only : %s\n", ts->emm_only ? "yes" : "no");
|
311
|
340
|
} else {
|
312
|
341
|
ts_LOGf("EMM send : %s\n", ts->emm_send ? "enabled" : "disabled");
|
313
|
|
- ts_LOGf("PID filter : %s\n", ts->pid_filter ? "enabled" : "disabled");
|
314
|
342
|
ts_LOGf("Decoding : %s\n", ts->threaded ? "threaded" : "single thread");
|
315
|
343
|
}
|
316
|
344
|
|