- fix Building without Nagra not possible at Nagra_Merlin https://trac.streamboard...
[oscam.git] / oscam-config-reader.c
blobb3e58fc23432f957de9fa851f8dbb9a8ff80ff83
1 #define MODULE_LOG_PREFIX "config"
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 #ifdef CS_CACHEEX_AIO
19 #include "module-cacheex.h"
20 #endif
22 #define cs_srvr "oscam.server"
24 extern const struct s_cardreader *cardreaders[];
25 extern char *RDR_CD_TXT[];
27 static void reader_label_fn(const char *token, char *value, void *setting, FILE *f)
29 struct s_reader *rdr = setting;
30 if(value)
32 int i, found = 0;
33 if(!cs_strlen(value))
34 { return; }
35 for(i = 0; i < (int)cs_strlen(value); i++)
37 if(value[i] == ' ')
39 value[i] = '_';
40 found++;
43 if(found)
44 { fprintf(stderr, "Configuration reader: corrected label to %s\n", value); }
45 cs_strncpy(rdr->label, value, sizeof(rdr->label));
46 return;
48 fprintf_conf(f, token, "%s\n", rdr->label);
51 static void ecmwhitelist_fn(const char *token, char *value, void *setting, FILE *f)
53 struct s_reader *rdr = setting;
54 if(value)
56 if(cs_strlen(value))
57 chk_ecm_whitelist(value, &rdr->ecm_whitelist);
58 else
59 ecm_whitelist_clear(&rdr->ecm_whitelist);
60 return;
63 value = mk_t_ecm_whitelist(&rdr->ecm_whitelist);
64 if(cs_strlen(value) > 0 || cfg.http_full_cfg)
65 { fprintf_conf(f, token, "%s\n", value); }
66 free_mk_t(value);
69 static void ecmheaderwhitelist_fn(const char *token, char *value, void *setting, FILE *f)
71 struct s_reader *rdr = setting;
72 if(value)
74 if(cs_strlen(value))
75 chk_ecm_hdr_whitelist(value, &rdr->ecm_hdr_whitelist);
76 else
77 ecm_hdr_whitelist_clear(&rdr->ecm_hdr_whitelist);
78 return;
81 value = mk_t_ecm_hdr_whitelist(&rdr->ecm_hdr_whitelist);
82 if(cs_strlen(value) > 0 || cfg.http_full_cfg)
83 { fprintf_conf(f, token, "%s\n", value); }
84 free_mk_t(value);
87 static void protocol_fn(const char *token, char *value, void *setting, FILE *f)
89 struct s_reader *rdr = setting;
90 if(value)
92 if(cs_strlen(value) == 0)
93 { return; }
94 struct protocol_map
96 char *name;
97 int typ;
98 } protocols[] =
100 { "serial", R_SERIAL },
101 { "camd35", R_CAMD35 },
102 { "cs378x", R_CS378X },
103 { "cs357x", R_CAMD35 },
104 { "camd33", R_CAMD33 },
105 { "gbox", R_GBOX },
106 { "cccam", R_CCCAM },
107 { "cccam_ext", R_CCCAM },
108 { "cccam_mcs", R_CCCAM },
109 { "constcw", R_CONSTCW },
110 { "radegast", R_RADEGAST },
111 { "scam", R_SCAM },
112 { "ghttp", R_GHTTP },
113 { "newcamd", R_NEWCAMD },
114 { "newcamd525", R_NEWCAMD },
115 { "newcamd524", R_NEWCAMD },
116 { "drecas", R_DRECAS },
117 { "emu", R_EMU },
118 { NULL, 0 }
119 }, *p;
120 int i;
121 // Parse card readers
122 for(i = 0; cardreaders[i]; i++)
124 if(streq(value, cardreaders[i]->desc))
126 rdr->crdr = cardreaders[i];
127 rdr->typ = cardreaders[i]->typ;
128 return;
131 // Parse protocols
132 for(i = 0, p = &protocols[0]; p->name; p = &protocols[++i])
134 if(streq(p->name, value))
136 rdr->typ = p->typ;
137 break;
140 if(rdr->typ == R_NEWCAMD)
141 { rdr->ncd_proto = streq(value, "newcamd524") ? NCD_524 : NCD_525; }
142 if(!rdr->typ)
144 fprintf(stderr, "ERROR: '%s' is unsupported reader protocol!\n", value);
145 rdr->enable = 0;
147 return;
149 fprintf_conf(f, token, "%s\n", reader_get_type_desc(rdr, 0));
152 static void device_fn(const char *token, char *value, void *setting, FILE *f)
154 struct s_reader *rdr = setting;
155 int32_t isphysical = !is_network_reader(rdr);
156 if(value)
158 int32_t i;
159 char *ptr, *saveptr1 = NULL;
160 for(i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 3) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++)
162 trim(ptr);
163 switch(i)
165 case 0:
166 cs_strncpy(rdr->device, ptr, sizeof(rdr->device));
167 break;
168 case 1:
169 rdr->r_port = atoi(ptr);
170 break;
171 case 2:
172 rdr->l_port = atoi(ptr);
173 break;
176 return;
178 fprintf_conf(f, token, "%s", rdr->device); // it should not have \n at the end
179 if((rdr->r_port || cfg.http_full_cfg) && !isphysical)
180 { fprintf(f, ",%d", rdr->r_port); }
181 if((rdr->l_port || cfg.http_full_cfg) && !isphysical && strncmp(reader_get_type_desc(rdr, 0), "cccam", 5))
182 { fprintf(f, ",%d", rdr->l_port); }
183 fprintf(f, "\n");
186 static void reader_services_fn(const char *token, char *value, void *setting, FILE *f)
188 services_fn(token, value, setting, f);
189 if(value)
191 struct s_reader *rdr = container_of(setting, struct s_reader, sidtabs);
192 if(rdr)
193 { rdr->changes_since_shareupdate = 1; }
197 static void reader_lb_services_fn(const char *token, char *value, void *setting, FILE *f)
199 services_fn(token, value, setting, f);
200 if(value)
202 struct s_reader *rdr = container_of(setting, struct s_reader, lb_sidtabs);
203 if(rdr)
204 { rdr->changes_since_shareupdate = 1; }
208 static void reader_caid_fn(const char *token, char *value, void *setting, FILE *f)
210 check_caidtab_fn(token, value, setting, f);
211 if(value)
213 struct s_reader *rdr = container_of(setting, struct s_reader, ctab);
214 if(rdr)
215 { rdr->changes_since_shareupdate = 1; }
219 static void boxid_fn(const char *token, char *value, void *setting, FILE *f)
221 struct s_reader *rdr = setting;
222 if(value)
224 rdr->boxid = cs_strlen(value) ? a2i(value, 4) : 0;
225 return;
227 if(rdr->boxid)
228 { fprintf_conf(f, token, "%08X\n", rdr->boxid); }
229 else if(cfg.http_full_cfg)
230 { fprintf_conf(f, token, "\n"); }
233 static void cwpkkey_fn(const char *token, char *value, void *setting, FILE *f)
235 struct s_reader *rdr = setting;
236 if(value)
238 int32_t len = strlen(value);
239 // rdr_log(rdr, "CWPK config key length: %16X", len);
240 if(len == 0 || len > 32)
242 rdr->cwpk_mod_length = 0;
243 memset(rdr->cwpk_mod, 0, sizeof(rdr->cwpk_mod));
245 else
247 if(key_atob_l(value, rdr->cwpk_mod, len))
249 fprintf(stderr, "reader cwpkkey parse error, %s=%s\n", token, value);
250 rdr->cwpk_mod_length = 0;
251 memset(rdr->cwpk_mod, 0, sizeof(rdr->cwpk_mod));
253 else
255 rdr->cwpk_mod_length = len/2;
258 return;
260 int32_t len = rdr->cwpk_mod_length;
261 if(len > 0)
263 char tmp[len * 2 + 1];
264 fprintf_conf(f, "cwpkkey", "%s\n", cs_hexdump(0, rdr->cwpk_mod, len, tmp, sizeof(tmp)));
266 else if(cfg.http_full_cfg)
267 { fprintf_conf(f, "cwpkkey", "\n"); }
270 static void rsakey_fn(const char *token, char *value, void *setting, FILE *f)
272 struct s_reader *rdr = setting;
273 if(value)
275 int32_t len = cs_strlen(value);
276 if(len != 128 && len != 240)
278 rdr->rsa_mod_length = 0;
279 memset(rdr->rsa_mod, 0, 120);
281 else
283 if(key_atob_l(value, rdr->rsa_mod, len))
285 fprintf(stderr, "reader rsakey parse error, %s=%s\n", token, value);
286 rdr->rsa_mod_length = 0;
287 memset(rdr->rsa_mod, 0, sizeof(rdr->rsa_mod));
289 else
291 rdr->rsa_mod_length = len/2;
294 return;
296 int32_t len = rdr->rsa_mod_length;
297 if(len > 0)
299 char tmp[len * 2 + 1];
300 fprintf_conf(f, "rsakey", "%s\n", cs_hexdump(0, rdr->rsa_mod, len, tmp, sizeof(tmp)));
302 else if(cfg.http_full_cfg)
303 { fprintf_conf(f, "rsakey", "\n"); }
306 static void deskey_fn(const char *token, char *value, void *setting, FILE *f)
308 struct s_reader *rdr = setting;
309 if(value)
311 int32_t len = cs_strlen(value);
312 if(((len % 16) != 0) || len == 0 || len > 128*2)
314 rdr->des_key_length = 0;
315 memset(rdr->des_key, 0, sizeof(rdr->des_key));
317 else
319 if(key_atob_l(value, rdr->des_key, len))
321 fprintf(stderr, "reader 3DES key parse error, %s=%s\n", token, value);
322 rdr->des_key_length = 0;
323 memset(rdr->des_key, 0, sizeof(rdr->des_key));
325 else
327 rdr->des_key_length = len/2;
330 return;
332 int32_t len = rdr->des_key_length;
333 if(len > 0)
335 char tmp[len * 2 + 1];
336 fprintf_conf(f, "deskey", "%s\n", cs_hexdump(0, rdr->des_key, len, tmp, sizeof(tmp)));
338 else if(cfg.http_full_cfg)
339 { fprintf_conf(f, "deskey", "\n"); }
342 static void boxkey_fn(const char *token, char *value, void *setting, FILE *f)
344 struct s_reader *rdr = setting;
345 if(value)
347 int32_t len = cs_strlen(value);
348 if(((len % 8) != 0) || len == 0 || len > 32)
350 rdr->boxkey_length = 0;
351 memset(rdr->boxkey, 0, sizeof(rdr->boxkey));
353 else
355 if(key_atob_l(value, rdr->boxkey, len))
357 fprintf(stderr, "reader boxkey parse error, %s=%s\n", token, value);
358 rdr->boxkey_length = 0;
359 memset(rdr->boxkey, 0, sizeof(rdr->boxkey));
361 else
363 rdr->boxkey_length = len/2;
366 return;
368 int32_t len = rdr->boxkey_length;
369 if(len > 0)
371 char tmp[len * 2 + 1];
372 fprintf_conf(f, "boxkey", "%s\n", cs_hexdump(0, rdr->boxkey, len, tmp, sizeof(tmp)));
374 else if(cfg.http_full_cfg)
375 { fprintf_conf(f, "boxkey", "\n"); }
378 #if defined(READER_NAGRA) || defined(READER_NAGRA_MERLIN)
379 static void param_fn(const char *token, char *value, void *setting, long data, FILE *f)
381 uint8_t *var = setting, valid_len = data & 0xFF;
382 uint8_t *var_len = (var + (data >> 8));
383 if(value)
385 int32_t len = cs_strlen(value);
386 if(len != valid_len * 2 || key_atob_l(value, var, len))
388 if(len > 0)
389 { fprintf(stderr, "reader %s parse error, %s=%s\n", token, token, value); }
390 memset(var, 0, valid_len);
392 else
394 *var_len = valid_len; // found and correct
396 return;
398 if(*var_len)
400 char tmp[*var_len * 2 + 1];
401 fprintf_conf(f, token, "%s\n", cs_hexdump(0, var, *var_len, tmp, sizeof(tmp)));
403 else if(cfg.http_full_cfg)
404 { fprintf_conf(f, token, "\n"); }
406 #endif
408 static void flags_fn(const char *token, char *value, void *setting, long flag, FILE *f)
410 uint32_t *var = setting;
411 if(value)
413 int i = atoi(value);
414 if(!i && (*var & flag))
415 { *var -= flag; }
416 if(i)
417 { *var |= flag; }
418 return;
420 if((*var & flag) || cfg.http_full_cfg)
421 { fprintf_conf(f, token, "%d\n", (*var & flag) ? 1 : 0); }
424 static void ins7E_fn(const char *token, char *value, void *setting, long var_size, FILE *f)
426 uint8_t *var = setting;
427 var_size -= 1; // var_size contains sizeof(var) which is [X + 1]
428 if(value)
430 int32_t len = cs_strlen(value);
431 if(len != var_size * 2 || key_atob_l(value, var, len))
433 if(len > 0)
434 { fprintf(stderr, "reader %s parse error, %s=%s\n", token, token, value); }
435 memset(var, 0, var_size + 1);
437 else
439 var[var_size] = 1; // found and correct
441 return;
443 if(var[var_size])
445 char tmp[var_size * 2 + 1];
446 fprintf_conf(f, token, "%s\n", cs_hexdump(0, var, var_size, tmp, sizeof(tmp)));
448 else if(cfg.http_full_cfg)
449 { fprintf_conf(f, token, "\n"); }
452 static void ins42_fn(const char *token, char *value, void *setting, long var_size, FILE *f)
454 uint8_t *var = setting;
455 var_size -= 1; // var_size contains sizeof(var) which is [X + 1]
456 if(value)
458 int32_t len = cs_strlen(value);
459 if(len != var_size * 2 || key_atob_l(value, var, len))
461 if(len > 0)
462 { fprintf(stderr, "reader %s parse error, %s=%s\n", token, token, value); }
463 memset(var, 0, var_size + 1);
465 else
467 var[var_size] = 1; // found and correct
469 return;
471 if(var[var_size])
473 char tmp[var_size * 2 + 1];
474 fprintf_conf(f, token, "%s\n", cs_hexdump(0, var, var_size, tmp, sizeof(tmp)));
476 else if(cfg.http_full_cfg)
477 { fprintf_conf(f, token, "\n"); }
480 static void des_and_3des_key_fn(const char *token, char *value, void *setting, FILE *f)
482 uint8_t *var = setting;
483 if(value)
485 int32_t len = cs_strlen(value);
486 if(((len != 16) && (len != 32)) || (key_atob_l(value, var, len)))
488 if(len > 0)
489 { fprintf(stderr, "reader %s parse error, %s=%s\n", token, token, value); }
490 memset(var, 0, 17);
492 else
494 var[16] = len/2;
496 return;
498 if(var[16])
500 char tmp[var[16] * 2 + 1];
501 fprintf_conf(f, token, "%s\n", cs_hexdump(0, var, var[16], tmp, sizeof(tmp)));
503 else if(cfg.http_full_cfg)
504 { fprintf_conf(f, token, "\n"); }
507 static void atr_fn(const char *token, char *value, void *setting, FILE *f)
509 struct s_reader *rdr = setting;
510 if(value)
512 memset(rdr->atr, 0, sizeof(rdr->atr));
513 rdr->atrlen = cs_strlen(value);
514 if(rdr->atrlen)
516 if(rdr->atrlen > (int32_t)sizeof(rdr->atr) * 2)
517 { rdr->atrlen = (int32_t)sizeof(rdr->atr) * 2; }
518 key_atob_l(value, rdr->atr, rdr->atrlen);
520 return;
522 if(rdr->atr[0] || cfg.http_full_cfg)
524 int j;
525 fprintf_conf(f, token, "%s", ""); // it should not have \n at the end
526 if(rdr->atr[0])
528 for(j = 0; j < rdr->atrlen / 2; j++)
530 fprintf(f, "%02X", rdr->atr[j]);
533 fprintf(f, "\n");
537 static void detect_fn(const char *token, char *value, void *setting, FILE *f)
539 struct s_reader *rdr = setting;
540 if(value)
542 int i;
543 for(i = 0; RDR_CD_TXT[i]; i++)
545 if(!strcmp(value, RDR_CD_TXT[i]))
547 rdr->detect = i;
549 else
551 if(value[0] == '!' && streq(value + 1, RDR_CD_TXT[i]))
552 { rdr->detect = i | 0x80; }
555 return;
557 fprintf_conf(f, token, "%s%s\n", rdr->detect & 0x80 ? "!" : "", RDR_CD_TXT[rdr->detect & 0x7f]);
560 void ftab_fn(const char *token, char *value, void *setting, long ftab_type, FILE *f)
562 FTAB *ftab = setting;
563 if(value)
565 if(cs_strlen(value))
566 chk_ftab(value, ftab);
567 else
568 ftab_clear(ftab);
569 return;
571 if(ftab_type & FTAB_READER)
573 struct s_reader *rdr = NULL;
574 if(ftab_type & FTAB_PROVID) { rdr = container_of(setting, struct s_reader, ftab); }
575 if(ftab_type & FTAB_CHID) { rdr = container_of(setting, struct s_reader, fchid); }
576 if(ftab_type & FTAB_FBPCAID) { rdr = container_of(setting, struct s_reader, fallback_percaid); }
577 if(ftab_type & FTAB_LOCALCARDS) { rdr = container_of(setting, struct s_reader, localcards); }
578 if(ftab_type & FTAB_IGNCHKSMCAID){ rdr = container_of(setting, struct s_reader, disablecrccws_only_for); }
579 #ifdef WITH_EMU
580 if(ftab_type & FTAB_EMUAU) { rdr = container_of(setting, struct s_reader, emu_auproviders); }
581 #endif
582 #ifdef MODULE_GBOX
583 if(ftab_type & FTAB_CCCGBXRESHARE){ rdr = container_of(setting, struct s_reader, ccc_gbx_reshare_ident); }
584 #endif
585 if(rdr)
586 { rdr->changes_since_shareupdate = 1; }
588 value = mk_t_ftab(ftab);
589 if(cs_strlen(value) > 0 || cfg.http_full_cfg)
590 { fprintf_conf(f, token, "%s\n", value); }
591 free_mk_t(value);
594 static void aeskeys_fn(const char *token, char *value, void *setting, FILE *f)
596 struct s_reader *rdr = setting;
597 if(value)
599 parse_aes_keys(rdr, value);
600 return;
602 value = mk_t_aeskeys(rdr);
603 if(cs_strlen(value) > 0 || cfg.http_full_cfg)
604 { fprintf_conf(f, token, "%s\n", value); }
605 free_mk_t(value);
608 static void emmcache_fn(const char *token, char *value, void *setting, FILE *f)
610 struct s_reader *rdr = setting;
611 if(value)
613 rdr->cachemm = 0;
614 rdr->rewritemm = 0;
615 rdr->logemm = 0;
616 rdr->deviceemm = 0;
617 if(cs_strlen(value))
619 int i;
620 char *ptr, *saveptr1 = NULL;
621 for(i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 4) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++)
623 switch(i)
625 case 0:
626 rdr->cachemm = atoi(ptr);
627 break;
628 case 1:
629 rdr->rewritemm = atoi(ptr);
630 break;
631 case 2:
632 rdr->logemm = atoi(ptr);
633 break;
634 case 3:
635 rdr->deviceemm = atoi(ptr);
638 if(rdr->rewritemm <= 0)
640 fprintf(stderr, "Setting reader \"emmcache\" to %i,%d,%i,%i instead of %i,%i,%i,%i.",
641 rdr->cachemm, 1, rdr->logemm, rdr->deviceemm,
642 rdr->cachemm, rdr->rewritemm, rdr->logemm, rdr->deviceemm);
643 fprintf(stderr, "Zero or negative number of rewrites is silly\n");
644 rdr->rewritemm = 1;
647 return;
649 if(rdr->cachemm || rdr->logemm || cfg.http_full_cfg)
650 { fprintf_conf(f, token, "%d,%d,%d,%d\n", rdr->cachemm, rdr->rewritemm, rdr->logemm,rdr->deviceemm); }
653 static void blockemm_bylen_fn(const char *token, char *value, void *setting, FILE *f)
655 struct s_reader *rdr = setting;
656 if(value)
658 char *ptr, *saveptr1 = NULL, dash;
659 struct s_emmlen_range *blocklen;
660 uint32_t num;
662 if(!cs_strlen(value))
664 ll_destroy_data(&rdr->blockemmbylen);
665 return;
668 if(!rdr->blockemmbylen)
669 { rdr->blockemmbylen = ll_create("blockemmbylen"); }
670 else
671 { ll_clear_data(rdr->blockemmbylen); }
673 for(ptr = strtok_r(value, ",", &saveptr1); ptr;
674 ptr = strtok_r(NULL, ",", &saveptr1))
676 if(!cs_malloc(&blocklen, sizeof(*blocklen)))
677 { return; }
678 num = sscanf(ptr, "%hd%c%hd", &blocklen->min, &dash, &blocklen->max);
679 if(num <= 0)
681 NULLFREE(blocklen);
682 fprintf(stderr, "blockemm-bylen parse error: %s\n", value);
683 continue;
685 if(num == 1) // single values: x1, x2, x3, ...
686 { blocklen->max = blocklen->min; }
687 else if(num == 2) // range values with open end: x1-
688 { blocklen->max = 0; }
689 ll_append(rdr->blockemmbylen, blocklen);
691 return;
693 value = mk_t_emmbylen(rdr);
694 if(cs_strlen(value) > 0 || cfg.http_full_cfg)
695 { fprintf_conf(f, token, "%s\n", value); }
696 free_mk_t(value);
699 static void nano_fn(const char *token, char *value, void *setting, FILE *f)
701 uint16_t *nano = setting;
702 if(value)
704 *nano = 0;
705 if(cs_strlen(value) > 0)
707 if(streq(value, "all"))
709 *nano = 0xFFFF;
711 else
713 int32_t i;
714 char *ptr, *saveptr1 = NULL;
715 for(ptr = strtok_r(value, ",", &saveptr1); ptr; ptr = strtok_r(NULL, ",", &saveptr1))
717 i = (byte_atob(ptr) % 0x80);
718 if(i >= 0 && i <= 16)
719 { *nano |= (1 << i); }
723 return;
725 value = mk_t_nano(*nano);
726 if(cs_strlen(value) > 0 || cfg.http_full_cfg)
727 { fprintf_conf(f, token, "%s\n", value); }
728 free_mk_t(value);
731 static void auprovid_fn(const char *token, char *value, void *setting, FILE *f)
733 struct s_reader *rdr = setting;
734 if(value)
736 rdr->auprovid = 0;
737 if(cs_strlen(value))
738 { rdr->auprovid = a2i(value, 3); }
739 return;
741 if(rdr->auprovid)
742 { fprintf_conf(f, token, "%06X\n", rdr->auprovid); }
743 else if(cfg.http_full_cfg)
744 { fprintf_conf(f, token, "\n"); }
747 static void ratelimitecm_fn(const char *token, char *value, void *setting, FILE *f)
749 struct s_reader *rdr = setting;
750 if(value)
752 rdr->ratelimitecm = 0;
753 if(cs_strlen(value))
755 int i;
756 rdr->ratelimitecm = atoi(value);
757 for(i = 0; i < MAXECMRATELIMIT; i++) // reset all slots
759 rdr->rlecmh[i].srvid = -1;
760 rdr->rlecmh[i].last.time = -1;
763 return;
765 if(rdr->ratelimitecm || cfg.http_full_cfg)
766 { fprintf_conf(f, token, "%d\n", rdr->ratelimitecm); }
769 static void ecmunique_fn(const char *token, char *value, void *setting, FILE *f)
771 struct s_reader *rdr = setting;
772 if(value)
774 if(cs_strlen(value) == 0)
776 rdr->ecmunique = 0; // default
778 else
780 rdr->ecmunique = atoi(value);
781 if(rdr->ecmunique >= 1)
782 { rdr->ecmunique = 1; }
783 else
784 { rdr->ecmunique = 0; }
786 return;
788 if((rdr->ratelimitecm && rdr->ecmunique != 0) || cfg.http_full_cfg)
789 { fprintf_conf(f, token, "%d\n", rdr->ecmunique); }
792 static void ratelimittime_fn(const char *token, char *value, void *setting, FILE *f)
794 struct s_reader *rdr = setting;
795 if(value)
797 if(cs_strlen(value) == 0)
799 if(rdr->ratelimitecm > 0)
801 rdr->ratelimittime = 9000; // default 9 seconds
802 rdr->srvidholdtime = 2000; // default 2 seconds hold
804 else
806 rdr->ratelimitecm = 0; // in case someone set a negative value
807 rdr->ratelimittime = 0;
808 rdr->srvidholdtime = 0;
811 else
813 rdr->ratelimittime = atoi(value);
814 if (rdr->ratelimittime < 60) rdr->ratelimittime *= 1000;
816 return;
818 if(rdr->ratelimitecm || cfg.http_full_cfg)
819 { fprintf_conf(f, token, "%d\n", rdr->ratelimittime); }
822 static void srvidholdtime_fn(const char *token, char *value, void *setting, FILE *f)
824 struct s_reader *rdr = setting;
825 if(value)
827 if(cs_strlen(value) == 0)
829 if(rdr->ratelimitecm > 0)
831 rdr->srvidholdtime = 2000; // default 2 seconds hold
833 else
835 rdr->ratelimitecm = 0; // in case someone set a negative value
836 rdr->srvidholdtime = 0;
839 else
841 rdr->srvidholdtime = atoi(value);
842 if (rdr->srvidholdtime < 60) rdr->srvidholdtime *=1000;
844 return;
846 if(rdr->ratelimitecm || cfg.http_full_cfg)
847 { fprintf_conf(f, token, "%d\n", rdr->srvidholdtime); }
850 static void cooldown_fn(const char *token, char *value, void *setting, FILE *f)
852 struct s_reader *rdr = setting;
853 if(value)
855 if(cs_strlen(value) == 0)
857 rdr->cooldown[0] = 0;
858 rdr->cooldown[1] = 0;
860 else
862 int32_t i;
863 char *ptr, *saveptr1 = NULL;
864 for(i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 2) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++)
866 rdr->cooldown[i] = atoi(ptr);
868 if(rdr->cooldown[0] <= 0 || rdr->cooldown[1] <= 0)
870 fprintf(stderr, "cooldown must have 2 positive values (x,y) set values %d,%d ! cooldown deactivated\n",
871 rdr->cooldown[0], rdr->cooldown[1]);
872 rdr->cooldown[0] = 0;
873 rdr->cooldown[1] = 0;
876 return;
878 if(rdr->cooldown[0] || cfg.http_full_cfg)
880 fprintf_conf(f, token, "%d,%d\n", rdr->cooldown[0], rdr->cooldown[1]);
884 static void cooldowndelay_fn(const char *UNUSED(token), char *value, void *setting, FILE *UNUSED(f))
886 struct s_reader *rdr = setting;
887 if(value)
889 rdr->cooldown[0] = cs_strlen(value) ? atoi(value) : 0;
891 // This option is *not* written in the config file.
892 // It is only set by WebIf as convenience
895 static void cooldowntime_fn(const char *UNUSED(token), char *value, void *setting, FILE *UNUSED(f))
897 struct s_reader *rdr = setting;
898 if(value)
900 if(cs_strlen(value) == 0)
902 rdr->cooldown[0] = 0; // no cooling down time means no cooling set
903 rdr->cooldown[1] = 0;
905 else
907 rdr->cooldown[1] = atoi(value);
909 return;
911 // This option is *not* written in the config file.
912 // It is only set by WebIf as convenience
915 void reader_fixups_fn(void *var)
917 struct s_reader *rdr = var;
918 #ifdef WITH_LB
919 if(rdr->lb_weight > 1000)
920 { rdr->lb_weight = 1000; }
921 else if(rdr->lb_weight <= 0)
922 { rdr->lb_weight = 100; }
923 #endif
925 #ifdef CS_CACHEEX_AIO
926 caidtab2ftab_add(&rdr->cacheex.localgenerated_only_in_caidtab, &rdr->cacheex.lg_only_in_tab);
927 caidtab_clear(&rdr->cacheex.localgenerated_only_in_caidtab);
928 caidtab2ftab_add(&rdr->cacheex.localgenerated_only_caidtab, &rdr->cacheex.lg_only_tab);
929 caidtab_clear(&rdr->cacheex.localgenerated_only_caidtab);
930 #endif
932 if(is_cascading_reader(rdr) && (rdr->typ == R_CAMD35 || rdr->typ == R_CS378X))
934 #ifdef CS_CACHEEX
935 if(rdr && rdr->cacheex.mode>1)
936 { rdr->keepalive = 1; } // with cacheex, it is required!
937 else
938 #endif
939 if(rdr->typ == R_CAMD35)
940 { rdr->keepalive = 0; } // with NO-cacheex, and UDP, keepalive is not required!
944 #define OFS(X) offsetof(struct s_reader, X)
945 #define SIZEOF(X) sizeof(((struct s_reader *)0)->X)
947 static const struct config_list reader_opts[] =
949 DEF_OPT_FIXUP_FUNC(reader_fixups_fn),
950 DEF_OPT_FUNC("label" , 0, reader_label_fn),
951 #ifdef WEBIF
952 DEF_OPT_STR("description" , OFS(description), NULL),
953 #endif
954 DEF_OPT_INT8("enable" , OFS(enable), 1),
955 DEF_OPT_FUNC("protocol" , 0, protocol_fn),
956 DEF_OPT_FUNC("device" , 0, device_fn),
957 DEF_OPT_HEX("key" , OFS(ncd_key), SIZEOF(ncd_key)),
958 DEF_OPT_SSTR("user" , OFS(r_usr), "", SIZEOF(r_usr)),
959 DEF_OPT_SSTR("password" , OFS(r_pwd), "", SIZEOF(r_pwd)),
960 DEF_OPT_SSTR("pincode" , OFS(pincode), "none", SIZEOF(pincode)),
961 #ifdef MODULE_GBOX
962 DEF_OPT_UINT8("gbox_max_distance" , OFS(gbox_maxdist), DEFAULT_GBOX_MAX_DIST),
963 DEF_OPT_UINT8("gbox_max_ecm_send" , OFS(gbox_maxecmsend), DEFAULT_GBOX_MAX_ECM_SEND),
964 DEF_OPT_UINT8("gbox_reshare" , OFS(gbox_reshare), DEFAULT_GBOX_RESHARE),
965 DEF_OPT_INT8("cccam_reshare" , OFS(gbox_cccam_reshare), -1),
966 DEF_OPT_UINT8("force_remm" , OFS(gbox_force_remm), 0),
967 DEF_OPT_FUNC_X("ccc_gbx_reshare_ident" , OFS(ccc_gbx_reshare_ident), ftab_fn, FTAB_READER | FTAB_CCCGBXRESHARE),
968 DEF_OPT_UINT8("send_offline_cmd" , OFS(send_offline_cmd), 0),
969 #endif
970 DEF_OPT_STR("readnano" , OFS(emmfile), NULL),
971 DEF_OPT_FUNC("services" , OFS(sidtabs), reader_services_fn),
972 DEF_OPT_FUNC("lb_whitelist_services" , OFS(lb_sidtabs), reader_lb_services_fn),
973 DEF_OPT_INT32("inactivitytimeout" , OFS(tcp_ito), DEFAULT_INACTIVITYTIMEOUT),
974 DEF_OPT_INT32("reconnecttimeout" , OFS(tcp_rto), DEFAULT_TCP_RECONNECT_TIMEOUT),
975 DEF_OPT_INT32("reconnectdelay" , OFS(tcp_reconnect_delay), 60000),
976 DEF_OPT_INT32("resetcycle" , OFS(resetcycle), 0),
977 DEF_OPT_INT8("disableserverfilter" , OFS(ncd_disable_server_filt), 0),
978 DEF_OPT_INT8("connectoninit" , OFS(ncd_connect_on_init), 0),
979 DEF_OPT_UINT8("keepalive" , OFS(keepalive), 0),
980 DEF_OPT_INT8("smargopatch" , OFS(smargopatch), 0),
981 DEF_OPT_INT8("autospeed" , OFS(autospeed), 1),
982 DEF_OPT_UINT8("sc8in1_dtrrts_patch" , OFS(sc8in1_dtrrts_patch), 0),
983 DEF_OPT_INT8("fallback" , OFS(fallback), 0),
984 DEF_OPT_FUNC_X("fallback_percaid" , OFS(fallback_percaid), ftab_fn, FTAB_READER | FTAB_FBPCAID),
985 DEF_OPT_FUNC_X("localcards" , OFS(localcards), ftab_fn, FTAB_READER | FTAB_LOCALCARDS),
986 DEF_OPT_FUNC_X("disablecrccws_only_for" , OFS(disablecrccws_only_for), ftab_fn, FTAB_READER | FTAB_IGNCHKSMCAID),
987 #ifdef CS_CACHEEX
988 DEF_OPT_INT8("cacheex" , OFS(cacheex.mode), 0),
989 DEF_OPT_INT8("cacheex_maxhop" , OFS(cacheex.maxhop), 0),
990 #ifdef CS_CACHEEX_AIO
991 DEF_OPT_INT8("cacheex_maxhop_lg" , OFS(cacheex.maxhop_lg), 0),
992 #endif
993 DEF_OPT_FUNC("cacheex_ecm_filter" , OFS(cacheex.filter_caidtab), cacheex_hitvaluetab_fn),
994 DEF_OPT_UINT8("cacheex_allow_request" , OFS(cacheex.allow_request), 0),
995 DEF_OPT_UINT8("cacheex_drop_csp" , OFS(cacheex.drop_csp), 0),
996 DEF_OPT_UINT8("cacheex_allow_filter" , OFS(cacheex.allow_filter), 1),
997 #ifdef CS_CACHEEX_AIO
998 DEF_OPT_UINT8("cacheex_allow_maxhop" , OFS(cacheex.allow_maxhop), 0),
999 #endif
1000 DEF_OPT_UINT8("cacheex_block_fakecws" , OFS(cacheex.block_fakecws), 0),
1001 #ifdef CS_CACHEEX_AIO
1002 DEF_OPT_UINT8("cacheex_cw_check_for_push" , OFS(cacheex.cw_check_for_push), 0),
1003 DEF_OPT_UINT8("cacheex_lg_only_remote_settings", OFS(cacheex.lg_only_remote_settings), 1),
1004 DEF_OPT_UINT8("cacheex_localgenerated_only" , OFS(cacheex.localgenerated_only), 0),
1005 DEF_OPT_FUNC("cacheex_localgenerated_only_caid", OFS(cacheex.localgenerated_only_caidtab), check_caidtab_fn),
1006 DEF_OPT_FUNC_X("cacheex_lg_only_tab" , OFS(cacheex.lg_only_tab), ftab_fn, FTAB_ACCOUNT),
1007 DEF_OPT_UINT8("cacheex_lg_only_in_aio_only" , OFS(cacheex.lg_only_in_aio_only), 0),
1008 DEF_OPT_UINT8("cacheex_localgenerated_only_in", OFS(cacheex.localgenerated_only_in), 0),
1009 DEF_OPT_FUNC("cacheex_localgenerated_only_in_caid", OFS(cacheex.localgenerated_only_in_caidtab), check_caidtab_fn),
1010 DEF_OPT_FUNC_X("cacheex_lg_only_in_tab" , OFS(cacheex.lg_only_in_tab), ftab_fn, FTAB_ACCOUNT),
1011 DEF_OPT_FUNC("cacheex_nopushafter" , OFS(cacheex.cacheex_nopushafter_tab), caidvaluetab_fn),
1012 #endif
1013 #endif
1014 DEF_OPT_FUNC("caid" , OFS(ctab), reader_caid_fn),
1015 DEF_OPT_FUNC("atr" , 0, atr_fn),
1016 DEF_OPT_FUNC("boxid" , 0, boxid_fn),
1017 DEF_OPT_FUNC("boxkey" , 0, boxkey_fn),
1018 DEF_OPT_FUNC("rsakey" , 0, rsakey_fn),
1019 DEF_OPT_FUNC("cwpkkey" , 0, cwpkkey_fn),
1020 DEF_OPT_FUNC("deskey" , 0, deskey_fn),
1021 #ifdef READER_NAGRA_MERLIN
1022 DEF_OPT_FUNC_X("mod1" , OFS(mod1), param_fn, SIZEOF(mod1) ^ (OFS(mod1_length) - OFS(mod1)) << 8),
1023 DEF_OPT_FUNC_X("idird" , OFS(idird), param_fn, SIZEOF(idird) ^ (OFS(idird_length) - OFS(idird)) << 8),
1024 DEF_OPT_FUNC_X("cmd0eprov" , OFS(cmd0eprov), param_fn, SIZEOF(cmd0eprov) ^ (OFS(cmd0eprov_length) - OFS(cmd0eprov)) << 8),
1025 DEF_OPT_FUNC_X("mod2" , OFS(mod2), param_fn, SIZEOF(mod2) ^ (OFS(mod2_length) - OFS(mod2)) << 8),
1026 DEF_OPT_FUNC_X("key3588" , OFS(key3588), param_fn, SIZEOF(key3588) ^ (OFS(key3588_length) - OFS(key3588)) << 8),
1027 DEF_OPT_FUNC_X("key3460" , OFS(key3460), param_fn, SIZEOF(key3460) ^ (OFS(key3460_length) - OFS(key3460)) << 8),
1028 DEF_OPT_FUNC_X("key3310" , OFS(key3310), param_fn, SIZEOF(key3310) ^ (OFS(key3310_length) - OFS(key3310)) << 8),
1029 DEF_OPT_FUNC_X("data50" , OFS(data50), param_fn, SIZEOF(data50) ^ (OFS(data50_length) - OFS(data50)) << 8),
1030 DEF_OPT_FUNC_X("mod50" , OFS(mod50), param_fn, SIZEOF(mod50) ^ (OFS(mod50_length) - OFS(mod50)) << 8),
1031 DEF_OPT_FUNC_X("nuid" , OFS(nuid), param_fn, SIZEOF(nuid) ^ (OFS(nuid_length) - OFS(nuid)) << 8),
1032 DEF_OPT_FUNC_X("forcepair" , OFS(forcepair), param_fn, SIZEOF(forcepair) ^ (OFS(forcepair_length) - OFS(forcepair)) << 8),
1033 DEF_OPT_FUNC_X("otpcsc" , OFS(otpcsc), param_fn, SIZEOF(otpcsc) ^ (OFS(otpcsc_length) - OFS(otpcsc)) << 8),
1034 DEF_OPT_FUNC_X("otacsc" , OFS(otacsc), param_fn, SIZEOF(otacsc) ^ (OFS(otacsc_length) - OFS(otacsc)) << 8),
1035 DEF_OPT_FUNC_X("cwpkcaid" , OFS(cwpkcaid), param_fn, SIZEOF(cwpkcaid) ^ (OFS(cwpkcaid_length) - OFS(cwpkcaid)) << 8),
1036 DEF_OPT_FUNC_X("cwekey0" , OFS(cwekey[0]), param_fn, SIZEOF(cwekey[0]) ^ (OFS(cwekey_length[0]) - OFS(cwekey[0])) << 8),
1037 DEF_OPT_FUNC_X("cwekey1" , OFS(cwekey[1]), param_fn, SIZEOF(cwekey[1]) ^ (OFS(cwekey_length[1]) - OFS(cwekey[1])) << 8),
1038 DEF_OPT_FUNC_X("cwekey2" , OFS(cwekey[2]), param_fn, SIZEOF(cwekey[2]) ^ (OFS(cwekey_length[2]) - OFS(cwekey[2])) << 8),
1039 DEF_OPT_FUNC_X("cwekey3" , OFS(cwekey[3]), param_fn, SIZEOF(cwekey[3]) ^ (OFS(cwekey_length[3]) - OFS(cwekey[3])) << 8),
1040 DEF_OPT_FUNC_X("cwekey4" , OFS(cwekey[4]), param_fn, SIZEOF(cwekey[4]) ^ (OFS(cwekey_length[4]) - OFS(cwekey[4])) << 8),
1041 DEF_OPT_FUNC_X("cwekey5" , OFS(cwekey[5]), param_fn, SIZEOF(cwekey[5]) ^ (OFS(cwekey_length[5]) - OFS(cwekey[5])) << 8),
1042 DEF_OPT_FUNC_X("cwekey6" , OFS(cwekey[6]), param_fn, SIZEOF(cwekey[6]) ^ (OFS(cwekey_length[6]) - OFS(cwekey[6])) << 8),
1043 DEF_OPT_FUNC_X("cwekey7" , OFS(cwekey[7]), param_fn, SIZEOF(cwekey[7]) ^ (OFS(cwekey_length[7]) - OFS(cwekey[7])) << 8),
1044 DEF_OPT_INT8("forcecwswap" , OFS(forcecwswap), 0),
1045 DEF_OPT_INT8("evensa" , OFS(evensa), 0),
1046 DEF_OPT_INT8("forceemmg" , OFS(forceemmg), 0),
1047 DEF_OPT_INT8("cwpkota" , OFS(cwpkota), 0),
1048 #endif
1049 #if defined(READER_NAGRA)
1050 DEF_OPT_FUNC_X("cak63nuid" , OFS(cak63nuid), param_fn, SIZEOF(cak63nuid) ^ (OFS(cak63nuid_length) - OFS(cak63nuid)) << 8),
1051 DEF_OPT_FUNC_X("cak63cwekey" , OFS(cak63cwekey), param_fn, SIZEOF(cak63cwekey) ^ (OFS(cak63cwekey_length) - OFS(cak63cwekey)) << 8),
1052 #endif
1054 DEF_OPT_INT8("cak7_mode" , OFS(cak7_mode), 0),
1055 DEF_OPT_FUNC_X("ins7e" , OFS(ins7E), ins7E_fn, SIZEOF(ins7E)),
1056 DEF_OPT_FUNC_X("ins42" , OFS(ins42), ins42_fn, SIZEOF(ins42)),
1057 DEF_OPT_FUNC_X("ins7e11" , OFS(ins7E11), ins7E_fn, SIZEOF(ins7E11)),
1058 DEF_OPT_FUNC_X("ins2e06" , OFS(ins2e06), ins7E_fn, SIZEOF(ins2e06)),
1059 DEF_OPT_FUNC("k1_generic" , OFS(k1_generic), des_and_3des_key_fn),
1060 DEF_OPT_FUNC("k1_unique" , OFS(k1_unique), des_and_3des_key_fn),
1061 DEF_OPT_INT8("fix07" , OFS(fix_07), 1),
1062 DEF_OPT_INT8("fix9993" , OFS(fix_9993), 0),
1063 DEF_OPT_INT8("readtiers" , OFS(readtiers), 1),
1064 DEF_OPT_INT8("force_irdeto" , OFS(force_irdeto), 0),
1065 DEF_OPT_INT8("needsemmfirst" , OFS(needsemmfirst), 0),
1066 #ifdef READER_CRYPTOWORKS
1067 DEF_OPT_INT8("needsglobalfirst" , OFS(needsglobalfirst), 0),
1068 #endif
1069 DEF_OPT_UINT32("ecmnotfoundlimit" , OFS(ecmnotfoundlimit), 0),
1070 DEF_OPT_FUNC("ecmwhitelist" , 0, ecmwhitelist_fn),
1071 DEF_OPT_FUNC("ecmheaderwhitelist" , 0, ecmheaderwhitelist_fn),
1072 DEF_OPT_FUNC("detect" , 0, detect_fn),
1073 DEF_OPT_INT8("nagra_read" , OFS(nagra_read), 0),
1074 DEF_OPT_INT8("detect_seca_nagra_tunneled_card", OFS(detect_seca_nagra_tunneled_card), 1),
1075 DEF_OPT_INT32("mhz" , OFS(mhz), 357),
1076 DEF_OPT_INT32("cardmhz" , OFS(cardmhz), 357),
1077 #ifdef WITH_AZBOX
1078 DEF_OPT_INT32("mode" , OFS(azbox_mode), -1),
1079 #endif
1080 DEF_OPT_FUNC_X("ident" , OFS(ftab), ftab_fn, FTAB_READER | FTAB_PROVID),
1081 DEF_OPT_FUNC_X("chid" , OFS(fchid), ftab_fn, FTAB_READER | FTAB_CHID),
1082 DEF_OPT_FUNC("class" , OFS(cltab), class_fn),
1083 DEF_OPT_FUNC("aeskeys" , 0, aeskeys_fn),
1084 DEF_OPT_FUNC("group" , OFS(grp), group_fn),
1085 DEF_OPT_FUNC("emmcache" , 0, emmcache_fn),
1086 DEF_OPT_FUNC_X("blockemm-unknown" , OFS(blockemm), flags_fn, EMM_UNKNOWN),
1087 DEF_OPT_FUNC_X("blockemm-u" , OFS(blockemm), flags_fn, EMM_UNIQUE),
1088 DEF_OPT_FUNC_X("blockemm-s" , OFS(blockemm), flags_fn, EMM_SHARED),
1089 DEF_OPT_FUNC_X("blockemm-g" , OFS(blockemm), flags_fn, EMM_GLOBAL),
1090 DEF_OPT_FUNC_X("saveemm-unknown" , OFS(saveemm), flags_fn, EMM_UNKNOWN),
1091 DEF_OPT_FUNC_X("saveemm-u" , OFS(saveemm), flags_fn, EMM_UNIQUE),
1092 DEF_OPT_FUNC_X("saveemm-s" , OFS(saveemm), flags_fn, EMM_SHARED),
1093 DEF_OPT_FUNC_X("saveemm-g" , OFS(saveemm), flags_fn, EMM_GLOBAL),
1094 DEF_OPT_FUNC("blockemm-bylen" , 0, blockemm_bylen_fn),
1095 #ifdef WITH_LB
1096 DEF_OPT_INT32("lb_weight" , OFS(lb_weight), 100),
1097 DEF_OPT_INT8("lb_force_fallback" , OFS(lb_force_fallback), 0),
1098 #endif
1099 DEF_OPT_FUNC("savenano" , OFS(s_nano), nano_fn),
1100 DEF_OPT_FUNC("blocknano" , OFS(b_nano), nano_fn),
1101 DEF_OPT_INT8("dropbadcws" , OFS(dropbadcws), 0),
1102 DEF_OPT_INT8("disablecrccws" , OFS(disablecrccws), 0),
1103 DEF_OPT_INT32("use_gpio" , OFS(use_gpio), 0),
1104 #ifdef MODULE_PANDORA
1105 DEF_OPT_UINT8("pand_send_ecm" , OFS(pand_send_ecm), 0),
1106 #endif
1107 #ifdef MODULE_CCCAM
1108 DEF_OPT_SSTR("cccversion" , OFS(cc_version), "", SIZEOF(cc_version)),
1109 DEF_OPT_INT8("cccmaxhops" , OFS(cc_maxhops), DEFAULT_CC_MAXHOPS),
1110 DEF_OPT_INT8("cccmindown" , OFS(cc_mindown), 0),
1111 DEF_OPT_INT8("cccwantemu" , OFS(cc_want_emu), 0),
1112 DEF_OPT_INT8("ccckeepalive" , OFS(cc_keepalive), DEFAULT_CC_KEEPALIVE),
1113 DEF_OPT_INT8("cccreshare" , OFS(cc_reshare), DEFAULT_CC_RESHARE),
1114 DEF_OPT_INT32("cccreconnect" , OFS(cc_reconnect), DEFAULT_CC_RECONNECT),
1115 DEF_OPT_INT8("ccchop" , OFS(cc_hop), 0),
1116 #endif
1117 #ifdef MODULE_GHTTP
1118 DEF_OPT_UINT8("use_ssl" , OFS(ghttp_use_ssl), 0),
1119 #endif
1120 #if defined(READER_DRE) || defined(READER_DRECAS)
1121 DEF_OPT_HEX("force_ua" , OFS(force_ua), 4),
1122 DEF_OPT_STR("exec_cmd_file" , OFS(userscript), NULL),
1123 #endif
1124 #ifdef READER_DRECAS
1125 DEF_OPT_STR("stmkeys" , OFS(stmkeys), NULL),
1126 #endif
1127 #ifdef WITH_EMU
1128 DEF_OPT_FUNC_X("emu_auproviders" , OFS(emu_auproviders), ftab_fn, FTAB_READER | FTAB_EMUAU),
1129 DEF_OPT_INT8("emu_datecodedenabled" , OFS(emu_datecodedenabled), 0),
1130 #endif
1131 DEF_OPT_INT8("deprecated" , OFS(deprecated), 0),
1132 DEF_OPT_INT8("audisabled" , OFS(audisabled), 0),
1133 DEF_OPT_INT8("autype" , OFS(autype), 0),
1134 DEF_OPT_FUNC("auprovid" , 0, auprovid_fn),
1135 DEF_OPT_INT8("ndsversion" , OFS(ndsversion), 0),
1136 DEF_OPT_FUNC("ratelimitecm" , 0, ratelimitecm_fn),
1137 DEF_OPT_FUNC("ecmunique" , 0, ecmunique_fn),
1138 DEF_OPT_FUNC("ratelimittime" , 0, ratelimittime_fn),
1139 DEF_OPT_FUNC("srvidholdtime" , 0, srvidholdtime_fn),
1140 DEF_OPT_FUNC("cooldown" , 0, cooldown_fn),
1141 DEF_OPT_FUNC("cooldowndelay" , 0, cooldowndelay_fn),
1142 DEF_OPT_FUNC("cooldowntime" , 0, cooldowntime_fn),
1143 DEF_OPT_UINT8("read_old_classes" , OFS(read_old_classes), 1),
1144 DEF_LAST_OPT
1147 static inline bool in_list(const char *token, const char *list[])
1149 int i;
1150 for(i = 0; list[i]; i++)
1152 if(streq(token, list[i]))
1153 { return true; }
1155 return false;
1158 static bool reader_check_setting(const struct config_list *UNUSED(clist), void *config_data, const char *setting)
1160 struct s_reader *reader = config_data;
1161 // These are written only when the reader is physical reader
1162 static const char *hw_only_settings[] =
1164 "readnano", "resetcycle", "smargopatch", "autospeed", "sc8in1_dtrrts_patch", "boxid","fix07",
1165 "fix9993", "rsakey", "deskey", "ins7e", "ins42", "ins7e11", "ins2e06", "k1_generic", "k1_unique", "force_irdeto", "needsemmfirst", "boxkey",
1166 "atr", "detect", "nagra_read", "mhz", "cardmhz", "readtiers", "read_old_classes", "use_gpio", "needsglobalfirst",
1167 #ifdef READER_NAGRA_MERLIN
1168 "mod1", "idird", "cmd0eprov", "mod2", "key3588", "key3460", "key3310", "data50", "mod50", "nuid", "forcepair", "otpcsc", "otacsc", "cwpkcaid", "cwekey0", "cwekey1", "cwekey2", "cwekey3", "cwekey4", "cwekey5", "cwekey6", "cwekey7",
1169 #endif
1170 #if defined(READER_NAGRA)
1171 "cak63nuid", "cak63cwekey",
1172 #endif
1173 #if defined(READER_DRE) || defined(READER_DRECAS)
1174 "exec_cmd_file",
1175 #endif
1176 #ifdef READER_CONAX
1177 "cwpkkey",
1178 #endif
1179 #ifdef WITH_AZBOX
1180 "mode",
1181 #endif
1182 "deprecated", "ndsversion",
1185 // These are written only when the reader is network reader
1186 static const char *network_only_settings[] =
1188 "user", "inactivitytimeout", "reconnecttimeout", "autype",
1191 if(is_network_reader(reader))
1193 if(in_list(setting, hw_only_settings))
1194 { return false; }
1196 else
1198 if(in_list(setting, network_only_settings))
1199 { return false; }
1202 // These are not written in the config file
1203 static const char *deprecated_settings[] =
1205 "cooldowndelay", "cooldowntime",
1208 if(in_list(setting, deprecated_settings))
1209 { return false; }
1211 // Special settings for NEWCAMD
1212 static const char *newcamd_settings[] =
1214 "disableserverfilter", "connectoninit",
1217 if(reader->typ != R_NEWCAMD && in_list(setting, newcamd_settings))
1218 { return false; }
1219 #ifdef MODULE_CCCAM
1220 // These are written only when the reader is CCCAM
1221 static const char *cccam_settings[] =
1223 "cccversion", "cccmaxhops", "cccmindown", "cccwantemu", "ccckeepalive",
1224 "cccreconnect",
1227 // Special settings for CCCAM
1228 if(reader->typ != R_CCCAM)
1230 if(in_list(setting, cccam_settings))
1231 { return false; }
1233 else if(streq(setting, "ccchop"))
1235 return false;
1237 #endif
1239 #ifdef MODULE_PANDORA
1240 // Special settings for PANDORA
1241 if(reader->typ != R_PANDORA && streq(setting, "pand_send_ecm"))
1242 { return false; }
1243 #endif
1245 #ifdef MODULE_GBOX
1246 // These are written only when the reader is GBOX
1247 static const char *gbox_settings[] =
1249 "gbox_max_distance", "gbox_max_ecm_send", "gbox_reshare", "cccam_reshare", "force_remm","ccc_gbx_reshare_ident","send_offline_cmd",
1252 if(reader->typ != R_GBOX)
1254 if(in_list(setting, gbox_settings))
1255 { return false; }
1257 #endif
1259 return true; // Write the setting
1262 void chk_reader(char *token, char *value, struct s_reader *rdr)
1264 if(config_list_parse(reader_opts, token, value, rdr))
1265 { return; }
1266 else if(token[0] != '#')
1267 { fprintf(stderr, "Warning: keyword '%s' in reader section not recognized\n", token); }
1270 void reader_set_defaults(struct s_reader *rdr)
1272 config_list_set_defaults(reader_opts, rdr);
1275 int32_t init_readerdb(void)
1277 configured_readers = ll_create("configured_readers");
1279 FILE *fp = open_config_file(cs_srvr);
1280 if(!fp)
1281 { return 1; }
1283 int32_t tag = 0;
1284 char *value, *token;
1286 if(!cs_malloc(&token, MAXLINESIZE))
1287 { return 1; }
1289 struct s_reader *rdr;
1290 if(!cs_malloc(&rdr, sizeof(struct s_reader)))
1292 NULLFREE(token);
1293 return 1;
1296 ll_append(configured_readers, rdr);
1297 while(fgets(token, MAXLINESIZE, fp))
1299 int32_t l;
1300 if((l = cs_strlen(trim(token))) < 3)
1301 { continue; }
1302 if((token[0] == '[') && (token[l - 1] == ']'))
1304 token[l - 1] = 0;
1305 tag = (!strcmp("reader", strtolower(token + 1)));
1306 if(rdr->label[0] && rdr->typ)
1308 struct s_reader *newreader;
1309 if(cs_malloc(&newreader, sizeof(struct s_reader)))
1311 ll_append(configured_readers, newreader);
1312 rdr = newreader;
1315 reader_set_defaults(rdr);
1316 continue;
1319 if(!tag)
1320 { continue; }
1321 if(!(value = strchr(token, '=')))
1322 { continue; }
1323 *value++ = '\0';
1324 chk_reader(trim(strtolower(token)), trim(value), rdr);
1326 NULLFREE(token);
1327 LL_ITER itr = ll_iter_create(configured_readers);
1328 while((rdr = ll_iter_next(&itr))) // build active readers list
1330 reader_fixups_fn(rdr);
1331 module_reader_set(rdr);
1333 fclose(fp);
1334 return (0);
1337 void free_reader(struct s_reader *rdr)
1339 NULLFREE(rdr->emmfile);
1341 ecm_whitelist_clear(&rdr->ecm_whitelist);
1342 ecm_hdr_whitelist_clear(&rdr->ecm_hdr_whitelist);
1344 ftab_clear(&rdr->fallback_percaid);
1345 ftab_clear(&rdr->localcards);
1346 ftab_clear(&rdr->fchid);
1347 ftab_clear(&rdr->ftab);
1348 ftab_clear(&rdr->disablecrccws_only_for);
1349 #ifdef MODULE_GBOX
1350 ftab_clear(&rdr->ccc_gbx_reshare_ident);
1351 #endif
1353 NULLFREE(rdr->cltab.aclass);
1354 NULLFREE(rdr->cltab.bclass);
1356 caidtab_clear(&rdr->ctab);
1357 #ifdef CS_CACHEEX
1358 cecspvaluetab_clear(&rdr->cacheex.filter_caidtab);
1359 #ifdef CS_CACHEEX_AIO
1360 caidtab_clear(&rdr->cacheex.localgenerated_only_caidtab);
1361 caidtab_clear(&rdr->cacheex.localgenerated_only_in_caidtab);
1362 ftab_clear(&rdr->cacheex.lg_only_tab);
1363 ftab_clear(&rdr->cacheex.lg_only_in_tab);
1364 caidvaluetab_clear(&rdr->cacheex.cacheex_nopushafter_tab);
1365 #endif
1366 #endif
1367 lb_destroy_stats(rdr);
1369 cs_clear_entitlement(rdr);
1370 ll_destroy(&rdr->ll_entitlements);
1372 if(rdr->csystem && rdr->csystem->card_done)
1373 rdr->csystem->card_done(rdr);
1374 NULLFREE(rdr->csystem_data);
1376 ll_destroy_data(&rdr->blockemmbylen);
1378 ll_destroy_data(&rdr->emmstat);
1380 aes_clear_entries(&rdr->aes_list);
1382 config_list_gc_values(reader_opts, rdr);
1383 add_garbage(rdr);
1386 int32_t free_readerdb(void)
1388 int count = 0;
1389 struct s_reader *rdr;
1390 LL_ITER itr = ll_iter_create(configured_readers);
1391 while((rdr = ll_iter_next(&itr)))
1393 free_reader(rdr);
1394 count++;
1396 cs_log("readerdb %d readers freed", count);
1397 ll_destroy(&configured_readers);
1398 return count;
1401 int32_t write_server(void)
1403 FILE *f = create_config_file(cs_srvr);
1404 if(!f)
1405 { return 1; }
1406 struct s_reader *rdr;
1407 LL_ITER itr = ll_iter_create(configured_readers);
1408 while((rdr = ll_iter_next(&itr)))
1410 if(rdr->label[0])
1412 fprintf(f, "[reader]\n");
1413 config_list_apply_fixups(reader_opts, rdr);
1414 config_list_save_ex(f, reader_opts, rdr, cfg.http_full_cfg, reader_check_setting);
1415 fprintf(f, "\n");
1418 return flush_config_file(f, cs_srvr);
1421 void reload_readerdb(void)
1423 struct s_reader *rdr;
1424 LL_ITER itr = ll_iter_create(configured_readers);
1425 while((rdr = ll_iter_next(&itr)))
1427 // disable the current reader
1428 rdr->enable = 0;
1429 restart_cardreader(rdr,1);
1431 free_readerdb(); // release the old readerdb
1432 init_readerdb(); // reload the new readerdb
1433 init_cardreader(); // start the readers