revert breaks some stupid old compilers
[oscam.git] / oscam-config-reader.c
blob62e7b94d464b7e3d460349fe4d063427fd9bb909
1 #define MODULE_LOG_PREFIX "config"
3 #include "globals.h"
4 #include "module-gbox.h"
5 #include "module-stat.h"
6 #include "oscam-aes.h"
7 #include "oscam-array.h"
8 #include "oscam-conf.h"
9 #include "oscam-conf-chk.h"
10 #include "oscam-conf-mk.h"
11 #include "oscam-config.h"
12 #include "oscam-garbage.h"
13 #include "oscam-lock.h"
14 #include "oscam-reader.h"
15 #include "oscam-string.h"
17 #define cs_srvr "oscam.server"
19 extern const struct s_cardreader *cardreaders[];
20 extern char *RDR_CD_TXT[];
22 static void reader_label_fn(const char *token, char *value, void *setting, FILE *f)
24 struct s_reader *rdr = setting;
25 if(value)
27 int i, found = 0;
28 if(!strlen(value))
29 { return; }
30 for(i = 0; i < (int)strlen(value); i++)
32 if(value[i] == ' ')
34 value[i] = '_';
35 found++;
38 if(found)
39 { fprintf(stderr, "Configuration reader: corrected label to %s\n", value); }
40 cs_strncpy(rdr->label, value, sizeof(rdr->label));
41 return;
43 fprintf_conf(f, token, "%s\n", rdr->label);
46 static void ecmwhitelist_fn(const char *token, char *value, void *setting, FILE *f)
48 struct s_reader *rdr = setting;
49 if(value)
51 if(strlen(value))
52 chk_ecm_whitelist(value, &rdr->ecm_whitelist);
53 else
54 ecm_whitelist_clear(&rdr->ecm_whitelist);
55 return;
58 value = mk_t_ecm_whitelist(&rdr->ecm_whitelist);
59 if(strlen(value) > 0 || cfg.http_full_cfg)
60 { fprintf_conf(f, token, "%s\n", value); }
61 free_mk_t(value);
64 static void ecmheaderwhitelist_fn(const char *token, char *value, void *setting, FILE *f)
66 struct s_reader *rdr = setting;
67 if(value)
69 if(strlen(value))
70 chk_ecm_hdr_whitelist(value, &rdr->ecm_hdr_whitelist);
71 else
72 ecm_hdr_whitelist_clear(&rdr->ecm_hdr_whitelist);
73 return;
76 value = mk_t_ecm_hdr_whitelist(&rdr->ecm_hdr_whitelist);
77 if(strlen(value) > 0 || cfg.http_full_cfg)
78 { fprintf_conf(f, token, "%s\n", value); }
79 free_mk_t(value);
82 static void protocol_fn(const char *token, char *value, void *setting, FILE *f)
84 struct s_reader *rdr = setting;
85 if(value)
87 if(strlen(value) == 0)
88 { return; }
89 struct protocol_map
91 char *name;
92 int typ;
93 } protocols[] =
95 { "serial", R_SERIAL },
96 { "camd35", R_CAMD35 },
97 { "cs378x", R_CS378X },
98 { "cs357x", R_CAMD35 },
99 { "camd33", R_CAMD33 },
100 { "gbox", R_GBOX },
101 { "cccam", R_CCCAM },
102 { "cccam_ext", R_CCCAM },
103 { "cccam_mcs", R_CCCAM },
104 { "constcw", R_CONSTCW },
105 { "radegast", R_RADEGAST },
106 { "scam", R_SCAM },
107 { "ghttp", R_GHTTP },
108 { "newcamd", R_NEWCAMD },
109 { "newcamd525", R_NEWCAMD },
110 { "newcamd524", R_NEWCAMD },
111 { "drecas", R_DRECAS },
112 { NULL , 0 }
113 }, *p;
114 int i;
115 // Parse card readers
116 for(i = 0; cardreaders[i]; i++)
118 if(streq(value, cardreaders[i]->desc))
120 rdr->crdr = cardreaders[i];
121 rdr->typ = cardreaders[i]->typ;
122 return;
125 // Parse protocols
126 for(i = 0, p = &protocols[0]; p->name; p = &protocols[++i])
128 if(streq(p->name, value))
130 rdr->typ = p->typ;
131 break;
134 if(rdr->typ == R_NEWCAMD)
135 { rdr->ncd_proto = streq(value, "newcamd524") ? NCD_524 : NCD_525; }
136 if(!rdr->typ)
138 fprintf(stderr, "ERROR: '%s' is unsupported reader protocol!\n", value);
139 rdr->enable = 0;
141 return;
143 fprintf_conf(f, token, "%s\n", reader_get_type_desc(rdr, 0));
146 static void device_fn(const char *token, char *value, void *setting, FILE *f)
148 struct s_reader *rdr = setting;
149 int32_t isphysical = !is_network_reader(rdr);
150 if(value)
152 int32_t i;
153 char *ptr, *saveptr1 = NULL;
154 for(i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 3) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++)
156 trim(ptr);
157 switch(i)
159 case 0:
160 cs_strncpy(rdr->device, ptr, sizeof(rdr->device));
161 break;
162 case 1:
163 rdr->r_port = atoi(ptr);
164 break;
165 case 2:
166 rdr->l_port = atoi(ptr);
167 break;
170 return;
172 fprintf_conf(f, token, "%s", rdr->device); // it should not have \n at the end
173 if((rdr->r_port || cfg.http_full_cfg) && !isphysical)
174 { fprintf(f, ",%d", rdr->r_port); }
175 if((rdr->l_port || cfg.http_full_cfg) && !isphysical && strncmp(reader_get_type_desc(rdr, 0), "cccam", 5))
176 { fprintf(f, ",%d", rdr->l_port); }
177 fprintf(f, "\n");
180 static void reader_services_fn(const char *token, char *value, void *setting, FILE *f)
182 services_fn(token, value, setting, f);
183 if(value)
185 struct s_reader *rdr = container_of(setting, struct s_reader, sidtabs);
186 if(rdr)
187 { rdr->changes_since_shareupdate = 1; }
191 static void reader_lb_services_fn(const char *token, char *value, void *setting, FILE *f)
193 services_fn(token, value, setting, f);
194 if(value)
196 struct s_reader *rdr = container_of(setting, struct s_reader, lb_sidtabs);
197 if(rdr)
198 { rdr->changes_since_shareupdate = 1; }
202 static void reader_caid_fn(const char *token, char *value, void *setting, FILE *f)
204 check_caidtab_fn(token, value, setting, f);
205 if(value)
207 struct s_reader *rdr = container_of(setting, struct s_reader, ctab);
208 if(rdr)
209 { rdr->changes_since_shareupdate = 1; }
213 static void boxid_fn(const char *token, char *value, void *setting, FILE *f)
215 struct s_reader *rdr = setting;
216 if(value)
218 rdr->boxid = strlen(value) ? a2i(value, 4) : 0;
219 return;
221 if(rdr->boxid)
222 { fprintf_conf(f, token, "%08X\n", rdr->boxid); }
223 else if(cfg.http_full_cfg)
224 { fprintf_conf(f, token, "\n"); }
227 static void rsakey_fn(const char *token, char *value, void *setting, FILE *f)
229 struct s_reader *rdr = setting;
230 if(value)
232 int32_t len = strlen(value);
233 if(len != 128 && len != 240)
235 rdr->rsa_mod_length = 0;
236 memset(rdr->rsa_mod, 0, 120);
238 else
240 if(key_atob_l(value, rdr->rsa_mod, len))
242 fprintf(stderr, "reader rsakey parse error, %s=%s\n", token, value);
243 rdr->rsa_mod_length = 0;
244 memset(rdr->rsa_mod, 0, sizeof(rdr->rsa_mod));
246 else
248 rdr->rsa_mod_length = len/2;
251 return;
253 int32_t len = rdr->rsa_mod_length;
254 if(len > 0)
256 char tmp[len * 2 + 1];
257 fprintf_conf(f, "rsakey", "%s\n", cs_hexdump(0, rdr->rsa_mod, len, tmp, sizeof(tmp)));
259 else if(cfg.http_full_cfg)
260 { fprintf_conf(f, "rsakey", "\n"); }
263 static void deskey_fn(const char *token, char *value, void *setting, FILE *f)
265 struct s_reader *rdr = setting;
266 if(value)
268 int32_t len = strlen(value);
269 if(((len % 16) != 0) || len == 0 || len > 128*2)
271 rdr->des_key_length = 0;
272 memset(rdr->des_key, 0, sizeof(rdr->des_key));
274 else
276 if(key_atob_l(value, rdr->des_key, len))
278 fprintf(stderr, "reader 3DES key parse error, %s=%s\n", token, value);
279 rdr->des_key_length = 0;
280 memset(rdr->des_key, 0, sizeof(rdr->des_key));
282 else
284 rdr->des_key_length = len/2;
287 return;
289 int32_t len = rdr->des_key_length;
290 if(len > 0)
292 char tmp[len * 2 + 1];
293 fprintf_conf(f, "deskey", "%s\n", cs_hexdump(0, rdr->des_key, len, tmp, sizeof(tmp)));
295 else if(cfg.http_full_cfg)
296 { fprintf_conf(f, "deskey", "\n"); }
299 static void boxkey_fn(const char *token, char *value, void *setting, FILE *f)
301 struct s_reader *rdr = setting;
302 if(value)
304 int32_t len = strlen(value);
305 if(((len % 8) != 0) || len == 0 || len > 32)
307 rdr->boxkey_length = 0;
308 memset(rdr->boxkey, 0, sizeof(rdr->boxkey));
310 else
312 if(key_atob_l(value, rdr->boxkey, len))
314 fprintf(stderr, "reader boxkey parse error, %s=%s\n", token, value);
315 rdr->boxkey_length = 0;
316 memset(rdr->boxkey, 0, sizeof(rdr->boxkey));
318 else
320 rdr->boxkey_length = len/2;
323 return;
325 int32_t len = rdr->boxkey_length;
326 if(len > 0)
328 char tmp[len * 2 + 1];
329 fprintf_conf(f, "boxkey", "%s\n", cs_hexdump(0, rdr->boxkey, len, tmp, sizeof(tmp)));
331 else if(cfg.http_full_cfg)
332 { fprintf_conf(f, "boxkey", "\n"); }
335 static void flags_fn(const char *token, char *value, void *setting, long flag, FILE *f)
337 uint32_t *var = setting;
338 if(value)
340 int i = atoi(value);
341 if(!i && (*var & flag))
342 { *var -= flag; }
343 if(i)
344 { *var |= flag; }
345 return;
347 if((*var & flag) || cfg.http_full_cfg)
348 { fprintf_conf(f, token, "%d\n", (*var & flag) ? 1 : 0); }
351 static void ins7E_fn(const char *token, char *value, void *setting, long var_size, FILE *f)
353 uint8_t *var = setting;
354 var_size -= 1; // var_size contains sizeof(var) which is [X + 1]
355 if(value)
357 int32_t len = strlen(value);
358 if(len != var_size * 2 || key_atob_l(value, var, len))
360 if(len > 0)
361 { fprintf(stderr, "reader %s parse error, %s=%s\n", token, token, value); }
362 memset(var, 0, var_size + 1);
364 else
366 var[var_size] = 1; // found and correct
368 return;
370 if(var[var_size])
372 char tmp[var_size * 2 + 1];
373 fprintf_conf(f, token, "%s\n", cs_hexdump(0, var, var_size, tmp, sizeof(tmp)));
375 else if(cfg.http_full_cfg)
376 { fprintf_conf(f, token, "\n"); }
379 static void atr_fn(const char *token, char *value, void *setting, FILE *f)
381 struct s_reader *rdr = setting;
382 if(value)
384 memset(rdr->atr, 0, sizeof(rdr->atr));
385 rdr->atrlen = strlen(value);
386 if(rdr->atrlen)
388 if(rdr->atrlen > (int32_t)sizeof(rdr->atr) * 2)
389 { rdr->atrlen = (int32_t)sizeof(rdr->atr) * 2; }
390 key_atob_l(value, rdr->atr, rdr->atrlen);
392 return;
394 if(rdr->atr[0] || cfg.http_full_cfg)
396 int j;
397 fprintf_conf(f, token, "%s", ""); // it should not have \n at the end
398 if(rdr->atr[0])
400 for(j = 0; j < rdr->atrlen / 2; j++)
402 fprintf(f, "%02X", rdr->atr[j]);
405 fprintf(f, "\n");
409 static void detect_fn(const char *token, char *value, void *setting, FILE *f)
411 struct s_reader *rdr = setting;
412 if(value)
414 int i;
415 for(i = 0; RDR_CD_TXT[i]; i++)
417 if(!strcmp(value, RDR_CD_TXT[i]))
419 rdr->detect = i;
421 else
423 if(value[0] == '!' && streq(value + 1, RDR_CD_TXT[i]))
424 { rdr->detect = i | 0x80; }
427 return;
429 fprintf_conf(f, token, "%s%s\n", rdr->detect & 0x80 ? "!" : "", RDR_CD_TXT[rdr->detect & 0x7f]);
432 void ftab_fn(const char *token, char *value, void *setting, long ftab_type, FILE *f)
434 FTAB *ftab = setting;
435 if(value)
437 if(strlen(value))
438 chk_ftab(value, ftab);
439 else
440 ftab_clear(ftab);
441 return;
443 if(ftab_type & FTAB_READER)
445 struct s_reader *rdr = NULL;
446 if(ftab_type & FTAB_PROVID) { rdr = container_of(setting, struct s_reader, ftab); }
447 if(ftab_type & FTAB_CHID) { rdr = container_of(setting, struct s_reader, fchid); }
448 if(ftab_type & FTAB_FBPCAID) { rdr = container_of(setting, struct s_reader, fallback_percaid); }
449 if(ftab_type & FTAB_LOCALCARDS) { rdr = container_of(setting, struct s_reader, localcards); }
450 if(ftab_type & FTAB_IGNCHKSMCAID){ rdr = container_of(setting, struct s_reader, disablecrccws_only_for); }
451 if(rdr)
452 { rdr->changes_since_shareupdate = 1; }
454 value = mk_t_ftab(ftab);
455 if(strlen(value) > 0 || cfg.http_full_cfg)
456 { fprintf_conf(f, token, "%s\n", value); }
457 free_mk_t(value);
460 static void aeskeys_fn(const char *token, char *value, void *setting, FILE *f)
462 struct s_reader *rdr = setting;
463 if(value)
465 parse_aes_keys(rdr, value);
466 return;
468 value = mk_t_aeskeys(rdr);
469 if(strlen(value) > 0 || cfg.http_full_cfg)
470 { fprintf_conf(f, token, "%s\n", value); }
471 free_mk_t(value);
474 static void emmcache_fn(const char *token, char *value, void *setting, FILE *f)
476 struct s_reader *rdr = setting;
477 if(value)
479 rdr->cachemm = 0;
480 rdr->rewritemm = 0;
481 rdr->logemm = 0;
482 rdr->deviceemm = 0;
483 if(strlen(value))
485 int i;
486 char *ptr, *saveptr1 = NULL;
487 for(i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 4) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++)
489 switch(i)
491 case 0:
492 rdr->cachemm = atoi(ptr);
493 break;
494 case 1:
495 rdr->rewritemm = atoi(ptr);
496 break;
497 case 2:
498 rdr->logemm = atoi(ptr);
499 break;
500 case 3:
501 rdr->deviceemm = atoi(ptr);
504 if(rdr->rewritemm <= 0)
506 fprintf(stderr, "Setting reader \"emmcache\" to %i,%d,%i,%i instead of %i,%i,%i,%i.",
507 rdr->cachemm, 1, rdr->logemm, rdr->deviceemm,
508 rdr->cachemm, rdr->rewritemm, rdr->logemm, rdr->deviceemm);
509 fprintf(stderr, "Zero or negative number of rewrites is silly\n");
510 rdr->rewritemm = 1;
513 return;
515 if(rdr->cachemm || rdr->logemm || cfg.http_full_cfg)
516 { fprintf_conf(f, token, "%d,%d,%d,%d\n", rdr->cachemm, rdr->rewritemm, rdr->logemm,rdr->deviceemm); }
519 static void blockemm_bylen_fn(const char *token, char *value, void *setting, FILE *f)
521 struct s_reader *rdr = setting;
522 if(value)
524 char *ptr, *saveptr1 = NULL, dash;
525 struct s_emmlen_range *blocklen;
526 uint32_t num;
528 if(!strlen(value))
530 ll_destroy_data(&rdr->blockemmbylen);
531 return;
534 if(!rdr->blockemmbylen)
535 { rdr->blockemmbylen = ll_create("blockemmbylen"); }
536 else
537 { ll_clear_data(rdr->blockemmbylen); }
539 for(ptr = strtok_r(value, ",", &saveptr1); ptr;
540 ptr = strtok_r(NULL, ",", &saveptr1))
542 if(!cs_malloc(&blocklen, sizeof(*blocklen)))
543 { return; }
544 num = sscanf(ptr, "%hd%c%hd", &blocklen->min, &dash, &blocklen->max);
545 if(num <= 0)
547 NULLFREE(blocklen);
548 fprintf(stderr, "blockemm-bylen parse error: %s\n", value);
549 continue;
551 if(num == 1) // single values: x1,x2,x3,...
552 { blocklen->max = blocklen->min; }
553 else if(num == 2) // range values with open end: x1-
554 { blocklen->max = 0; }
555 ll_append(rdr->blockemmbylen, blocklen);
557 return;
559 value = mk_t_emmbylen(rdr);
560 if(strlen(value) > 0 || cfg.http_full_cfg)
561 { fprintf_conf(f, token, "%s\n", value); }
562 free_mk_t(value);
565 static void nano_fn(const char *token, char *value, void *setting, FILE *f)
567 uint16_t *nano = setting;
568 if(value)
570 *nano = 0;
571 if(strlen(value) > 0)
573 if(streq(value, "all"))
575 *nano = 0xFFFF;
577 else
579 int32_t i;
580 char *ptr, *saveptr1 = NULL;
581 for(ptr = strtok_r(value, ",", &saveptr1); ptr; ptr = strtok_r(NULL, ",", &saveptr1))
583 i = (byte_atob(ptr) % 0x80);
584 if(i >= 0 && i <= 16)
585 { *nano |= (1 << i); }
589 return;
591 value = mk_t_nano(*nano);
592 if(strlen(value) > 0 || cfg.http_full_cfg)
593 { fprintf_conf(f, token, "%s\n", value); }
594 free_mk_t(value);
597 static void auprovid_fn(const char *token, char *value, void *setting, FILE *f)
599 struct s_reader *rdr = setting;
600 if(value)
602 rdr->auprovid = 0;
603 if(strlen(value))
604 { rdr->auprovid = a2i(value, 3); }
605 return;
607 if(rdr->auprovid)
608 { fprintf_conf(f, token, "%06X\n", rdr->auprovid); }
609 else if(cfg.http_full_cfg)
610 { fprintf_conf(f, token, "\n"); }
613 static void ratelimitecm_fn(const char *token, char *value, void *setting, FILE *f)
615 struct s_reader *rdr = setting;
616 if(value)
618 rdr->ratelimitecm = 0;
619 if(strlen(value))
621 int i;
622 rdr->ratelimitecm = atoi(value);
623 for(i = 0; i < MAXECMRATELIMIT; i++) // reset all slots
625 rdr->rlecmh[i].srvid = -1;
626 rdr->rlecmh[i].last.time = -1;
629 return;
631 if(rdr->ratelimitecm || cfg.http_full_cfg)
632 { fprintf_conf(f, token, "%d\n", rdr->ratelimitecm); }
635 static void ecmunique_fn(const char *token, char *value, void *setting, FILE *f)
637 struct s_reader *rdr = setting;
638 if(value)
640 if(strlen(value) == 0)
642 rdr->ecmunique = 0; // default
644 else
646 rdr->ecmunique = atoi(value);
647 if(rdr->ecmunique >= 1)
648 { rdr->ecmunique=1; }
649 else
650 { rdr->ecmunique=0; }
652 return;
654 if((rdr->ratelimitecm && rdr->ecmunique!=0) || cfg.http_full_cfg)
655 { fprintf_conf(f, token, "%d\n", rdr->ecmunique); }
658 static void ratelimittime_fn(const char *token, char *value, void *setting, FILE *f)
660 struct s_reader *rdr = setting;
661 if(value)
663 if(strlen(value) == 0)
665 if(rdr->ratelimitecm > 0)
667 rdr->ratelimittime = 9000; // default 9 seconds
668 rdr->srvidholdtime = 2000; // default 2 seconds hold
670 else
672 rdr->ratelimitecm = 0; // in case someone set a negative value
673 rdr->ratelimittime = 0;
674 rdr->srvidholdtime = 0;
677 else
679 rdr->ratelimittime = atoi(value);
680 if (rdr->ratelimittime < 60) rdr->ratelimittime *=1000;
682 return;
684 if(rdr->ratelimitecm || cfg.http_full_cfg)
685 { fprintf_conf(f, token, "%d\n", rdr->ratelimittime); }
688 static void srvidholdtime_fn(const char *token, char *value, void *setting, FILE *f)
690 struct s_reader *rdr = setting;
691 if(value)
693 if(strlen(value) == 0)
695 if(rdr->ratelimitecm > 0)
697 rdr->srvidholdtime = 2000; // default 2 seconds hold
699 else
701 rdr->ratelimitecm = 0; // in case someone set a negative value
702 rdr->srvidholdtime = 0;
705 else
707 rdr->srvidholdtime = atoi(value);
708 if (rdr->srvidholdtime < 60) rdr->srvidholdtime *=1000;
710 return;
712 if(rdr->ratelimitecm || cfg.http_full_cfg)
713 { fprintf_conf(f, token, "%d\n", rdr->srvidholdtime); }
716 static void cooldown_fn(const char *token, char *value, void *setting, FILE *f)
718 struct s_reader *rdr = setting;
719 if(value)
721 if(strlen(value) == 0)
723 rdr->cooldown[0] = 0;
724 rdr->cooldown[1] = 0;
726 else
728 int32_t i;
729 char *ptr, *saveptr1 = NULL;
730 for(i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 2) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++)
732 rdr->cooldown[i] = atoi(ptr);
734 if(rdr->cooldown[0] <= 0 || rdr->cooldown[1] <= 0)
736 fprintf(stderr, "cooldown must have 2 positive values (x,y) set values %d,%d ! cooldown deactivated\n",
737 rdr->cooldown[0], rdr->cooldown[1]);
738 rdr->cooldown[0] = 0;
739 rdr->cooldown[1] = 0;
742 return;
744 if(rdr->cooldown[0] || cfg.http_full_cfg)
746 fprintf_conf(f, token, "%d,%d\n", rdr->cooldown[0], rdr->cooldown[1]);
750 static void cooldowndelay_fn(const char *UNUSED(token), char *value, void *setting, FILE *UNUSED(f))
752 struct s_reader *rdr = setting;
753 if(value)
755 rdr->cooldown[0] = strlen(value) ? atoi(value) : 0;
757 // This option is *not* written in the config file.
758 // It is only set by WebIf as convenience
761 static void cooldowntime_fn(const char *UNUSED(token), char *value, void *setting, FILE *UNUSED(f))
763 struct s_reader *rdr = setting;
764 if(value)
766 if(strlen(value) == 0)
768 rdr->cooldown[0] = 0; // no cooling down time means no cooling set
769 rdr->cooldown[1] = 0;
771 else
773 rdr->cooldown[1] = atoi(value);
775 return;
777 // This option is *not* written in the config file.
778 // It is only set by WebIf as convenience
782 static void reader_fixups_fn(void *var)
784 struct s_reader *rdr = var;
785 #ifdef WITH_LB
786 if(rdr->lb_weight > 1000)
787 { rdr->lb_weight = 1000; }
788 else if(rdr->lb_weight <= 0)
789 { rdr->lb_weight = 100; }
790 #endif
792 if(is_cascading_reader(rdr) && (rdr->typ == R_CAMD35 || rdr->typ == R_CS378X))
794 #ifdef CS_CACHEEX
795 if(rdr && rdr->cacheex.mode>1)
796 { rdr->keepalive = 1; } //with cacheex, it is required!
797 else
798 #endif
799 if(rdr->typ == R_CAMD35)
800 { rdr->keepalive = 0; } //with NO-cacheex, and UDP, keepalive is not required!
805 #define OFS(X) offsetof(struct s_reader, X)
806 #define SIZEOF(X) sizeof(((struct s_reader *)0)->X)
808 static const struct config_list reader_opts[] =
810 DEF_OPT_FIXUP_FUNC(reader_fixups_fn),
811 DEF_OPT_FUNC("label" , 0, reader_label_fn),
812 #ifdef WEBIF
813 DEF_OPT_STR("description" , OFS(description), NULL),
814 #endif
815 DEF_OPT_INT8("enable" , OFS(enable), 1),
816 DEF_OPT_FUNC("protocol" , 0, protocol_fn),
817 DEF_OPT_FUNC("device" , 0, device_fn),
818 DEF_OPT_HEX("key" , OFS(ncd_key), SIZEOF(ncd_key)),
819 DEF_OPT_SSTR("user" , OFS(r_usr), "", SIZEOF(r_usr)),
820 DEF_OPT_SSTR("password" , OFS(r_pwd), "", SIZEOF(r_pwd)),
821 DEF_OPT_SSTR("pincode" , OFS(pincode), "none", SIZEOF(pincode)),
822 #ifdef MODULE_GBOX
823 DEF_OPT_UINT8("gbox_max_distance" , OFS(gbox_maxdist), DEFAULT_GBOX_MAX_DIST),
824 DEF_OPT_UINT8("gbox_max_ecm_send" , OFS(gbox_maxecmsend), DEFAULT_GBOX_MAX_ECM_SEND),
825 DEF_OPT_UINT8("gbox_reshare" , OFS(gbox_reshare), DEFAULT_GBOX_RESHARE),
826 DEF_OPT_UINT8("cccam_reshare" , OFS(gbox_cccam_reshare), DEFAULT_GBOX_RESHARE),
827 #endif
828 DEF_OPT_STR("readnano" , OFS(emmfile), NULL),
829 DEF_OPT_FUNC("services" , OFS(sidtabs), reader_services_fn),
830 DEF_OPT_FUNC("lb_whitelist_services" , OFS(lb_sidtabs), reader_lb_services_fn),
831 DEF_OPT_INT32("inactivitytimeout" , OFS(tcp_ito), DEFAULT_INACTIVITYTIMEOUT),
832 DEF_OPT_INT32("reconnecttimeout" , OFS(tcp_rto), DEFAULT_TCP_RECONNECT_TIMEOUT),
833 DEF_OPT_INT32("reconnectdelay" , OFS(tcp_reconnect_delay), 60000),
834 DEF_OPT_INT32("resetcycle" , OFS(resetcycle), 0),
835 DEF_OPT_INT8("disableserverfilter" , OFS(ncd_disable_server_filt), 0),
836 DEF_OPT_INT8("connectoninit" , OFS(ncd_connect_on_init), 0),
837 DEF_OPT_UINT8("keepalive" , OFS(keepalive), 0),
838 DEF_OPT_INT8("smargopatch" , OFS(smargopatch), 0),
839 DEF_OPT_INT8("autospeed" , OFS(autospeed), 1),
840 DEF_OPT_UINT8("sc8in1_dtrrts_patch" , OFS(sc8in1_dtrrts_patch), 0),
841 DEF_OPT_INT8("fallback" , OFS(fallback), 0),
842 DEF_OPT_FUNC_X("fallback_percaid" , OFS(fallback_percaid), ftab_fn, FTAB_READER | FTAB_FBPCAID),
843 DEF_OPT_FUNC_X("localcards" , OFS(localcards), ftab_fn, FTAB_READER | FTAB_LOCALCARDS),
844 DEF_OPT_FUNC_X("disablecrccws_only_for", OFS(disablecrccws_only_for), ftab_fn, FTAB_READER | FTAB_IGNCHKSMCAID),
845 #ifdef CS_CACHEEX
846 DEF_OPT_INT8("cacheex" , OFS(cacheex.mode), 0),
847 DEF_OPT_INT8("cacheex_maxhop" , OFS(cacheex.maxhop), 0),
848 DEF_OPT_FUNC("cacheex_ecm_filter" , OFS(cacheex.filter_caidtab), cacheex_hitvaluetab_fn),
849 DEF_OPT_UINT8("cacheex_allow_request" , OFS(cacheex.allow_request), 0),
850 DEF_OPT_UINT8("cacheex_drop_csp" , OFS(cacheex.drop_csp), 0),
851 DEF_OPT_UINT8("cacheex_allow_filter", OFS(cacheex.allow_filter), 1),
852 DEF_OPT_UINT8("cacheex_block_fakecws",OFS(cacheex.block_fakecws), 0),
853 #endif
854 DEF_OPT_FUNC("caid" , OFS(ctab), reader_caid_fn),
855 DEF_OPT_FUNC("atr" , 0, atr_fn),
856 DEF_OPT_FUNC("boxid" , 0, boxid_fn),
857 DEF_OPT_FUNC("boxkey" , 0, boxkey_fn),
858 DEF_OPT_FUNC("rsakey" , 0, rsakey_fn),
859 DEF_OPT_FUNC("deskey" , 0, deskey_fn),
860 DEF_OPT_FUNC_X("ins7e" , OFS(ins7E), ins7E_fn, SIZEOF(ins7E)),
861 DEF_OPT_FUNC_X("ins7e11" , OFS(ins7E11), ins7E_fn, SIZEOF(ins7E11)),
862 DEF_OPT_FUNC_X("ins2e06" , OFS(ins2e06), ins7E_fn, SIZEOF(ins2e06)),
863 DEF_OPT_INT8("fix07" , OFS(fix_07), 1),
864 DEF_OPT_INT8("fix9993" , OFS(fix_9993), 0),
865 DEF_OPT_INT8("readtiers" , OFS(readtiers), 1),
866 DEF_OPT_INT8("force_irdeto" , OFS(force_irdeto), 0),
867 DEF_OPT_INT8("needsemmfirst" , OFS(needsemmfirst), 0),
868 DEF_OPT_UINT32("ecmnotfoundlimit" , OFS(ecmnotfoundlimit), 0),
869 DEF_OPT_FUNC("ecmwhitelist" , 0, ecmwhitelist_fn),
870 DEF_OPT_FUNC("ecmheaderwhitelist" , 0, ecmheaderwhitelist_fn),
871 DEF_OPT_FUNC("detect" , 0, detect_fn),
872 DEF_OPT_INT8("nagra_read" , OFS(nagra_read), 0),
873 DEF_OPT_INT8("detect_seca_nagra_tunneled_card", OFS(detect_seca_nagra_tunneled_card), 1),
874 DEF_OPT_INT32("mhz" , OFS(mhz), 357),
875 DEF_OPT_INT32("cardmhz" , OFS(cardmhz), 357),
876 #ifdef WITH_AZBOX
877 DEF_OPT_INT32("mode" , OFS(azbox_mode), -1),
878 #endif
879 DEF_OPT_FUNC_X("ident" , OFS(ftab), ftab_fn, FTAB_READER | FTAB_PROVID),
880 DEF_OPT_FUNC_X("chid" , OFS(fchid), ftab_fn, FTAB_READER | FTAB_CHID),
881 DEF_OPT_FUNC("class" , OFS(cltab), class_fn),
882 DEF_OPT_FUNC("aeskeys" , 0, aeskeys_fn),
883 DEF_OPT_FUNC("group" , OFS(grp), group_fn),
884 DEF_OPT_FUNC("emmcache" , 0, emmcache_fn),
885 DEF_OPT_FUNC_X("blockemm-unknown" , OFS(blockemm), flags_fn, EMM_UNKNOWN),
886 DEF_OPT_FUNC_X("blockemm-u" , OFS(blockemm), flags_fn, EMM_UNIQUE),
887 DEF_OPT_FUNC_X("blockemm-s" , OFS(blockemm), flags_fn, EMM_SHARED),
888 DEF_OPT_FUNC_X("blockemm-g" , OFS(blockemm), flags_fn, EMM_GLOBAL),
889 DEF_OPT_FUNC_X("saveemm-unknown" , OFS(saveemm), flags_fn, EMM_UNKNOWN),
890 DEF_OPT_FUNC_X("saveemm-u" , OFS(saveemm), flags_fn, EMM_UNIQUE),
891 DEF_OPT_FUNC_X("saveemm-s" , OFS(saveemm), flags_fn, EMM_SHARED),
892 DEF_OPT_FUNC_X("saveemm-g" , OFS(saveemm), flags_fn, EMM_GLOBAL),
893 DEF_OPT_FUNC("blockemm-bylen" , 0, blockemm_bylen_fn),
894 #ifdef WITH_LB
895 DEF_OPT_INT32("lb_weight" , OFS(lb_weight), 100),
896 DEF_OPT_INT8("lb_force_fallback" , OFS(lb_force_fallback), 0),
897 #endif
898 DEF_OPT_FUNC("savenano" , OFS(s_nano), nano_fn),
899 DEF_OPT_FUNC("blocknano" , OFS(b_nano), nano_fn),
900 DEF_OPT_INT8("dropbadcws" , OFS(dropbadcws), 0),
901 DEF_OPT_INT8("disablecrccws" , OFS(disablecrccws), 0),
902 DEF_OPT_INT32("use_gpio" , OFS(use_gpio), 0),
903 #ifdef MODULE_PANDORA
904 DEF_OPT_UINT8("pand_send_ecm" , OFS(pand_send_ecm), 0),
905 #endif
906 #ifdef MODULE_CCCAM
907 DEF_OPT_SSTR("cccversion" , OFS(cc_version), "", SIZEOF(cc_version)),
908 DEF_OPT_INT8("cccmaxhops" , OFS(cc_maxhops), DEFAULT_CC_MAXHOPS),
909 DEF_OPT_INT8("cccmindown" , OFS(cc_mindown), 0),
910 DEF_OPT_INT8("cccwantemu" , OFS(cc_want_emu), 0),
911 DEF_OPT_INT8("ccckeepalive" , OFS(cc_keepalive), DEFAULT_CC_KEEPALIVE),
912 DEF_OPT_INT8("cccreshare" , OFS(cc_reshare), DEFAULT_CC_RESHARE),
913 DEF_OPT_INT32("cccreconnect" , OFS(cc_reconnect), DEFAULT_CC_RECONNECT),
914 DEF_OPT_INT8("ccchop" , OFS(cc_hop), 0),
915 #endif
916 #ifdef MODULE_GHTTP
917 DEF_OPT_UINT8("use_ssl" , OFS(ghttp_use_ssl), 0),
918 #endif
919 #if defined(READER_DRE) || defined(READER_DRECAS)
920 DEF_OPT_HEX("force_ua" , OFS(force_ua), 4),
921 DEF_OPT_STR("exec_cmd_file" , OFS(userscript), NULL),
922 #endif
923 #ifdef READER_DRECAS
924 DEF_OPT_STR("stmkeys" , OFS(stmkeys), NULL),
925 #endif
926 DEF_OPT_INT8("deprecated" , OFS(deprecated), 0),
927 DEF_OPT_INT8("audisabled" , OFS(audisabled), 0),
928 DEF_OPT_FUNC("auprovid" , 0, auprovid_fn),
929 DEF_OPT_INT8("ndsversion" , OFS(ndsversion), 0),
930 DEF_OPT_FUNC("ratelimitecm" , 0, ratelimitecm_fn),
931 DEF_OPT_FUNC("ecmunique" , 0, ecmunique_fn),
932 DEF_OPT_FUNC("ratelimittime" , 0, ratelimittime_fn),
933 DEF_OPT_FUNC("srvidholdtime" , 0, srvidholdtime_fn),
934 DEF_OPT_FUNC("cooldown" , 0, cooldown_fn),
935 DEF_OPT_FUNC("cooldowndelay" , 0, cooldowndelay_fn),
936 DEF_OPT_FUNC("cooldowntime" , 0, cooldowntime_fn),
937 DEF_OPT_UINT8("read_old_classes" , OFS(read_old_classes), 1),
938 DEF_LAST_OPT
941 static inline bool in_list(const char *token, const char *list[])
943 int i;
944 for(i = 0; list[i]; i++)
946 if(streq(token, list[i]))
947 { return true; }
949 return false;
952 static bool reader_check_setting(const struct config_list *UNUSED(clist), void *config_data, const char *setting)
954 struct s_reader *reader = config_data;
955 // These are written only when the reader is physical reader
956 static const char *hw_only_settings[] =
958 "readnano", "resetcycle", "smargopatch", "autospeed", "sc8in1_dtrrts_patch", "boxid","fix07",
959 "fix9993", "rsakey", "deskey", "ins7e", "ins7e11", "ins2e06", "force_irdeto", "needsemmfirst", "boxkey",
960 "atr", "detect", "nagra_read", "mhz", "cardmhz", "readtiers", "read_old_classes",
961 #if defined(READER_DRE) || defined(READER_DRECAS)
962 "exec_cmd_file",
963 #endif
964 #ifdef WITH_AZBOX
965 "mode",
966 #endif
967 "deprecated", "ndsversion",
970 // These are written only when the reader is network reader
971 static const char *network_only_settings[] =
973 "user", "inactivitytimeout", "reconnecttimeout",
976 if(is_network_reader(reader))
978 if(in_list(setting, hw_only_settings))
979 { return false; }
981 else
983 if(in_list(setting, network_only_settings))
984 { return false; }
987 // These are not written in the config file
988 static const char *deprecated_settings[] =
990 "cooldowndelay", "cooldowntime", "mg-encrypted",
993 if(in_list(setting, deprecated_settings))
994 { return false; }
996 // Special settings for NEWCAMD
997 static const char *newcamd_settings[] =
999 "disableserverfilter", "connectoninit",
1002 if(reader->typ != R_NEWCAMD && in_list(setting, newcamd_settings))
1003 { return false; }
1004 #ifdef MODULE_CCCAM
1005 // These are written only when the reader is CCCAM
1006 static const char *cccam_settings[] =
1008 "cccversion", "cccmaxhops", "cccmindown", "cccwantemu", "ccckeepalive",
1009 "cccreconnect",
1012 // Special settings for CCCAM
1013 if(reader->typ != R_CCCAM)
1015 if(in_list(setting, cccam_settings))
1016 { return false; }
1018 else if(streq(setting, "ccchop"))
1020 return false;
1022 #endif
1024 #ifdef MODULE_PANDORA
1025 // Special settings for PANDORA
1026 if(reader->typ != R_PANDORA && streq(setting, "pand_send_ecm"))
1027 { return false; }
1028 #endif
1030 return true; // Write the setting
1034 void chk_reader(char *token, char *value, struct s_reader *rdr)
1036 if(config_list_parse(reader_opts, token, value, rdr))
1037 { return; }
1038 else if(token[0] != '#')
1039 { fprintf(stderr, "Warning: keyword '%s' in reader section not recognized\n", token); }
1042 void reader_set_defaults(struct s_reader *rdr)
1044 config_list_set_defaults(reader_opts, rdr);
1047 int32_t init_readerdb(void)
1049 configured_readers = ll_create("configured_readers");
1051 FILE *fp = open_config_file(cs_srvr);
1052 if(!fp)
1053 { return 1; }
1055 int32_t tag = 0;
1056 char *value, *token;
1058 if(!cs_malloc(&token, MAXLINESIZE))
1059 { return 1; }
1061 struct s_reader *rdr;
1062 if(!cs_malloc(&rdr, sizeof(struct s_reader)))
1064 NULLFREE(token);
1065 return 1;
1068 ll_append(configured_readers, rdr);
1069 while(fgets(token, MAXLINESIZE, fp))
1071 int32_t l;
1072 if((l = strlen(trim(token))) < 3)
1073 { continue; }
1074 if((token[0] == '[') && (token[l - 1] == ']'))
1076 token[l - 1] = 0;
1077 tag = (!strcmp("reader", strtolower(token + 1)));
1078 if(rdr->label[0] && rdr->typ)
1080 struct s_reader *newreader;
1081 if(cs_malloc(&newreader, sizeof(struct s_reader)))
1083 ll_append(configured_readers, newreader);
1084 rdr = newreader;
1087 reader_set_defaults(rdr);
1088 continue;
1091 if(!tag)
1092 { continue; }
1093 if(!(value = strchr(token, '=')))
1094 { continue; }
1095 *value++ = '\0';
1096 chk_reader(trim(strtolower(token)), trim(value), rdr);
1098 NULLFREE(token);
1099 LL_ITER itr = ll_iter_create(configured_readers);
1100 while((rdr = ll_iter_next(&itr))) //build active readers list
1102 reader_fixups_fn(rdr);
1103 module_reader_set(rdr);
1105 fclose(fp);
1106 return (0);
1109 void free_reader(struct s_reader *rdr)
1111 NULLFREE(rdr->emmfile);
1113 ecm_whitelist_clear(&rdr->ecm_whitelist);
1114 ecm_hdr_whitelist_clear(&rdr->ecm_hdr_whitelist);
1116 ftab_clear(&rdr->fallback_percaid);
1117 ftab_clear(&rdr->localcards);
1118 ftab_clear(&rdr->fchid);
1119 ftab_clear(&rdr->ftab);
1121 NULLFREE(rdr->cltab.aclass);
1122 NULLFREE(rdr->cltab.bclass);
1124 caidtab_clear(&rdr->ctab);
1125 #ifdef CS_CACHEEX
1126 cecspvaluetab_clear(&rdr->cacheex.filter_caidtab);
1127 #endif
1128 lb_destroy_stats(rdr);
1130 cs_clear_entitlement(rdr);
1131 ll_destroy(&rdr->ll_entitlements);
1133 if(rdr->csystem && rdr->csystem->card_done)
1134 rdr->csystem->card_done(rdr);
1135 NULLFREE(rdr->csystem_data);
1137 ll_destroy_data(&rdr->blockemmbylen);
1139 ll_destroy_data(&rdr->emmstat);
1141 aes_clear_entries(&rdr->aes_list);
1143 config_list_gc_values(reader_opts, rdr);
1144 add_garbage(rdr);
1147 int32_t free_readerdb(void)
1149 int count = 0;
1150 struct s_reader *rdr;
1151 LL_ITER itr = ll_iter_create(configured_readers);
1152 while((rdr = ll_iter_next(&itr)))
1154 free_reader(rdr);
1155 count++;
1157 cs_log("readerdb %d readers freed", count);
1158 ll_destroy(&configured_readers);
1159 return count;
1162 int32_t write_server(void)
1164 FILE *f = create_config_file(cs_srvr);
1165 if(!f)
1166 { return 1; }
1167 struct s_reader *rdr;
1168 LL_ITER itr = ll_iter_create(configured_readers);
1169 while((rdr = ll_iter_next(&itr)))
1171 if(rdr->label[0])
1173 fprintf(f, "[reader]\n");
1174 config_list_apply_fixups(reader_opts, rdr);
1175 config_list_save_ex(f, reader_opts, rdr, cfg.http_full_cfg, reader_check_setting);
1176 fprintf(f, "\n");
1179 return flush_config_file(f, cs_srvr);
1182 void reload_readerdb(void)
1184 struct s_reader *rdr;
1185 LL_ITER itr = ll_iter_create(configured_readers);
1186 while((rdr = ll_iter_next(&itr)))
1188 // disable the current reader
1189 rdr->enable = 0;
1190 restart_cardreader(rdr,1);
1192 free_readerdb(); // release the old readerdb
1193 init_readerdb(); // reload the new readerdb
1194 init_cardreader(); // start the readers