source: trunk/oscam-config-reader.c@ 11518

Last change on this file since 11518 was 11518, checked in by Gorgone Impertinence, 4 years ago

DVBAPI:
Fixed bug in dvbapi not releasing used descramblers in stapi, coolapi and gxapi boxes
Increased MAX_STREAM_INDICES back to 32 (it must be equal to MAX_STREAM_PIDS)
Modified the get_emm_filter_adv() function to accept more arguments

OTHER:
Cosmetics to module-cccam.c and module-cccam-cacheex.x
Removed some emu specific code not needed anymore

File size: 41.9 KB
Line 
1#define MODULE_LOG_PREFIX "config"
2
3#include "globals.h"
4#include "module-stat.h"
5#include "oscam-aes.h"
6#include "oscam-array.h"
7#include "oscam-conf.h"
8#include "oscam-conf-chk.h"
9#include "oscam-conf-mk.h"
10#include "oscam-config.h"
11#include "oscam-garbage.h"
12#include "oscam-lock.h"
13#include "oscam-reader.h"
14#include "oscam-string.h"
15#ifdef MODULE_GBOX
16#include "module-gbox.h"
17#endif
18
19#define cs_srvr "oscam.server"
20
21extern const struct s_cardreader *cardreaders[];
22extern char *RDR_CD_TXT[];
23
24static void reader_label_fn(const char *token, char *value, void *setting, FILE *f)
25{
26 struct s_reader *rdr = setting;
27 if(value)
28 {
29 int i, found = 0;
30 if(!strlen(value))
31 { return; }
32 for(i = 0; i < (int)strlen(value); i++)
33 {
34 if(value[i] == ' ')
35 {
36 value[i] = '_';
37 found++;
38 }
39 }
40 if(found)
41 { fprintf(stderr, "Configuration reader: corrected label to %s\n", value); }
42 cs_strncpy(rdr->label, value, sizeof(rdr->label));
43 return;
44 }
45 fprintf_conf(f, token, "%s\n", rdr->label);
46}
47
48static void ecmwhitelist_fn(const char *token, char *value, void *setting, FILE *f)
49{
50 struct s_reader *rdr = setting;
51 if(value)
52 {
53 if(strlen(value))
54 chk_ecm_whitelist(value, &rdr->ecm_whitelist);
55 else
56 ecm_whitelist_clear(&rdr->ecm_whitelist);
57 return;
58 }
59
60 value = mk_t_ecm_whitelist(&rdr->ecm_whitelist);
61 if(strlen(value) > 0 || cfg.http_full_cfg)
62 { fprintf_conf(f, token, "%s\n", value); }
63 free_mk_t(value);
64}
65
66static void ecmheaderwhitelist_fn(const char *token, char *value, void *setting, FILE *f)
67{
68 struct s_reader *rdr = setting;
69 if(value)
70 {
71 if(strlen(value))
72 chk_ecm_hdr_whitelist(value, &rdr->ecm_hdr_whitelist);
73 else
74 ecm_hdr_whitelist_clear(&rdr->ecm_hdr_whitelist);
75 return;
76 }
77
78 value = mk_t_ecm_hdr_whitelist(&rdr->ecm_hdr_whitelist);
79 if(strlen(value) > 0 || cfg.http_full_cfg)
80 { fprintf_conf(f, token, "%s\n", value); }
81 free_mk_t(value);
82}
83
84static void protocol_fn(const char *token, char *value, void *setting, FILE *f)
85{
86 struct s_reader *rdr = setting;
87 if(value)
88 {
89 if(strlen(value) == 0)
90 { return; }
91 struct protocol_map
92 {
93 char *name;
94 int typ;
95 } protocols[] =
96 {
97 { "serial", R_SERIAL },
98 { "camd35", R_CAMD35 },
99 { "cs378x", R_CS378X },
100 { "cs357x", R_CAMD35 },
101 { "camd33", R_CAMD33 },
102 { "gbox", R_GBOX },
103 { "cccam", R_CCCAM },
104 { "cccam_ext", R_CCCAM },
105 { "cccam_mcs", R_CCCAM },
106 { "constcw", R_CONSTCW },
107 { "radegast", R_RADEGAST },
108 { "scam", R_SCAM },
109 { "ghttp", R_GHTTP },
110 { "newcamd", R_NEWCAMD },
111 { "newcamd525", R_NEWCAMD },
112 { "newcamd524", R_NEWCAMD },
113 { "drecas", R_DRECAS },
114 { "emu", R_EMU },
115 { NULL, 0 }
116 }, *p;
117 int i;
118 // Parse card readers
119 for(i = 0; cardreaders[i]; i++)
120 {
121 if(streq(value, cardreaders[i]->desc))
122 {
123 rdr->crdr = cardreaders[i];
124 rdr->typ = cardreaders[i]->typ;
125 return;
126 }
127 }
128 // Parse protocols
129 for(i = 0, p = &protocols[0]; p->name; p = &protocols[++i])
130 {
131 if(streq(p->name, value))
132 {
133 rdr->typ = p->typ;
134 break;
135 }
136 }
137 if(rdr->typ == R_NEWCAMD)
138 { rdr->ncd_proto = streq(value, "newcamd524") ? NCD_524 : NCD_525; }
139 if(!rdr->typ)
140 {
141 fprintf(stderr, "ERROR: '%s' is unsupported reader protocol!\n", value);
142 rdr->enable = 0;
143 }
144 return;
145 }
146 fprintf_conf(f, token, "%s\n", reader_get_type_desc(rdr, 0));
147}
148
149static void device_fn(const char *token, char *value, void *setting, FILE *f)
150{
151 struct s_reader *rdr = setting;
152 int32_t isphysical = !is_network_reader(rdr);
153 if(value)
154 {
155 int32_t i;
156 char *ptr, *saveptr1 = NULL;
157 for(i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 3) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++)
158 {
159 trim(ptr);
160 switch(i)
161 {
162 case 0:
163 cs_strncpy(rdr->device, ptr, sizeof(rdr->device));
164 break;
165 case 1:
166 rdr->r_port = atoi(ptr);
167 break;
168 case 2:
169 rdr->l_port = atoi(ptr);
170 break;
171 }
172 }
173 return;
174 }
175 fprintf_conf(f, token, "%s", rdr->device); // it should not have \n at the end
176 if((rdr->r_port || cfg.http_full_cfg) && !isphysical)
177 { fprintf(f, ",%d", rdr->r_port); }
178 if((rdr->l_port || cfg.http_full_cfg) && !isphysical && strncmp(reader_get_type_desc(rdr, 0), "cccam", 5))
179 { fprintf(f, ",%d", rdr->l_port); }
180 fprintf(f, "\n");
181}
182
183static void reader_services_fn(const char *token, char *value, void *setting, FILE *f)
184{
185 services_fn(token, value, setting, f);
186 if(value)
187 {
188 struct s_reader *rdr = container_of(setting, struct s_reader, sidtabs);
189 if(rdr)
190 { rdr->changes_since_shareupdate = 1; }
191 }
192}
193
194static void reader_lb_services_fn(const char *token, char *value, void *setting, FILE *f)
195{
196 services_fn(token, value, setting, f);
197 if(value)
198 {
199 struct s_reader *rdr = container_of(setting, struct s_reader, lb_sidtabs);
200 if(rdr)
201 { rdr->changes_since_shareupdate = 1; }
202 }
203}
204
205static void reader_caid_fn(const char *token, char *value, void *setting, FILE *f)
206{
207 check_caidtab_fn(token, value, setting, f);
208 if(value)
209 {
210 struct s_reader *rdr = container_of(setting, struct s_reader, ctab);
211 if(rdr)
212 { rdr->changes_since_shareupdate = 1; }
213 }
214}
215
216static void boxid_fn(const char *token, char *value, void *setting, FILE *f)
217{
218 struct s_reader *rdr = setting;
219 if(value)
220 {
221 rdr->boxid = strlen(value) ? a2i(value, 4) : 0;
222 return;
223 }
224 if(rdr->boxid)
225 { fprintf_conf(f, token, "%08X\n", rdr->boxid); }
226 else if(cfg.http_full_cfg)
227 { fprintf_conf(f, token, "\n"); }
228}
229
230static void rsakey_fn(const char *token, char *value, void *setting, FILE *f)
231{
232 struct s_reader *rdr = setting;
233 if(value)
234 {
235 int32_t len = strlen(value);
236 if(len != 128 && len != 240)
237 {
238 rdr->rsa_mod_length = 0;
239 memset(rdr->rsa_mod, 0, 120);
240 }
241 else
242 {
243 if(key_atob_l(value, rdr->rsa_mod, len))
244 {
245 fprintf(stderr, "reader rsakey parse error, %s=%s\n", token, value);
246 rdr->rsa_mod_length = 0;
247 memset(rdr->rsa_mod, 0, sizeof(rdr->rsa_mod));
248 }
249 else
250 {
251 rdr->rsa_mod_length = len/2;
252 }
253 }
254 return;
255 }
256 int32_t len = rdr->rsa_mod_length;
257 if(len > 0)
258 {
259 char tmp[len * 2 + 1];
260 fprintf_conf(f, "rsakey", "%s\n", cs_hexdump(0, rdr->rsa_mod, len, tmp, sizeof(tmp)));
261 }
262 else if(cfg.http_full_cfg)
263 { fprintf_conf(f, "rsakey", "\n"); }
264}
265
266static void deskey_fn(const char *token, char *value, void *setting, FILE *f)
267{
268 struct s_reader *rdr = setting;
269 if(value)
270 {
271 int32_t len = strlen(value);
272 if(((len % 16) != 0) || len == 0 || len > 128*2)
273 {
274 rdr->des_key_length = 0;
275 memset(rdr->des_key, 0, sizeof(rdr->des_key));
276 }
277 else
278 {
279 if(key_atob_l(value, rdr->des_key, len))
280 {
281 fprintf(stderr, "reader 3DES key parse error, %s=%s\n", token, value);
282 rdr->des_key_length = 0;
283 memset(rdr->des_key, 0, sizeof(rdr->des_key));
284 }
285 else
286 {
287 rdr->des_key_length = len/2;
288 }
289 }
290 return;
291 }
292 int32_t len = rdr->des_key_length;
293 if(len > 0)
294 {
295 char tmp[len * 2 + 1];
296 fprintf_conf(f, "deskey", "%s\n", cs_hexdump(0, rdr->des_key, len, tmp, sizeof(tmp)));
297 }
298 else if(cfg.http_full_cfg)
299 { fprintf_conf(f, "deskey", "\n"); }
300}
301
302static void boxkey_fn(const char *token, char *value, void *setting, FILE *f)
303{
304 struct s_reader *rdr = setting;
305 if(value)
306 {
307 int32_t len = strlen(value);
308 if(((len % 8) != 0) || len == 0 || len > 32)
309 {
310 rdr->boxkey_length = 0;
311 memset(rdr->boxkey, 0, sizeof(rdr->boxkey));
312 }
313 else
314 {
315 if(key_atob_l(value, rdr->boxkey, len))
316 {
317 fprintf(stderr, "reader boxkey parse error, %s=%s\n", token, value);
318 rdr->boxkey_length = 0;
319 memset(rdr->boxkey, 0, sizeof(rdr->boxkey));
320 }
321 else
322 {
323 rdr->boxkey_length = len/2;
324 }
325 }
326 return;
327 }
328 int32_t len = rdr->boxkey_length;
329 if(len > 0)
330 {
331 char tmp[len * 2 + 1];
332 fprintf_conf(f, "boxkey", "%s\n", cs_hexdump(0, rdr->boxkey, len, tmp, sizeof(tmp)));
333 }
334 else if(cfg.http_full_cfg)
335 { fprintf_conf(f, "boxkey", "\n"); }
336}
337
338#ifdef READER_NAGRA_MERLIN
339static void mod1_fn(const char *token, char *value, void *setting, FILE *f)
340{
341 struct s_reader *rdr = setting;
342 if(value)
343 {
344 int32_t len = strlen(value);
345 if(len != 224)
346 {
347 rdr->mod1_length = 0;
348 memset(rdr->mod1, 0, 112);
349 }
350 else
351 {
352 if(key_atob_l(value, rdr->mod1, len))
353 {
354 fprintf(stderr, "reader mod1 parse error, %s=%s\n", token, value);
355 rdr->mod1_length = 0;
356 memset(rdr->mod1, 0, sizeof(rdr->mod1));
357 }
358 else
359 {
360 rdr->mod1_length = len/2;
361 }
362 }
363 return;
364 }
365 int32_t len = rdr->mod1_length;
366 if(len > 0)
367 {
368 char tmp[len * 2 + 1];
369 fprintf_conf(f, "mod1", "%s\n", cs_hexdump(0, rdr->mod1, len, tmp, sizeof(tmp)));
370 }
371 else if(cfg.http_full_cfg)
372 { fprintf_conf(f, "mod1", "\n"); }
373}
374
375static void data50_fn(const char *token, char *value, void *setting, FILE *f)
376{
377 struct s_reader *rdr = setting;
378 if(value)
379 {
380 int32_t len = strlen(value);
381 if(len != 160)
382 {
383 rdr->data50_length = 0;
384 memset(rdr->data50, 0, 80);
385 }
386 else
387 {
388 if(key_atob_l(value, rdr->data50, len))
389 {
390 fprintf(stderr, "reader data50 parse error, %s=%s\n", token, value);
391 rdr->data50_length = 0;
392 memset(rdr->data50, 0, sizeof(rdr->data50));
393 }
394 else
395 {
396 rdr->data50_length = len/2;
397 }
398 }
399 return;
400 }
401 int32_t len = rdr->data50_length;
402 if(len > 0)
403 {
404 char tmp[len * 2 + 1];
405 fprintf_conf(f, "data50", "%s\n", cs_hexdump(0, rdr->data50, len, tmp, sizeof(tmp)));
406 }
407 else if(cfg.http_full_cfg)
408 { fprintf_conf(f, "data50", "\n"); }
409}
410
411static void mod50_fn(const char *token, char *value, void *setting, FILE *f)
412{
413 struct s_reader *rdr = setting;
414 if(value)
415 {
416 int32_t len = strlen(value);
417 if(len != 160)
418 {
419 rdr->mod50_length = 0;
420 memset(rdr->mod50, 0, 80);
421 }
422 else
423 {
424 if(key_atob_l(value, rdr->mod50, len))
425 {
426 fprintf(stderr, "reader mod50 parse error, %s=%s\n", token, value);
427 rdr->mod50_length = 0;
428 memset(rdr->mod50, 0, sizeof(rdr->mod50));
429 }
430 else
431 {
432 rdr->mod50_length = len/2;
433 }
434 }
435 return;
436 }
437 int32_t len = rdr->mod50_length;
438 if(len > 0)
439 {
440 char tmp[len * 2 + 1];
441 fprintf_conf(f, "mod50", "%s\n", cs_hexdump(0, rdr->mod50, len, tmp, sizeof(tmp)));
442 }
443 else if(cfg.http_full_cfg)
444 { fprintf_conf(f, "mod50", "\n"); }
445}
446
447static void key60_fn(const char *token, char *value, void *setting, FILE *f)
448{
449 struct s_reader *rdr = setting;
450 if(value)
451 {
452 int32_t len = strlen(value);
453 if(len != 192)
454 {
455 rdr->key60_length = 0;
456 memset(rdr->key60, 0, 96);
457 }
458 else
459 {
460 if(key_atob_l(value, rdr->key60, len))
461 {
462 fprintf(stderr, "reader key60 parse error, %s=%s\n", token, value);
463 rdr->key60_length = 0;
464 memset(rdr->key60, 0, sizeof(rdr->key60));
465 }
466 else
467 {
468 rdr->key60_length = len/2;
469 }
470 }
471 return;
472 }
473 int32_t len = rdr->key60_length;
474 if(len > 0)
475 {
476 char tmp[len * 2 + 1];
477 fprintf_conf(f, "key60", "%s\n", cs_hexdump(0, rdr->key60, len, tmp, sizeof(tmp)));
478 }
479 else if(cfg.http_full_cfg)
480 { fprintf_conf(f, "key60", "\n"); }
481}
482
483static void exp60_fn(const char *token, char *value, void *setting, FILE *f)
484{
485 struct s_reader *rdr = setting;
486 if(value)
487 {
488 int32_t len = strlen(value);
489 if(len != 192)
490 {
491 rdr->exp60_length = 0;
492 memset(rdr->exp60, 0, 96);
493 }
494 else
495 {
496 if(key_atob_l(value, rdr->exp60, len))
497 {
498 fprintf(stderr, "reader exp60 parse error, %s=%s\n", token, value);
499 rdr->exp60_length = 0;
500 memset(rdr->exp60, 0, sizeof(rdr->exp60));
501 }
502 else
503 {
504 rdr->exp60_length = len/2;
505 }
506 }
507 return;
508 }
509 int32_t len = rdr->exp60_length;
510 if(len > 0)
511 {
512 char tmp[len * 2 + 1];
513 fprintf_conf(f, "exp60", "%s\n", cs_hexdump(0, rdr->exp60, len, tmp, sizeof(tmp)));
514 }
515 else if(cfg.http_full_cfg)
516 { fprintf_conf(f, "exp60", "\n"); }
517}
518
519static void nuid_fn(const char *token, char *value, void *setting, FILE *f)
520{
521 struct s_reader *rdr = setting;
522 if(value)
523 {
524 int32_t len = strlen(value);
525 if(len != 8)
526 {
527 rdr->nuid_length = 0;
528 memset(rdr->nuid, 0, 4);
529 }
530 else
531 {
532 if(key_atob_l(value, rdr->nuid, len))
533 {
534 fprintf(stderr, "reader nuid parse error, %s=%s\n", token, value);
535 rdr->nuid_length = 0;
536 memset(rdr->nuid, 0, sizeof(rdr->nuid));
537 }
538 else
539 {
540 rdr->nuid_length = len/2;
541 }
542 }
543 return;
544 }
545 int32_t len = rdr->nuid_length;
546 if(len > 0)
547 {
548 char tmp[len * 2 + 1];
549 fprintf_conf(f, "nuid", "%s\n", cs_hexdump(0, rdr->nuid, len, tmp, sizeof(tmp)));
550 }
551 else if(cfg.http_full_cfg)
552 { fprintf_conf(f, "nuid", "\n"); }
553}
554
555static void cwekey_fn(const char *token, char *value, void *setting, FILE *f)
556{
557 struct s_reader *rdr = setting;
558 if(value)
559 {
560 int32_t len = strlen(value);
561 if(len != 32)
562 {
563 rdr->cwekey_length = 0;
564 memset(rdr->cwekey, 0, 16);
565 }
566 else
567 {
568 if(key_atob_l(value, rdr->cwekey, len))
569 {
570 fprintf(stderr, "reader cwekey parse error, %s=%s\n", token, value);
571 rdr->cwekey_length = 0;
572 memset(rdr->cwekey, 0, sizeof(rdr->cwekey));
573 }
574 else
575 {
576 rdr->cwekey_length = len/2;
577 }
578 }
579 return;
580 }
581 int32_t len = rdr->cwekey_length;
582 if(len > 0)
583 {
584 char tmp[len * 2 + 1];
585 fprintf_conf(f, "cwekey", "%s\n", cs_hexdump(0, rdr->cwekey, len, tmp, sizeof(tmp)));
586 }
587 else if(cfg.http_full_cfg)
588 { fprintf_conf(f, "cwekey", "\n"); }
589}
590#endif
591
592static void flags_fn(const char *token, char *value, void *setting, long flag, FILE *f)
593{
594 uint32_t *var = setting;
595 if(value)
596 {
597 int i = atoi(value);
598 if(!i && (*var & flag))
599 { *var -= flag; }
600 if(i)
601 { *var |= flag; }
602 return;
603 }
604 if((*var & flag) || cfg.http_full_cfg)
605 { fprintf_conf(f, token, "%d\n", (*var & flag) ? 1 : 0); }
606}
607
608static void ins7E_fn(const char *token, char *value, void *setting, long var_size, FILE *f)
609{
610 uint8_t *var = setting;
611 var_size -= 1; // var_size contains sizeof(var) which is [X + 1]
612 if(value)
613 {
614 int32_t len = strlen(value);
615 if(len != var_size * 2 || key_atob_l(value, var, len))
616 {
617 if(len > 0)
618 { fprintf(stderr, "reader %s parse error, %s=%s\n", token, token, value); }
619 memset(var, 0, var_size + 1);
620 }
621 else
622 {
623 var[var_size] = 1; // found and correct
624 }
625 return;
626 }
627 if(var[var_size])
628 {
629 char tmp[var_size * 2 + 1];
630 fprintf_conf(f, token, "%s\n", cs_hexdump(0, var, var_size, tmp, sizeof(tmp)));
631 }
632 else if(cfg.http_full_cfg)
633 { fprintf_conf(f, token, "\n"); }
634}
635
636static void atr_fn(const char *token, char *value, void *setting, FILE *f)
637{
638 struct s_reader *rdr = setting;
639 if(value)
640 {
641 memset(rdr->atr, 0, sizeof(rdr->atr));
642 rdr->atrlen = strlen(value);
643 if(rdr->atrlen)
644 {
645 if(rdr->atrlen > (int32_t)sizeof(rdr->atr) * 2)
646 { rdr->atrlen = (int32_t)sizeof(rdr->atr) * 2; }
647 key_atob_l(value, rdr->atr, rdr->atrlen);
648 }
649 return;
650 }
651 if(rdr->atr[0] || cfg.http_full_cfg)
652 {
653 int j;
654 fprintf_conf(f, token, "%s", ""); // it should not have \n at the end
655 if(rdr->atr[0])
656 {
657 for(j = 0; j < rdr->atrlen / 2; j++)
658 {
659 fprintf(f, "%02X", rdr->atr[j]);
660 }
661 }
662 fprintf(f, "\n");
663 }
664}
665
666static void detect_fn(const char *token, char *value, void *setting, FILE *f)
667{
668 struct s_reader *rdr = setting;
669 if(value)
670 {
671 int i;
672 for(i = 0; RDR_CD_TXT[i]; i++)
673 {
674 if(!strcmp(value, RDR_CD_TXT[i]))
675 {
676 rdr->detect = i;
677 }
678 else
679 {
680 if(value[0] == '!' && streq(value + 1, RDR_CD_TXT[i]))
681 { rdr->detect = i | 0x80; }
682 }
683 }
684 return;
685 }
686 fprintf_conf(f, token, "%s%s\n", rdr->detect & 0x80 ? "!" : "", RDR_CD_TXT[rdr->detect & 0x7f]);
687}
688
689void ftab_fn(const char *token, char *value, void *setting, long ftab_type, FILE *f)
690{
691 FTAB *ftab = setting;
692 if(value)
693 {
694 if(strlen(value))
695 chk_ftab(value, ftab);
696 else
697 ftab_clear(ftab);
698 return;
699 }
700 if(ftab_type & FTAB_READER)
701 {
702 struct s_reader *rdr = NULL;
703 if(ftab_type & FTAB_PROVID) { rdr = container_of(setting, struct s_reader, ftab); }
704 if(ftab_type & FTAB_CHID) { rdr = container_of(setting, struct s_reader, fchid); }
705 if(ftab_type & FTAB_FBPCAID) { rdr = container_of(setting, struct s_reader, fallback_percaid); }
706 if(ftab_type & FTAB_LOCALCARDS) { rdr = container_of(setting, struct s_reader, localcards); }
707 if(ftab_type & FTAB_IGNCHKSMCAID){ rdr = container_of(setting, struct s_reader, disablecrccws_only_for); }
708#ifdef WITH_EMU
709 if(ftab_type & FTAB_EMUAU) { rdr = container_of(setting, struct s_reader, emu_auproviders); }
710#endif
711 if(rdr)
712 { rdr->changes_since_shareupdate = 1; }
713 }
714 value = mk_t_ftab(ftab);
715 if(strlen(value) > 0 || cfg.http_full_cfg)
716 { fprintf_conf(f, token, "%s\n", value); }
717 free_mk_t(value);
718}
719
720static void aeskeys_fn(const char *token, char *value, void *setting, FILE *f)
721{
722 struct s_reader *rdr = setting;
723 if(value)
724 {
725 parse_aes_keys(rdr, value);
726 return;
727 }
728 value = mk_t_aeskeys(rdr);
729 if(strlen(value) > 0 || cfg.http_full_cfg)
730 { fprintf_conf(f, token, "%s\n", value); }
731 free_mk_t(value);
732}
733
734static void emmcache_fn(const char *token, char *value, void *setting, FILE *f)
735{
736 struct s_reader *rdr = setting;
737 if(value)
738 {
739 rdr->cachemm = 0;
740 rdr->rewritemm = 0;
741 rdr->logemm = 0;
742 rdr->deviceemm = 0;
743 if(strlen(value))
744 {
745 int i;
746 char *ptr, *saveptr1 = NULL;
747 for(i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 4) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++)
748 {
749 switch(i)
750 {
751 case 0:
752 rdr->cachemm = atoi(ptr);
753 break;
754 case 1:
755 rdr->rewritemm = atoi(ptr);
756 break;
757 case 2:
758 rdr->logemm = atoi(ptr);
759 break;
760 case 3:
761 rdr->deviceemm = atoi(ptr);
762 }
763 }
764 if(rdr->rewritemm <= 0)
765 {
766 fprintf(stderr, "Setting reader \"emmcache\" to %i,%d,%i,%i instead of %i,%i,%i,%i.",
767 rdr->cachemm, 1, rdr->logemm, rdr->deviceemm,
768 rdr->cachemm, rdr->rewritemm, rdr->logemm, rdr->deviceemm);
769 fprintf(stderr, "Zero or negative number of rewrites is silly\n");
770 rdr->rewritemm = 1;
771 }
772 }
773 return;
774 }
775 if(rdr->cachemm || rdr->logemm || cfg.http_full_cfg)
776 { fprintf_conf(f, token, "%d,%d,%d,%d\n", rdr->cachemm, rdr->rewritemm, rdr->logemm,rdr->deviceemm); }
777}
778
779static void blockemm_bylen_fn(const char *token, char *value, void *setting, FILE *f)
780{
781 struct s_reader *rdr = setting;
782 if(value)
783 {
784 char *ptr, *saveptr1 = NULL, dash;
785 struct s_emmlen_range *blocklen;
786 uint32_t num;
787
788 if(!strlen(value))
789 {
790 ll_destroy_data(&rdr->blockemmbylen);
791 return;
792 }
793
794 if(!rdr->blockemmbylen)
795 { rdr->blockemmbylen = ll_create("blockemmbylen"); }
796 else
797 { ll_clear_data(rdr->blockemmbylen); }
798
799 for(ptr = strtok_r(value, ",", &saveptr1); ptr;
800 ptr = strtok_r(NULL, ",", &saveptr1))
801 {
802 if(!cs_malloc(&blocklen, sizeof(*blocklen)))
803 { return; }
804 num = sscanf(ptr, "%hd%c%hd", &blocklen->min, &dash, &blocklen->max);
805 if(num <= 0)
806 {
807 NULLFREE(blocklen);
808 fprintf(stderr, "blockemm-bylen parse error: %s\n", value);
809 continue;
810 }
811 if(num == 1) // single values: x1, x2, x3, ...
812 { blocklen->max = blocklen->min; }
813 else if(num == 2) // range values with open end: x1-
814 { blocklen->max = 0; }
815 ll_append(rdr->blockemmbylen, blocklen);
816 }
817 return;
818 }
819 value = mk_t_emmbylen(rdr);
820 if(strlen(value) > 0 || cfg.http_full_cfg)
821 { fprintf_conf(f, token, "%s\n", value); }
822 free_mk_t(value);
823}
824
825static void nano_fn(const char *token, char *value, void *setting, FILE *f)
826{
827 uint16_t *nano = setting;
828 if(value)
829 {
830 *nano = 0;
831 if(strlen(value) > 0)
832 {
833 if(streq(value, "all"))
834 {
835 *nano = 0xFFFF;
836 }
837 else
838 {
839 int32_t i;
840 char *ptr, *saveptr1 = NULL;
841 for(ptr = strtok_r(value, ",", &saveptr1); ptr; ptr = strtok_r(NULL, ",", &saveptr1))
842 {
843 i = (byte_atob(ptr) % 0x80);
844 if(i >= 0 && i <= 16)
845 { *nano |= (1 << i); }
846 }
847 }
848 }
849 return;
850 }
851 value = mk_t_nano(*nano);
852 if(strlen(value) > 0 || cfg.http_full_cfg)
853 { fprintf_conf(f, token, "%s\n", value); }
854 free_mk_t(value);
855}
856
857static void auprovid_fn(const char *token, char *value, void *setting, FILE *f)
858{
859 struct s_reader *rdr = setting;
860 if(value)
861 {
862 rdr->auprovid = 0;
863 if(strlen(value))
864 { rdr->auprovid = a2i(value, 3); }
865 return;
866 }
867 if(rdr->auprovid)
868 { fprintf_conf(f, token, "%06X\n", rdr->auprovid); }
869 else if(cfg.http_full_cfg)
870 { fprintf_conf(f, token, "\n"); }
871}
872
873static void ratelimitecm_fn(const char *token, char *value, void *setting, FILE *f)
874{
875 struct s_reader *rdr = setting;
876 if(value)
877 {
878 rdr->ratelimitecm = 0;
879 if(strlen(value))
880 {
881 int i;
882 rdr->ratelimitecm = atoi(value);
883 for(i = 0; i < MAXECMRATELIMIT; i++) // reset all slots
884 {
885 rdr->rlecmh[i].srvid = -1;
886 rdr->rlecmh[i].last.time = -1;
887 }
888 }
889 return;
890 }
891 if(rdr->ratelimitecm || cfg.http_full_cfg)
892 { fprintf_conf(f, token, "%d\n", rdr->ratelimitecm); }
893}
894
895static void ecmunique_fn(const char *token, char *value, void *setting, FILE *f)
896{
897 struct s_reader *rdr = setting;
898 if(value)
899 {
900 if(strlen(value) == 0)
901 {
902 rdr->ecmunique = 0; // default
903 }
904 else
905 {
906 rdr->ecmunique = atoi(value);
907 if(rdr->ecmunique >= 1)
908 { rdr->ecmunique = 1; }
909 else
910 { rdr->ecmunique = 0; }
911 }
912 return;
913 }
914 if((rdr->ratelimitecm && rdr->ecmunique != 0) || cfg.http_full_cfg)
915 { fprintf_conf(f, token, "%d\n", rdr->ecmunique); }
916}
917
918static void ratelimittime_fn(const char *token, char *value, void *setting, FILE *f)
919{
920 struct s_reader *rdr = setting;
921 if(value)
922 {
923 if(strlen(value) == 0)
924 {
925 if(rdr->ratelimitecm > 0)
926 {
927 rdr->ratelimittime = 9000; // default 9 seconds
928 rdr->srvidholdtime = 2000; // default 2 seconds hold
929 }
930 else
931 {
932 rdr->ratelimitecm = 0; // in case someone set a negative value
933 rdr->ratelimittime = 0;
934 rdr->srvidholdtime = 0;
935 }
936 }
937 else
938 {
939 rdr->ratelimittime = atoi(value);
940 if (rdr->ratelimittime < 60) rdr->ratelimittime *= 1000;
941 }
942 return;
943 }
944 if(rdr->ratelimitecm || cfg.http_full_cfg)
945 { fprintf_conf(f, token, "%d\n", rdr->ratelimittime); }
946}
947
948static void srvidholdtime_fn(const char *token, char *value, void *setting, FILE *f)
949{
950 struct s_reader *rdr = setting;
951 if(value)
952 {
953 if(strlen(value) == 0)
954 {
955 if(rdr->ratelimitecm > 0)
956 {
957 rdr->srvidholdtime = 2000; // default 2 seconds hold
958 }
959 else
960 {
961 rdr->ratelimitecm = 0; // in case someone set a negative value
962 rdr->srvidholdtime = 0;
963 }
964 }
965 else
966 {
967 rdr->srvidholdtime = atoi(value);
968 if (rdr->srvidholdtime < 60) rdr->srvidholdtime *=1000;
969 }
970 return;
971 }
972 if(rdr->ratelimitecm || cfg.http_full_cfg)
973 { fprintf_conf(f, token, "%d\n", rdr->srvidholdtime); }
974}
975
976static void cooldown_fn(const char *token, char *value, void *setting, FILE *f)
977{
978 struct s_reader *rdr = setting;
979 if(value)
980 {
981 if(strlen(value) == 0)
982 {
983 rdr->cooldown[0] = 0;
984 rdr->cooldown[1] = 0;
985 }
986 else
987 {
988 int32_t i;
989 char *ptr, *saveptr1 = NULL;
990 for(i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 2) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++)
991 {
992 rdr->cooldown[i] = atoi(ptr);
993 }
994 if(rdr->cooldown[0] <= 0 || rdr->cooldown[1] <= 0)
995 {
996 fprintf(stderr, "cooldown must have 2 positive values (x,y) set values %d,%d ! cooldown deactivated\n",
997 rdr->cooldown[0], rdr->cooldown[1]);
998 rdr->cooldown[0] = 0;
999 rdr->cooldown[1] = 0;
1000 }
1001 }
1002 return;
1003 }
1004 if(rdr->cooldown[0] || cfg.http_full_cfg)
1005 {
1006 fprintf_conf(f, token, "%d,%d\n", rdr->cooldown[0], rdr->cooldown[1]);
1007 }
1008}
1009
1010static void cooldowndelay_fn(const char *UNUSED(token), char *value, void *setting, FILE *UNUSED(f))
1011{
1012 struct s_reader *rdr = setting;
1013 if(value)
1014 {
1015 rdr->cooldown[0] = strlen(value) ? atoi(value) : 0;
1016 }
1017 // This option is *not* written in the config file.
1018 // It is only set by WebIf as convenience
1019}
1020
1021static void cooldowntime_fn(const char *UNUSED(token), char *value, void *setting, FILE *UNUSED(f))
1022{
1023 struct s_reader *rdr = setting;
1024 if(value)
1025 {
1026 if(strlen(value) == 0)
1027 {
1028 rdr->cooldown[0] = 0; // no cooling down time means no cooling set
1029 rdr->cooldown[1] = 0;
1030 }
1031 else
1032 {
1033 rdr->cooldown[1] = atoi(value);
1034 }
1035 return;
1036 }
1037 // This option is *not* written in the config file.
1038 // It is only set by WebIf as convenience
1039}
1040
1041void reader_fixups_fn(void *var)
1042{
1043 struct s_reader *rdr = var;
1044#ifdef WITH_LB
1045 if(rdr->lb_weight > 1000)
1046 { rdr->lb_weight = 1000; }
1047 else if(rdr->lb_weight <= 0)
1048 { rdr->lb_weight = 100; }
1049#endif
1050
1051 if(is_cascading_reader(rdr) && (rdr->typ == R_CAMD35 || rdr->typ == R_CS378X))
1052 {
1053#ifdef CS_CACHEEX
1054 if(rdr && rdr->cacheex.mode>1)
1055 { rdr->keepalive = 1; } // with cacheex, it is required!
1056 else
1057#endif
1058 if(rdr->typ == R_CAMD35)
1059 { rdr->keepalive = 0; } // with NO-cacheex, and UDP, keepalive is not required!
1060 }
1061}
1062
1063#define OFS(X) offsetof(struct s_reader, X)
1064#define SIZEOF(X) sizeof(((struct s_reader *)0)->X)
1065
1066static const struct config_list reader_opts[] =
1067{
1068 DEF_OPT_FIXUP_FUNC(reader_fixups_fn),
1069 DEF_OPT_FUNC("label" , 0, reader_label_fn),
1070#ifdef WEBIF
1071 DEF_OPT_STR("description" , OFS(description), NULL),
1072#endif
1073 DEF_OPT_INT8("enable" , OFS(enable), 1),
1074 DEF_OPT_FUNC("protocol" , 0, protocol_fn),
1075 DEF_OPT_FUNC("device" , 0, device_fn),
1076 DEF_OPT_HEX("key" , OFS(ncd_key), SIZEOF(ncd_key)),
1077 DEF_OPT_SSTR("user" , OFS(r_usr), "", SIZEOF(r_usr)),
1078 DEF_OPT_SSTR("password" , OFS(r_pwd), "", SIZEOF(r_pwd)),
1079 DEF_OPT_SSTR("pincode" , OFS(pincode), "none", SIZEOF(pincode)),
1080#ifdef MODULE_GBOX
1081 DEF_OPT_UINT8("gbox_max_distance" , OFS(gbox_maxdist), DEFAULT_GBOX_MAX_DIST),
1082 DEF_OPT_UINT8("gbox_max_ecm_send" , OFS(gbox_maxecmsend), DEFAULT_GBOX_MAX_ECM_SEND),
1083 DEF_OPT_UINT8("gbox_reshare" , OFS(gbox_reshare), DEFAULT_GBOX_RESHARE),
1084 DEF_OPT_UINT8("cccam_reshare" , OFS(gbox_cccam_reshare), DEFAULT_CCC_GBOX_RESHARE),
1085#endif
1086 DEF_OPT_STR("readnano" , OFS(emmfile), NULL),
1087 DEF_OPT_FUNC("services" , OFS(sidtabs), reader_services_fn),
1088 DEF_OPT_FUNC("lb_whitelist_services" , OFS(lb_sidtabs), reader_lb_services_fn),
1089 DEF_OPT_INT32("inactivitytimeout" , OFS(tcp_ito), DEFAULT_INACTIVITYTIMEOUT),
1090 DEF_OPT_INT32("reconnecttimeout" , OFS(tcp_rto), DEFAULT_TCP_RECONNECT_TIMEOUT),
1091 DEF_OPT_INT32("reconnectdelay" , OFS(tcp_reconnect_delay), 60000),
1092 DEF_OPT_INT32("resetcycle" , OFS(resetcycle), 0),
1093 DEF_OPT_INT8("disableserverfilter" , OFS(ncd_disable_server_filt), 0),
1094 DEF_OPT_INT8("connectoninit" , OFS(ncd_connect_on_init), 0),
1095 DEF_OPT_UINT8("keepalive" , OFS(keepalive), 0),
1096 DEF_OPT_INT8("smargopatch" , OFS(smargopatch), 0),
1097 DEF_OPT_INT8("autospeed" , OFS(autospeed), 1),
1098 DEF_OPT_UINT8("sc8in1_dtrrts_patch" , OFS(sc8in1_dtrrts_patch), 0),
1099 DEF_OPT_INT8("fallback" , OFS(fallback), 0),
1100 DEF_OPT_FUNC_X("fallback_percaid" , OFS(fallback_percaid), ftab_fn, FTAB_READER | FTAB_FBPCAID),
1101 DEF_OPT_FUNC_X("localcards" , OFS(localcards), ftab_fn, FTAB_READER | FTAB_LOCALCARDS),
1102 DEF_OPT_FUNC_X("disablecrccws_only_for" , OFS(disablecrccws_only_for), ftab_fn, FTAB_READER | FTAB_IGNCHKSMCAID),
1103#ifdef CS_CACHEEX
1104 DEF_OPT_INT8("cacheex" , OFS(cacheex.mode), 0),
1105 DEF_OPT_INT8("cacheex_maxhop" , OFS(cacheex.maxhop), 0),
1106 DEF_OPT_FUNC("cacheex_ecm_filter" , OFS(cacheex.filter_caidtab), cacheex_hitvaluetab_fn),
1107 DEF_OPT_UINT8("cacheex_allow_request" , OFS(cacheex.allow_request), 0),
1108 DEF_OPT_UINT8("cacheex_drop_csp" , OFS(cacheex.drop_csp), 0),
1109 DEF_OPT_UINT8("cacheex_allow_filter" , OFS(cacheex.allow_filter), 1),
1110 DEF_OPT_UINT8("cacheex_block_fakecws" , OFS(cacheex.block_fakecws), 0),
1111#endif
1112 DEF_OPT_FUNC("caid" , OFS(ctab), reader_caid_fn),
1113 DEF_OPT_FUNC("atr" , 0, atr_fn),
1114 DEF_OPT_FUNC("boxid" , 0, boxid_fn),
1115 DEF_OPT_FUNC("boxkey" , 0, boxkey_fn),
1116 DEF_OPT_FUNC("rsakey" , 0, rsakey_fn),
1117 DEF_OPT_FUNC("deskey" , 0, deskey_fn),
1118#ifdef READER_NAGRA_MERLIN
1119 DEF_OPT_FUNC("mod1" , 0, mod1_fn),
1120 DEF_OPT_FUNC("data50" , 0, data50_fn),
1121 DEF_OPT_FUNC("mod50" , 0, mod50_fn),
1122 DEF_OPT_FUNC("key60" , 0, key60_fn),
1123 DEF_OPT_FUNC("exp60" , 0, exp60_fn),
1124 DEF_OPT_FUNC("nuid" , 0, nuid_fn),
1125 DEF_OPT_FUNC("cwekey" , 0, cwekey_fn),
1126#endif
1127 DEF_OPT_FUNC_X("ins7e" , OFS(ins7E), ins7E_fn, SIZEOF(ins7E)),
1128 DEF_OPT_FUNC_X("ins7e11" , OFS(ins7E11), ins7E_fn, SIZEOF(ins7E11)),
1129 DEF_OPT_FUNC_X("ins2e06" , OFS(ins2e06), ins7E_fn, SIZEOF(ins2e06)),
1130 DEF_OPT_INT8("fix07" , OFS(fix_07), 1),
1131 DEF_OPT_INT8("fix9993" , OFS(fix_9993), 0),
1132 DEF_OPT_INT8("readtiers" , OFS(readtiers), 1),
1133 DEF_OPT_INT8("force_irdeto" , OFS(force_irdeto), 0),
1134 DEF_OPT_INT8("needsemmfirst" , OFS(needsemmfirst), 0),
1135#ifdef READER_CRYPTOWORKS
1136 DEF_OPT_INT8("needsglobalfirst" , OFS(needsglobalfirst), 0),
1137#endif
1138 DEF_OPT_UINT32("ecmnotfoundlimit" , OFS(ecmnotfoundlimit), 0),
1139 DEF_OPT_FUNC("ecmwhitelist" , 0, ecmwhitelist_fn),
1140 DEF_OPT_FUNC("ecmheaderwhitelist" , 0, ecmheaderwhitelist_fn),
1141 DEF_OPT_FUNC("detect" , 0, detect_fn),
1142 DEF_OPT_INT8("nagra_read" , OFS(nagra_read), 0),
1143 DEF_OPT_INT8("detect_seca_nagra_tunneled_card", OFS(detect_seca_nagra_tunneled_card), 1),
1144 DEF_OPT_INT32("mhz" , OFS(mhz), 357),
1145 DEF_OPT_INT32("cardmhz" , OFS(cardmhz), 357),
1146#ifdef WITH_AZBOX
1147 DEF_OPT_INT32("mode" , OFS(azbox_mode), -1),
1148#endif
1149 DEF_OPT_FUNC_X("ident" , OFS(ftab), ftab_fn, FTAB_READER | FTAB_PROVID),
1150 DEF_OPT_FUNC_X("chid" , OFS(fchid), ftab_fn, FTAB_READER | FTAB_CHID),
1151 DEF_OPT_FUNC("class" , OFS(cltab), class_fn),
1152 DEF_OPT_FUNC("aeskeys" , 0, aeskeys_fn),
1153 DEF_OPT_FUNC("group" , OFS(grp), group_fn),
1154 DEF_OPT_FUNC("emmcache" , 0, emmcache_fn),
1155 DEF_OPT_FUNC_X("blockemm-unknown" , OFS(blockemm), flags_fn, EMM_UNKNOWN),
1156 DEF_OPT_FUNC_X("blockemm-u" , OFS(blockemm), flags_fn, EMM_UNIQUE),
1157 DEF_OPT_FUNC_X("blockemm-s" , OFS(blockemm), flags_fn, EMM_SHARED),
1158 DEF_OPT_FUNC_X("blockemm-g" , OFS(blockemm), flags_fn, EMM_GLOBAL),
1159 DEF_OPT_FUNC_X("saveemm-unknown" , OFS(saveemm), flags_fn, EMM_UNKNOWN),
1160 DEF_OPT_FUNC_X("saveemm-u" , OFS(saveemm), flags_fn, EMM_UNIQUE),
1161 DEF_OPT_FUNC_X("saveemm-s" , OFS(saveemm), flags_fn, EMM_SHARED),
1162 DEF_OPT_FUNC_X("saveemm-g" , OFS(saveemm), flags_fn, EMM_GLOBAL),
1163 DEF_OPT_FUNC("blockemm-bylen" , 0, blockemm_bylen_fn),
1164#ifdef WITH_LB
1165 DEF_OPT_INT32("lb_weight" , OFS(lb_weight), 100),
1166 DEF_OPT_INT8("lb_force_fallback" , OFS(lb_force_fallback), 0),
1167#endif
1168 DEF_OPT_FUNC("savenano" , OFS(s_nano), nano_fn),
1169 DEF_OPT_FUNC("blocknano" , OFS(b_nano), nano_fn),
1170 DEF_OPT_INT8("dropbadcws" , OFS(dropbadcws), 0),
1171 DEF_OPT_INT8("disablecrccws" , OFS(disablecrccws), 0),
1172 DEF_OPT_INT32("use_gpio" , OFS(use_gpio), 0),
1173#ifdef MODULE_PANDORA
1174 DEF_OPT_UINT8("pand_send_ecm" , OFS(pand_send_ecm), 0),
1175#endif
1176#ifdef MODULE_CCCAM
1177 DEF_OPT_SSTR("cccversion" , OFS(cc_version), "", SIZEOF(cc_version)),
1178 DEF_OPT_INT8("cccmaxhops" , OFS(cc_maxhops), DEFAULT_CC_MAXHOPS),
1179 DEF_OPT_INT8("cccmindown" , OFS(cc_mindown), 0),
1180 DEF_OPT_INT8("cccwantemu" , OFS(cc_want_emu), 0),
1181 DEF_OPT_INT8("ccckeepalive" , OFS(cc_keepalive), DEFAULT_CC_KEEPALIVE),
1182 DEF_OPT_INT8("cccreshare" , OFS(cc_reshare), DEFAULT_CC_RESHARE),
1183 DEF_OPT_INT32("cccreconnect" , OFS(cc_reconnect), DEFAULT_CC_RECONNECT),
1184 DEF_OPT_INT8("ccchop" , OFS(cc_hop), 0),
1185#endif
1186#ifdef MODULE_GHTTP
1187 DEF_OPT_UINT8("use_ssl" , OFS(ghttp_use_ssl), 0),
1188#endif
1189#if defined(READER_DRE) || defined(READER_DRECAS)
1190 DEF_OPT_HEX("force_ua" , OFS(force_ua), 4),
1191 DEF_OPT_STR("exec_cmd_file" , OFS(userscript), NULL),
1192#endif
1193#ifdef READER_DRECAS
1194 DEF_OPT_STR("stmkeys" , OFS(stmkeys), NULL),
1195#endif
1196#ifdef WITH_EMU
1197 DEF_OPT_FUNC_X("emu_auproviders" , OFS(emu_auproviders), ftab_fn, FTAB_READER | FTAB_EMUAU),
1198 DEF_OPT_INT8("emu_datecodedenabled" , OFS(emu_datecodedenabled), 0),
1199#endif
1200 DEF_OPT_INT8("deprecated" , OFS(deprecated), 0),
1201 DEF_OPT_INT8("audisabled" , OFS(audisabled), 0),
1202 DEF_OPT_FUNC("auprovid" , 0, auprovid_fn),
1203 DEF_OPT_INT8("ndsversion" , OFS(ndsversion), 0),
1204 DEF_OPT_FUNC("ratelimitecm" , 0, ratelimitecm_fn),
1205 DEF_OPT_FUNC("ecmunique" , 0, ecmunique_fn),
1206 DEF_OPT_FUNC("ratelimittime" , 0, ratelimittime_fn),
1207 DEF_OPT_FUNC("srvidholdtime" , 0, srvidholdtime_fn),
1208 DEF_OPT_FUNC("cooldown" , 0, cooldown_fn),
1209 DEF_OPT_FUNC("cooldowndelay" , 0, cooldowndelay_fn),
1210 DEF_OPT_FUNC("cooldowntime" , 0, cooldowntime_fn),
1211 DEF_OPT_UINT8("read_old_classes" , OFS(read_old_classes), 1),
1212 DEF_LAST_OPT
1213};
1214
1215static inline bool in_list(const char *token, const char *list[])
1216{
1217 int i;
1218 for(i = 0; list[i]; i++)
1219 {
1220 if(streq(token, list[i]))
1221 { return true; }
1222 }
1223 return false;
1224}
1225
1226static bool reader_check_setting(const struct config_list *UNUSED(clist), void *config_data, const char *setting)
1227{
1228 struct s_reader *reader = config_data;
1229 // These are written only when the reader is physical reader
1230 static const char *hw_only_settings[] =
1231 {
1232 "readnano", "resetcycle", "smargopatch", "autospeed", "sc8in1_dtrrts_patch", "boxid","fix07",
1233 "fix9993", "rsakey", "deskey", "ins7e", "ins7e11", "ins2e06", "force_irdeto", "needsemmfirst", "boxkey",
1234 "atr", "detect", "nagra_read", "mhz", "cardmhz", "readtiers", "read_old_classes", "use_gpio", "needsglobalfirst",
1235#ifdef READER_NAGRA_MERLIN
1236 "mod1", "data50", "mod50", "key60", "exp60", "nuid", "cwekey",
1237#endif
1238#if defined(READER_DRE) || defined(READER_DRECAS)
1239 "exec_cmd_file",
1240#endif
1241#ifdef WITH_AZBOX
1242 "mode",
1243#endif
1244 "deprecated", "ndsversion",
1245 0
1246 };
1247 // These are written only when the reader is network reader
1248 static const char *network_only_settings[] =
1249 {
1250 "user", "inactivitytimeout", "reconnecttimeout",
1251 0
1252 };
1253 if(is_network_reader(reader))
1254 {
1255 if(in_list(setting, hw_only_settings))
1256 { return false; }
1257 }
1258 else
1259 {
1260 if(in_list(setting, network_only_settings))
1261 { return false; }
1262 }
1263
1264 // These are not written in the config file
1265 static const char *deprecated_settings[] =
1266 {
1267 "cooldowndelay", "cooldowntime",
1268 0
1269 };
1270 if(in_list(setting, deprecated_settings))
1271 { return false; }
1272
1273 // Special settings for NEWCAMD
1274 static const char *newcamd_settings[] =
1275 {
1276 "disableserverfilter", "connectoninit",
1277 0
1278 };
1279 if(reader->typ != R_NEWCAMD && in_list(setting, newcamd_settings))
1280 { return false; }
1281#ifdef MODULE_CCCAM
1282 // These are written only when the reader is CCCAM
1283 static const char *cccam_settings[] =
1284 {
1285 "cccversion", "cccmaxhops", "cccmindown", "cccwantemu", "ccckeepalive",
1286 "cccreconnect",
1287 0
1288 };
1289 // Special settings for CCCAM
1290 if(reader->typ != R_CCCAM)
1291 {
1292 if(in_list(setting, cccam_settings))
1293 { return false; }
1294 }
1295 else if(streq(setting, "ccchop"))
1296 {
1297 return false;
1298 }
1299#endif
1300
1301#ifdef MODULE_PANDORA
1302 // Special settings for PANDORA
1303 if(reader->typ != R_PANDORA && streq(setting, "pand_send_ecm"))
1304 { return false; }
1305#endif
1306
1307#ifdef MODULE_GBOX
1308 // These are written only when the reader is GBOX
1309 static const char *gbox_settings[] =
1310 {
1311 "gbox_max_distance", "gbox_max_ecm_send", "gbox_reshare", "cccam_reshare",
1312 0
1313 };
1314 if(reader->typ != R_GBOX)
1315 {
1316 if(in_list(setting, gbox_settings))
1317 { return false; }
1318 }
1319#endif
1320
1321 return true; // Write the setting
1322}
1323
1324void chk_reader(char *token, char *value, struct s_reader *rdr)
1325{
1326 if(config_list_parse(reader_opts, token, value, rdr))
1327 { return; }
1328 else if(token[0] != '#')
1329 { fprintf(stderr, "Warning: keyword '%s' in reader section not recognized\n", token); }
1330}
1331
1332void reader_set_defaults(struct s_reader *rdr)
1333{
1334 config_list_set_defaults(reader_opts, rdr);
1335}
1336
1337int32_t init_readerdb(void)
1338{
1339 configured_readers = ll_create("configured_readers");
1340
1341 FILE *fp = open_config_file(cs_srvr);
1342 if(!fp)
1343 { return 1; }
1344
1345 int32_t tag = 0;
1346 char *value, *token;
1347
1348 if(!cs_malloc(&token, MAXLINESIZE))
1349 { return 1; }
1350
1351 struct s_reader *rdr;
1352 if(!cs_malloc(&rdr, sizeof(struct s_reader)))
1353 {
1354 NULLFREE(token);
1355 return 1;
1356 }
1357
1358 ll_append(configured_readers, rdr);
1359 while(fgets(token, MAXLINESIZE, fp))
1360 {
1361 int32_t l;
1362 if((l = strlen(trim(token))) < 3)
1363 { continue; }
1364 if((token[0] == '[') && (token[l - 1] == ']'))
1365 {
1366 token[l - 1] = 0;
1367 tag = (!strcmp("reader", strtolower(token + 1)));
1368 if(rdr->label[0] && rdr->typ)
1369 {
1370 struct s_reader *newreader;
1371 if(cs_malloc(&newreader, sizeof(struct s_reader)))
1372 {
1373 ll_append(configured_readers, newreader);
1374 rdr = newreader;
1375 }
1376 }
1377 reader_set_defaults(rdr);
1378 continue;
1379 }
1380
1381 if(!tag)
1382 { continue; }
1383 if(!(value = strchr(token, '=')))
1384 { continue; }
1385 *value++ = '\0';
1386 chk_reader(trim(strtolower(token)), trim(value), rdr);
1387 }
1388 NULLFREE(token);
1389 LL_ITER itr = ll_iter_create(configured_readers);
1390 while((rdr = ll_iter_next(&itr))) // build active readers list
1391 {
1392 reader_fixups_fn(rdr);
1393 module_reader_set(rdr);
1394 }
1395 fclose(fp);
1396 return (0);
1397}
1398
1399void free_reader(struct s_reader *rdr)
1400{
1401 NULLFREE(rdr->emmfile);
1402
1403 ecm_whitelist_clear(&rdr->ecm_whitelist);
1404 ecm_hdr_whitelist_clear(&rdr->ecm_hdr_whitelist);
1405
1406 ftab_clear(&rdr->fallback_percaid);
1407 ftab_clear(&rdr->localcards);
1408 ftab_clear(&rdr->fchid);
1409 ftab_clear(&rdr->ftab);
1410
1411 NULLFREE(rdr->cltab.aclass);
1412 NULLFREE(rdr->cltab.bclass);
1413
1414 caidtab_clear(&rdr->ctab);
1415#ifdef CS_CACHEEX
1416 cecspvaluetab_clear(&rdr->cacheex.filter_caidtab);
1417#endif
1418 lb_destroy_stats(rdr);
1419
1420 cs_clear_entitlement(rdr);
1421 ll_destroy(&rdr->ll_entitlements);
1422
1423 if(rdr->csystem && rdr->csystem->card_done)
1424 rdr->csystem->card_done(rdr);
1425 NULLFREE(rdr->csystem_data);
1426
1427 ll_destroy_data(&rdr->blockemmbylen);
1428
1429 ll_destroy_data(&rdr->emmstat);
1430
1431 aes_clear_entries(&rdr->aes_list);
1432
1433 config_list_gc_values(reader_opts, rdr);
1434 add_garbage(rdr);
1435}
1436
1437int32_t free_readerdb(void)
1438{
1439 int count = 0;
1440 struct s_reader *rdr;
1441 LL_ITER itr = ll_iter_create(configured_readers);
1442 while((rdr = ll_iter_next(&itr)))
1443 {
1444 free_reader(rdr);
1445 count++;
1446 }
1447 cs_log("readerdb %d readers freed", count);
1448 ll_destroy(&configured_readers);
1449 return count;
1450}
1451
1452int32_t write_server(void)
1453{
1454 FILE *f = create_config_file(cs_srvr);
1455 if(!f)
1456 { return 1; }
1457 struct s_reader *rdr;
1458 LL_ITER itr = ll_iter_create(configured_readers);
1459 while((rdr = ll_iter_next(&itr)))
1460 {
1461 if(rdr->label[0])
1462 {
1463 fprintf(f, "[reader]\n");
1464 config_list_apply_fixups(reader_opts, rdr);
1465 config_list_save_ex(f, reader_opts, rdr, cfg.http_full_cfg, reader_check_setting);
1466 fprintf(f, "\n");
1467 }
1468 }
1469 return flush_config_file(f, cs_srvr);
1470}
1471
1472void reload_readerdb(void)
1473{
1474 struct s_reader *rdr;
1475 LL_ITER itr = ll_iter_create(configured_readers);
1476 while((rdr = ll_iter_next(&itr)))
1477 {
1478 // disable the current reader
1479 rdr->enable = 0;
1480 restart_cardreader(rdr,1);
1481 }
1482 free_readerdb(); // release the old readerdb
1483 init_readerdb(); // reload the new readerdb
1484 init_cardreader(); // start the readers
1485}
Note: See TracBrowser for help on using the repository browser.