1 #define MODULE_LOG_PREFIX "config"
4 #include "module-stat.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"
16 #include "module-gbox.h"
19 #define cs_srvr "oscam.server"
21 extern const struct s_cardreader
*cardreaders
[];
22 extern char *RDR_CD_TXT
[];
24 static void reader_label_fn(const char *token
, char *value
, void *setting
, FILE *f
)
26 struct s_reader
*rdr
= setting
;
32 for(i
= 0; i
< (int)strlen(value
); i
++)
41 { fprintf(stderr
, "Configuration reader: corrected label to %s\n", value
); }
42 cs_strncpy(rdr
->label
, value
, sizeof(rdr
->label
));
45 fprintf_conf(f
, token
, "%s\n", rdr
->label
);
48 static void ecmwhitelist_fn(const char *token
, char *value
, void *setting
, FILE *f
)
50 struct s_reader
*rdr
= setting
;
54 chk_ecm_whitelist(value
, &rdr
->ecm_whitelist
);
56 ecm_whitelist_clear(&rdr
->ecm_whitelist
);
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
); }
66 static void ecmheaderwhitelist_fn(const char *token
, char *value
, void *setting
, FILE *f
)
68 struct s_reader
*rdr
= setting
;
72 chk_ecm_hdr_whitelist(value
, &rdr
->ecm_hdr_whitelist
);
74 ecm_hdr_whitelist_clear(&rdr
->ecm_hdr_whitelist
);
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
); }
84 static void protocol_fn(const char *token
, char *value
, void *setting
, FILE *f
)
86 struct s_reader
*rdr
= setting
;
89 if(strlen(value
) == 0)
97 { "serial", R_SERIAL
},
98 { "camd35", R_CAMD35
},
99 { "cs378x", R_CS378X
},
100 { "cs357x", R_CAMD35
},
101 { "camd33", R_CAMD33
},
103 { "cccam", R_CCCAM
},
104 { "cccam_ext", R_CCCAM
},
105 { "cccam_mcs", R_CCCAM
},
106 { "constcw", R_CONSTCW
},
107 { "radegast", R_RADEGAST
},
109 { "ghttp", R_GHTTP
},
110 { "newcamd", R_NEWCAMD
},
111 { "newcamd525", R_NEWCAMD
},
112 { "newcamd524", R_NEWCAMD
},
113 { "drecas", R_DRECAS
},
118 // Parse card readers
119 for(i
= 0; cardreaders
[i
]; i
++)
121 if(streq(value
, cardreaders
[i
]->desc
))
123 rdr
->crdr
= cardreaders
[i
];
124 rdr
->typ
= cardreaders
[i
]->typ
;
129 for(i
= 0, p
= &protocols
[0]; p
->name
; p
= &protocols
[++i
])
131 if(streq(p
->name
, value
))
137 if(rdr
->typ
== R_NEWCAMD
)
138 { rdr
->ncd_proto
= streq(value
, "newcamd524") ? NCD_524
: NCD_525
; }
141 fprintf(stderr
, "ERROR: '%s' is unsupported reader protocol!\n", value
);
146 fprintf_conf(f
, token
, "%s\n", reader_get_type_desc(rdr
, 0));
149 static void device_fn(const char *token
, char *value
, void *setting
, FILE *f
)
151 struct s_reader
*rdr
= setting
;
152 int32_t isphysical
= !is_network_reader(rdr
);
156 char *ptr
, *saveptr1
= NULL
;
157 for(i
= 0, ptr
= strtok_r(value
, ",", &saveptr1
); (i
< 3) && (ptr
); ptr
= strtok_r(NULL
, ",", &saveptr1
), i
++)
163 cs_strncpy(rdr
->device
, ptr
, sizeof(rdr
->device
));
166 rdr
->r_port
= atoi(ptr
);
169 rdr
->l_port
= atoi(ptr
);
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
); }
183 static void reader_services_fn(const char *token
, char *value
, void *setting
, FILE *f
)
185 services_fn(token
, value
, setting
, f
);
188 struct s_reader
*rdr
= container_of(setting
, struct s_reader
, sidtabs
);
190 { rdr
->changes_since_shareupdate
= 1; }
194 static void reader_lb_services_fn(const char *token
, char *value
, void *setting
, FILE *f
)
196 services_fn(token
, value
, setting
, f
);
199 struct s_reader
*rdr
= container_of(setting
, struct s_reader
, lb_sidtabs
);
201 { rdr
->changes_since_shareupdate
= 1; }
205 static void reader_caid_fn(const char *token
, char *value
, void *setting
, FILE *f
)
207 check_caidtab_fn(token
, value
, setting
, f
);
210 struct s_reader
*rdr
= container_of(setting
, struct s_reader
, ctab
);
212 { rdr
->changes_since_shareupdate
= 1; }
216 static void boxid_fn(const char *token
, char *value
, void *setting
, FILE *f
)
218 struct s_reader
*rdr
= setting
;
221 rdr
->boxid
= strlen(value
) ? a2i(value
, 4) : 0;
225 { fprintf_conf(f
, token
, "%08X\n", rdr
->boxid
); }
226 else if(cfg
.http_full_cfg
)
227 { fprintf_conf(f
, token
, "\n"); }
230 static void rsakey_fn(const char *token
, char *value
, void *setting
, FILE *f
)
232 struct s_reader
*rdr
= setting
;
235 int32_t len
= strlen(value
);
236 if(len
!= 128 && len
!= 240)
238 rdr
->rsa_mod_length
= 0;
239 memset(rdr
->rsa_mod
, 0, 120);
243 if(key_atob_l(value
, rdr
->rsa_mod
, len
))
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
));
251 rdr
->rsa_mod_length
= len
/2;
256 int32_t len
= rdr
->rsa_mod_length
;
259 char tmp
[len
* 2 + 1];
260 fprintf_conf(f
, "rsakey", "%s\n", cs_hexdump(0, rdr
->rsa_mod
, len
, tmp
, sizeof(tmp
)));
262 else if(cfg
.http_full_cfg
)
263 { fprintf_conf(f
, "rsakey", "\n"); }
266 static void deskey_fn(const char *token
, char *value
, void *setting
, FILE *f
)
268 struct s_reader
*rdr
= setting
;
271 int32_t len
= strlen(value
);
272 if(((len
% 16) != 0) || len
== 0 || len
> 128*2)
274 rdr
->des_key_length
= 0;
275 memset(rdr
->des_key
, 0, sizeof(rdr
->des_key
));
279 if(key_atob_l(value
, rdr
->des_key
, len
))
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
));
287 rdr
->des_key_length
= len
/2;
292 int32_t len
= rdr
->des_key_length
;
295 char tmp
[len
* 2 + 1];
296 fprintf_conf(f
, "deskey", "%s\n", cs_hexdump(0, rdr
->des_key
, len
, tmp
, sizeof(tmp
)));
298 else if(cfg
.http_full_cfg
)
299 { fprintf_conf(f
, "deskey", "\n"); }
302 static void boxkey_fn(const char *token
, char *value
, void *setting
, FILE *f
)
304 struct s_reader
*rdr
= setting
;
307 int32_t len
= strlen(value
);
308 if(((len
% 8) != 0) || len
== 0 || len
> 32)
310 rdr
->boxkey_length
= 0;
311 memset(rdr
->boxkey
, 0, sizeof(rdr
->boxkey
));
315 if(key_atob_l(value
, rdr
->boxkey
, len
))
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
));
323 rdr
->boxkey_length
= len
/2;
328 int32_t len
= rdr
->boxkey_length
;
331 char tmp
[len
* 2 + 1];
332 fprintf_conf(f
, "boxkey", "%s\n", cs_hexdump(0, rdr
->boxkey
, len
, tmp
, sizeof(tmp
)));
334 else if(cfg
.http_full_cfg
)
335 { fprintf_conf(f
, "boxkey", "\n"); }
338 #ifdef READER_NAGRA_MERLIN
339 static void mod1_fn(const char *token
, char *value
, void *setting
, FILE *f
)
341 struct s_reader
*rdr
= setting
;
344 int32_t len
= strlen(value
);
347 rdr
->mod1_length
= 0;
348 memset(rdr
->mod1
, 0, 112);
352 if(key_atob_l(value
, rdr
->mod1
, len
))
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
));
360 rdr
->mod1_length
= len
/2;
365 int32_t len
= rdr
->mod1_length
;
368 char tmp
[len
* 2 + 1];
369 fprintf_conf(f
, "mod1", "%s\n", cs_hexdump(0, rdr
->mod1
, len
, tmp
, sizeof(tmp
)));
371 else if(cfg
.http_full_cfg
)
372 { fprintf_conf(f
, "mod1", "\n"); }
375 static void data50_fn(const char *token
, char *value
, void *setting
, FILE *f
)
377 struct s_reader
*rdr
= setting
;
380 int32_t len
= strlen(value
);
383 rdr
->data50_length
= 0;
384 memset(rdr
->data50
, 0, 80);
388 if(key_atob_l(value
, rdr
->data50
, len
))
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
));
396 rdr
->data50_length
= len
/2;
401 int32_t len
= rdr
->data50_length
;
404 char tmp
[len
* 2 + 1];
405 fprintf_conf(f
, "data50", "%s\n", cs_hexdump(0, rdr
->data50
, len
, tmp
, sizeof(tmp
)));
407 else if(cfg
.http_full_cfg
)
408 { fprintf_conf(f
, "data50", "\n"); }
411 static void mod50_fn(const char *token
, char *value
, void *setting
, FILE *f
)
413 struct s_reader
*rdr
= setting
;
416 int32_t len
= strlen(value
);
419 rdr
->mod50_length
= 0;
420 memset(rdr
->mod50
, 0, 80);
424 if(key_atob_l(value
, rdr
->mod50
, len
))
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
));
432 rdr
->mod50_length
= len
/2;
437 int32_t len
= rdr
->mod50_length
;
440 char tmp
[len
* 2 + 1];
441 fprintf_conf(f
, "mod50", "%s\n", cs_hexdump(0, rdr
->mod50
, len
, tmp
, sizeof(tmp
)));
443 else if(cfg
.http_full_cfg
)
444 { fprintf_conf(f
, "mod50", "\n"); }
447 static void key60_fn(const char *token
, char *value
, void *setting
, FILE *f
)
449 struct s_reader
*rdr
= setting
;
452 int32_t len
= strlen(value
);
455 rdr
->key60_length
= 0;
456 memset(rdr
->key60
, 0, 96);
460 if(key_atob_l(value
, rdr
->key60
, len
))
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
));
468 rdr
->key60_length
= len
/2;
473 int32_t len
= rdr
->key60_length
;
476 char tmp
[len
* 2 + 1];
477 fprintf_conf(f
, "key60", "%s\n", cs_hexdump(0, rdr
->key60
, len
, tmp
, sizeof(tmp
)));
479 else if(cfg
.http_full_cfg
)
480 { fprintf_conf(f
, "key60", "\n"); }
483 static void exp60_fn(const char *token
, char *value
, void *setting
, FILE *f
)
485 struct s_reader
*rdr
= setting
;
488 int32_t len
= strlen(value
);
491 rdr
->exp60_length
= 0;
492 memset(rdr
->exp60
, 0, 96);
496 if(key_atob_l(value
, rdr
->exp60
, len
))
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
));
504 rdr
->exp60_length
= len
/2;
509 int32_t len
= rdr
->exp60_length
;
512 char tmp
[len
* 2 + 1];
513 fprintf_conf(f
, "exp60", "%s\n", cs_hexdump(0, rdr
->exp60
, len
, tmp
, sizeof(tmp
)));
515 else if(cfg
.http_full_cfg
)
516 { fprintf_conf(f
, "exp60", "\n"); }
519 static void nuid_fn(const char *token
, char *value
, void *setting
, FILE *f
)
521 struct s_reader
*rdr
= setting
;
524 int32_t len
= strlen(value
);
527 rdr
->nuid_length
= 0;
528 memset(rdr
->nuid
, 0, 4);
532 if(key_atob_l(value
, rdr
->nuid
, len
))
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
));
540 rdr
->nuid_length
= len
/2;
545 int32_t len
= rdr
->nuid_length
;
548 char tmp
[len
* 2 + 1];
549 fprintf_conf(f
, "nuid", "%s\n", cs_hexdump(0, rdr
->nuid
, len
, tmp
, sizeof(tmp
)));
551 else if(cfg
.http_full_cfg
)
552 { fprintf_conf(f
, "nuid", "\n"); }
555 static void cwekey_fn(const char *token
, char *value
, void *setting
, FILE *f
)
557 struct s_reader
*rdr
= setting
;
560 int32_t len
= strlen(value
);
563 rdr
->cwekey_length
= 0;
564 memset(rdr
->cwekey
, 0, 16);
568 if(key_atob_l(value
, rdr
->cwekey
, len
))
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
));
576 rdr
->cwekey_length
= len
/2;
581 int32_t len
= rdr
->cwekey_length
;
584 char tmp
[len
* 2 + 1];
585 fprintf_conf(f
, "cwekey", "%s\n", cs_hexdump(0, rdr
->cwekey
, len
, tmp
, sizeof(tmp
)));
587 else if(cfg
.http_full_cfg
)
588 { fprintf_conf(f
, "cwekey", "\n"); }
592 static void flags_fn(const char *token
, char *value
, void *setting
, long flag
, FILE *f
)
594 uint32_t *var
= setting
;
598 if(!i
&& (*var
& flag
))
604 if((*var
& flag
) || cfg
.http_full_cfg
)
605 { fprintf_conf(f
, token
, "%d\n", (*var
& flag
) ? 1 : 0); }
608 static void ins7E_fn(const char *token
, char *value
, void *setting
, long var_size
, FILE *f
)
610 uint8_t *var
= setting
;
611 var_size
-= 1; // var_size contains sizeof(var) which is [X + 1]
614 int32_t len
= strlen(value
);
615 if(len
!= var_size
* 2 || key_atob_l(value
, var
, len
))
618 { fprintf(stderr
, "reader %s parse error, %s=%s\n", token
, token
, value
); }
619 memset(var
, 0, var_size
+ 1);
623 var
[var_size
] = 1; // found and correct
629 char tmp
[var_size
* 2 + 1];
630 fprintf_conf(f
, token
, "%s\n", cs_hexdump(0, var
, var_size
, tmp
, sizeof(tmp
)));
632 else if(cfg
.http_full_cfg
)
633 { fprintf_conf(f
, token
, "\n"); }
636 static void des_and_3des_key_fn(const char *token
, char *value
, void *setting
, FILE *f
)
638 uint8_t *var
= setting
;
641 int32_t len
= strlen(value
);
642 if(((len
!= 16) && (len
!= 32)) || (key_atob_l(value
, var
, len
)))
645 { fprintf(stderr
, "reader %s parse error, %s=%s\n", token
, token
, value
); }
656 char tmp
[var
[16] * 2 + 1];
657 fprintf_conf(f
, token
, "%s\n", cs_hexdump(0, var
, var
[16], tmp
, sizeof(tmp
)));
659 else if(cfg
.http_full_cfg
)
660 { fprintf_conf(f
, token
, "\n"); }
663 static void atr_fn(const char *token
, char *value
, void *setting
, FILE *f
)
665 struct s_reader
*rdr
= setting
;
668 memset(rdr
->atr
, 0, sizeof(rdr
->atr
));
669 rdr
->atrlen
= strlen(value
);
672 if(rdr
->atrlen
> (int32_t)sizeof(rdr
->atr
) * 2)
673 { rdr
->atrlen
= (int32_t)sizeof(rdr
->atr
) * 2; }
674 key_atob_l(value
, rdr
->atr
, rdr
->atrlen
);
678 if(rdr
->atr
[0] || cfg
.http_full_cfg
)
681 fprintf_conf(f
, token
, "%s", ""); // it should not have \n at the end
684 for(j
= 0; j
< rdr
->atrlen
/ 2; j
++)
686 fprintf(f
, "%02X", rdr
->atr
[j
]);
693 static void detect_fn(const char *token
, char *value
, void *setting
, FILE *f
)
695 struct s_reader
*rdr
= setting
;
699 for(i
= 0; RDR_CD_TXT
[i
]; i
++)
701 if(!strcmp(value
, RDR_CD_TXT
[i
]))
707 if(value
[0] == '!' && streq(value
+ 1, RDR_CD_TXT
[i
]))
708 { rdr
->detect
= i
| 0x80; }
713 fprintf_conf(f
, token
, "%s%s\n", rdr
->detect
& 0x80 ? "!" : "", RDR_CD_TXT
[rdr
->detect
& 0x7f]);
716 void ftab_fn(const char *token
, char *value
, void *setting
, long ftab_type
, FILE *f
)
718 FTAB
*ftab
= setting
;
722 chk_ftab(value
, ftab
);
727 if(ftab_type
& FTAB_READER
)
729 struct s_reader
*rdr
= NULL
;
730 if(ftab_type
& FTAB_PROVID
) { rdr
= container_of(setting
, struct s_reader
, ftab
); }
731 if(ftab_type
& FTAB_CHID
) { rdr
= container_of(setting
, struct s_reader
, fchid
); }
732 if(ftab_type
& FTAB_FBPCAID
) { rdr
= container_of(setting
, struct s_reader
, fallback_percaid
); }
733 if(ftab_type
& FTAB_LOCALCARDS
) { rdr
= container_of(setting
, struct s_reader
, localcards
); }
734 if(ftab_type
& FTAB_IGNCHKSMCAID
){ rdr
= container_of(setting
, struct s_reader
, disablecrccws_only_for
); }
736 if(ftab_type
& FTAB_EMUAU
) { rdr
= container_of(setting
, struct s_reader
, emu_auproviders
); }
739 { rdr
->changes_since_shareupdate
= 1; }
741 value
= mk_t_ftab(ftab
);
742 if(strlen(value
) > 0 || cfg
.http_full_cfg
)
743 { fprintf_conf(f
, token
, "%s\n", value
); }
747 static void aeskeys_fn(const char *token
, char *value
, void *setting
, FILE *f
)
749 struct s_reader
*rdr
= setting
;
752 parse_aes_keys(rdr
, value
);
755 value
= mk_t_aeskeys(rdr
);
756 if(strlen(value
) > 0 || cfg
.http_full_cfg
)
757 { fprintf_conf(f
, token
, "%s\n", value
); }
761 static void emmcache_fn(const char *token
, char *value
, void *setting
, FILE *f
)
763 struct s_reader
*rdr
= setting
;
773 char *ptr
, *saveptr1
= NULL
;
774 for(i
= 0, ptr
= strtok_r(value
, ",", &saveptr1
); (i
< 4) && (ptr
); ptr
= strtok_r(NULL
, ",", &saveptr1
), i
++)
779 rdr
->cachemm
= atoi(ptr
);
782 rdr
->rewritemm
= atoi(ptr
);
785 rdr
->logemm
= atoi(ptr
);
788 rdr
->deviceemm
= atoi(ptr
);
791 if(rdr
->rewritemm
<= 0)
793 fprintf(stderr
, "Setting reader \"emmcache\" to %i,%d,%i,%i instead of %i,%i,%i,%i.",
794 rdr
->cachemm
, 1, rdr
->logemm
, rdr
->deviceemm
,
795 rdr
->cachemm
, rdr
->rewritemm
, rdr
->logemm
, rdr
->deviceemm
);
796 fprintf(stderr
, "Zero or negative number of rewrites is silly\n");
802 if(rdr
->cachemm
|| rdr
->logemm
|| cfg
.http_full_cfg
)
803 { fprintf_conf(f
, token
, "%d,%d,%d,%d\n", rdr
->cachemm
, rdr
->rewritemm
, rdr
->logemm
,rdr
->deviceemm
); }
806 static void blockemm_bylen_fn(const char *token
, char *value
, void *setting
, FILE *f
)
808 struct s_reader
*rdr
= setting
;
811 char *ptr
, *saveptr1
= NULL
, dash
;
812 struct s_emmlen_range
*blocklen
;
817 ll_destroy_data(&rdr
->blockemmbylen
);
821 if(!rdr
->blockemmbylen
)
822 { rdr
->blockemmbylen
= ll_create("blockemmbylen"); }
824 { ll_clear_data(rdr
->blockemmbylen
); }
826 for(ptr
= strtok_r(value
, ",", &saveptr1
); ptr
;
827 ptr
= strtok_r(NULL
, ",", &saveptr1
))
829 if(!cs_malloc(&blocklen
, sizeof(*blocklen
)))
831 num
= sscanf(ptr
, "%hd%c%hd", &blocklen
->min
, &dash
, &blocklen
->max
);
835 fprintf(stderr
, "blockemm-bylen parse error: %s\n", value
);
838 if(num
== 1) // single values: x1, x2, x3, ...
839 { blocklen
->max
= blocklen
->min
; }
840 else if(num
== 2) // range values with open end: x1-
841 { blocklen
->max
= 0; }
842 ll_append(rdr
->blockemmbylen
, blocklen
);
846 value
= mk_t_emmbylen(rdr
);
847 if(strlen(value
) > 0 || cfg
.http_full_cfg
)
848 { fprintf_conf(f
, token
, "%s\n", value
); }
852 static void nano_fn(const char *token
, char *value
, void *setting
, FILE *f
)
854 uint16_t *nano
= setting
;
858 if(strlen(value
) > 0)
860 if(streq(value
, "all"))
867 char *ptr
, *saveptr1
= NULL
;
868 for(ptr
= strtok_r(value
, ",", &saveptr1
); ptr
; ptr
= strtok_r(NULL
, ",", &saveptr1
))
870 i
= (byte_atob(ptr
) % 0x80);
871 if(i
>= 0 && i
<= 16)
872 { *nano
|= (1 << i
); }
878 value
= mk_t_nano(*nano
);
879 if(strlen(value
) > 0 || cfg
.http_full_cfg
)
880 { fprintf_conf(f
, token
, "%s\n", value
); }
884 static void auprovid_fn(const char *token
, char *value
, void *setting
, FILE *f
)
886 struct s_reader
*rdr
= setting
;
891 { rdr
->auprovid
= a2i(value
, 3); }
895 { fprintf_conf(f
, token
, "%06X\n", rdr
->auprovid
); }
896 else if(cfg
.http_full_cfg
)
897 { fprintf_conf(f
, token
, "\n"); }
900 static void ratelimitecm_fn(const char *token
, char *value
, void *setting
, FILE *f
)
902 struct s_reader
*rdr
= setting
;
905 rdr
->ratelimitecm
= 0;
909 rdr
->ratelimitecm
= atoi(value
);
910 for(i
= 0; i
< MAXECMRATELIMIT
; i
++) // reset all slots
912 rdr
->rlecmh
[i
].srvid
= -1;
913 rdr
->rlecmh
[i
].last
.time
= -1;
918 if(rdr
->ratelimitecm
|| cfg
.http_full_cfg
)
919 { fprintf_conf(f
, token
, "%d\n", rdr
->ratelimitecm
); }
922 static void ecmunique_fn(const char *token
, char *value
, void *setting
, FILE *f
)
924 struct s_reader
*rdr
= setting
;
927 if(strlen(value
) == 0)
929 rdr
->ecmunique
= 0; // default
933 rdr
->ecmunique
= atoi(value
);
934 if(rdr
->ecmunique
>= 1)
935 { rdr
->ecmunique
= 1; }
937 { rdr
->ecmunique
= 0; }
941 if((rdr
->ratelimitecm
&& rdr
->ecmunique
!= 0) || cfg
.http_full_cfg
)
942 { fprintf_conf(f
, token
, "%d\n", rdr
->ecmunique
); }
945 static void ratelimittime_fn(const char *token
, char *value
, void *setting
, FILE *f
)
947 struct s_reader
*rdr
= setting
;
950 if(strlen(value
) == 0)
952 if(rdr
->ratelimitecm
> 0)
954 rdr
->ratelimittime
= 9000; // default 9 seconds
955 rdr
->srvidholdtime
= 2000; // default 2 seconds hold
959 rdr
->ratelimitecm
= 0; // in case someone set a negative value
960 rdr
->ratelimittime
= 0;
961 rdr
->srvidholdtime
= 0;
966 rdr
->ratelimittime
= atoi(value
);
967 if (rdr
->ratelimittime
< 60) rdr
->ratelimittime
*= 1000;
971 if(rdr
->ratelimitecm
|| cfg
.http_full_cfg
)
972 { fprintf_conf(f
, token
, "%d\n", rdr
->ratelimittime
); }
975 static void srvidholdtime_fn(const char *token
, char *value
, void *setting
, FILE *f
)
977 struct s_reader
*rdr
= setting
;
980 if(strlen(value
) == 0)
982 if(rdr
->ratelimitecm
> 0)
984 rdr
->srvidholdtime
= 2000; // default 2 seconds hold
988 rdr
->ratelimitecm
= 0; // in case someone set a negative value
989 rdr
->srvidholdtime
= 0;
994 rdr
->srvidholdtime
= atoi(value
);
995 if (rdr
->srvidholdtime
< 60) rdr
->srvidholdtime
*=1000;
999 if(rdr
->ratelimitecm
|| cfg
.http_full_cfg
)
1000 { fprintf_conf(f
, token
, "%d\n", rdr
->srvidholdtime
); }
1003 static void cooldown_fn(const char *token
, char *value
, void *setting
, FILE *f
)
1005 struct s_reader
*rdr
= setting
;
1008 if(strlen(value
) == 0)
1010 rdr
->cooldown
[0] = 0;
1011 rdr
->cooldown
[1] = 0;
1016 char *ptr
, *saveptr1
= NULL
;
1017 for(i
= 0, ptr
= strtok_r(value
, ",", &saveptr1
); (i
< 2) && (ptr
); ptr
= strtok_r(NULL
, ",", &saveptr1
), i
++)
1019 rdr
->cooldown
[i
] = atoi(ptr
);
1021 if(rdr
->cooldown
[0] <= 0 || rdr
->cooldown
[1] <= 0)
1023 fprintf(stderr
, "cooldown must have 2 positive values (x,y) set values %d,%d ! cooldown deactivated\n",
1024 rdr
->cooldown
[0], rdr
->cooldown
[1]);
1025 rdr
->cooldown
[0] = 0;
1026 rdr
->cooldown
[1] = 0;
1031 if(rdr
->cooldown
[0] || cfg
.http_full_cfg
)
1033 fprintf_conf(f
, token
, "%d,%d\n", rdr
->cooldown
[0], rdr
->cooldown
[1]);
1037 static void cooldowndelay_fn(const char *UNUSED(token
), char *value
, void *setting
, FILE *UNUSED(f
))
1039 struct s_reader
*rdr
= setting
;
1042 rdr
->cooldown
[0] = strlen(value
) ? atoi(value
) : 0;
1044 // This option is *not* written in the config file.
1045 // It is only set by WebIf as convenience
1048 static void cooldowntime_fn(const char *UNUSED(token
), char *value
, void *setting
, FILE *UNUSED(f
))
1050 struct s_reader
*rdr
= setting
;
1053 if(strlen(value
) == 0)
1055 rdr
->cooldown
[0] = 0; // no cooling down time means no cooling set
1056 rdr
->cooldown
[1] = 0;
1060 rdr
->cooldown
[1] = atoi(value
);
1064 // This option is *not* written in the config file.
1065 // It is only set by WebIf as convenience
1068 void reader_fixups_fn(void *var
)
1070 struct s_reader
*rdr
= var
;
1072 if(rdr
->lb_weight
> 1000)
1073 { rdr
->lb_weight
= 1000; }
1074 else if(rdr
->lb_weight
<= 0)
1075 { rdr
->lb_weight
= 100; }
1078 if(is_cascading_reader(rdr
) && (rdr
->typ
== R_CAMD35
|| rdr
->typ
== R_CS378X
))
1081 if(rdr
&& rdr
->cacheex
.mode
>1)
1082 { rdr
->keepalive
= 1; } // with cacheex, it is required!
1085 if(rdr
->typ
== R_CAMD35
)
1086 { rdr
->keepalive
= 0; } // with NO-cacheex, and UDP, keepalive is not required!
1090 #define OFS(X) offsetof(struct s_reader, X)
1091 #define SIZEOF(X) sizeof(((struct s_reader *)0)->X)
1093 static const struct config_list reader_opts
[] =
1095 DEF_OPT_FIXUP_FUNC(reader_fixups_fn
),
1096 DEF_OPT_FUNC("label" , 0, reader_label_fn
),
1098 DEF_OPT_STR("description" , OFS(description
), NULL
),
1100 DEF_OPT_INT8("enable" , OFS(enable
), 1),
1101 DEF_OPT_FUNC("protocol" , 0, protocol_fn
),
1102 DEF_OPT_FUNC("device" , 0, device_fn
),
1103 DEF_OPT_HEX("key" , OFS(ncd_key
), SIZEOF(ncd_key
)),
1104 DEF_OPT_SSTR("user" , OFS(r_usr
), "", SIZEOF(r_usr
)),
1105 DEF_OPT_SSTR("password" , OFS(r_pwd
), "", SIZEOF(r_pwd
)),
1106 DEF_OPT_SSTR("pincode" , OFS(pincode
), "none", SIZEOF(pincode
)),
1108 DEF_OPT_UINT8("gbox_max_distance" , OFS(gbox_maxdist
), DEFAULT_GBOX_MAX_DIST
),
1109 DEF_OPT_UINT8("gbox_max_ecm_send" , OFS(gbox_maxecmsend
), DEFAULT_GBOX_MAX_ECM_SEND
),
1110 DEF_OPT_UINT8("gbox_reshare" , OFS(gbox_reshare
), DEFAULT_GBOX_RESHARE
),
1111 DEF_OPT_INT8("cccam_reshare" , OFS(gbox_cccam_reshare
), -1),
1112 DEF_OPT_UINT8("force_remm" , OFS(gbox_force_remm
), 0),
1114 DEF_OPT_STR("readnano" , OFS(emmfile
), NULL
),
1115 DEF_OPT_FUNC("services" , OFS(sidtabs
), reader_services_fn
),
1116 DEF_OPT_FUNC("lb_whitelist_services" , OFS(lb_sidtabs
), reader_lb_services_fn
),
1117 DEF_OPT_INT32("inactivitytimeout" , OFS(tcp_ito
), DEFAULT_INACTIVITYTIMEOUT
),
1118 DEF_OPT_INT32("reconnecttimeout" , OFS(tcp_rto
), DEFAULT_TCP_RECONNECT_TIMEOUT
),
1119 DEF_OPT_INT32("reconnectdelay" , OFS(tcp_reconnect_delay
), 60000),
1120 DEF_OPT_INT32("resetcycle" , OFS(resetcycle
), 0),
1121 DEF_OPT_INT8("disableserverfilter" , OFS(ncd_disable_server_filt
), 0),
1122 DEF_OPT_INT8("connectoninit" , OFS(ncd_connect_on_init
), 0),
1123 DEF_OPT_UINT8("keepalive" , OFS(keepalive
), 0),
1124 DEF_OPT_INT8("smargopatch" , OFS(smargopatch
), 0),
1125 DEF_OPT_INT8("autospeed" , OFS(autospeed
), 1),
1126 DEF_OPT_UINT8("sc8in1_dtrrts_patch" , OFS(sc8in1_dtrrts_patch
), 0),
1127 DEF_OPT_INT8("fallback" , OFS(fallback
), 0),
1128 DEF_OPT_FUNC_X("fallback_percaid" , OFS(fallback_percaid
), ftab_fn
, FTAB_READER
| FTAB_FBPCAID
),
1129 DEF_OPT_FUNC_X("localcards" , OFS(localcards
), ftab_fn
, FTAB_READER
| FTAB_LOCALCARDS
),
1130 DEF_OPT_FUNC_X("disablecrccws_only_for" , OFS(disablecrccws_only_for
), ftab_fn
, FTAB_READER
| FTAB_IGNCHKSMCAID
),
1132 DEF_OPT_INT8("cacheex" , OFS(cacheex
.mode
), 0),
1133 DEF_OPT_INT8("cacheex_maxhop" , OFS(cacheex
.maxhop
), 0),
1134 DEF_OPT_FUNC("cacheex_ecm_filter" , OFS(cacheex
.filter_caidtab
), cacheex_hitvaluetab_fn
),
1135 DEF_OPT_UINT8("cacheex_allow_request" , OFS(cacheex
.allow_request
), 0),
1136 DEF_OPT_UINT8("cacheex_drop_csp" , OFS(cacheex
.drop_csp
), 0),
1137 DEF_OPT_UINT8("cacheex_allow_filter" , OFS(cacheex
.allow_filter
), 1),
1138 DEF_OPT_UINT8("cacheex_block_fakecws" , OFS(cacheex
.block_fakecws
), 0),
1140 DEF_OPT_FUNC("caid" , OFS(ctab
), reader_caid_fn
),
1141 DEF_OPT_FUNC("atr" , 0, atr_fn
),
1142 DEF_OPT_FUNC("boxid" , 0, boxid_fn
),
1143 DEF_OPT_FUNC("boxkey" , 0, boxkey_fn
),
1144 DEF_OPT_FUNC("rsakey" , 0, rsakey_fn
),
1145 DEF_OPT_FUNC("deskey" , 0, deskey_fn
),
1146 #ifdef READER_NAGRA_MERLIN
1147 DEF_OPT_FUNC("mod1" , 0, mod1_fn
),
1148 DEF_OPT_FUNC("data50" , 0, data50_fn
),
1149 DEF_OPT_FUNC("mod50" , 0, mod50_fn
),
1150 DEF_OPT_FUNC("key60" , 0, key60_fn
),
1151 DEF_OPT_FUNC("exp60" , 0, exp60_fn
),
1152 DEF_OPT_FUNC("nuid" , 0, nuid_fn
),
1153 DEF_OPT_FUNC("cwekey" , 0, cwekey_fn
),
1155 DEF_OPT_FUNC_X("ins7e" , OFS(ins7E
), ins7E_fn
, SIZEOF(ins7E
)),
1156 DEF_OPT_FUNC_X("ins7e11" , OFS(ins7E11
), ins7E_fn
, SIZEOF(ins7E11
)),
1157 DEF_OPT_FUNC_X("ins2e06" , OFS(ins2e06
), ins7E_fn
, SIZEOF(ins2e06
)),
1158 DEF_OPT_FUNC("k1_generic" , OFS(k1_generic
), des_and_3des_key_fn
),
1159 DEF_OPT_FUNC("k1_unique" , OFS(k1_unique
), des_and_3des_key_fn
),
1160 DEF_OPT_INT8("fix07" , OFS(fix_07
), 1),
1161 DEF_OPT_INT8("fix9993" , OFS(fix_9993
), 0),
1162 DEF_OPT_INT8("readtiers" , OFS(readtiers
), 1),
1163 DEF_OPT_INT8("force_irdeto" , OFS(force_irdeto
), 0),
1164 DEF_OPT_INT8("needsemmfirst" , OFS(needsemmfirst
), 0),
1165 #ifdef READER_CRYPTOWORKS
1166 DEF_OPT_INT8("needsglobalfirst" , OFS(needsglobalfirst
), 0),
1168 DEF_OPT_UINT32("ecmnotfoundlimit" , OFS(ecmnotfoundlimit
), 0),
1169 DEF_OPT_FUNC("ecmwhitelist" , 0, ecmwhitelist_fn
),
1170 DEF_OPT_FUNC("ecmheaderwhitelist" , 0, ecmheaderwhitelist_fn
),
1171 DEF_OPT_FUNC("detect" , 0, detect_fn
),
1172 DEF_OPT_INT8("nagra_read" , OFS(nagra_read
), 0),
1173 DEF_OPT_INT8("detect_seca_nagra_tunneled_card", OFS(detect_seca_nagra_tunneled_card
), 1),
1174 DEF_OPT_INT32("mhz" , OFS(mhz
), 357),
1175 DEF_OPT_INT32("cardmhz" , OFS(cardmhz
), 357),
1177 DEF_OPT_INT32("mode" , OFS(azbox_mode
), -1),
1179 DEF_OPT_FUNC_X("ident" , OFS(ftab
), ftab_fn
, FTAB_READER
| FTAB_PROVID
),
1180 DEF_OPT_FUNC_X("chid" , OFS(fchid
), ftab_fn
, FTAB_READER
| FTAB_CHID
),
1181 DEF_OPT_FUNC("class" , OFS(cltab
), class_fn
),
1182 DEF_OPT_FUNC("aeskeys" , 0, aeskeys_fn
),
1183 DEF_OPT_FUNC("group" , OFS(grp
), group_fn
),
1184 DEF_OPT_FUNC("emmcache" , 0, emmcache_fn
),
1185 DEF_OPT_FUNC_X("blockemm-unknown" , OFS(blockemm
), flags_fn
, EMM_UNKNOWN
),
1186 DEF_OPT_FUNC_X("blockemm-u" , OFS(blockemm
), flags_fn
, EMM_UNIQUE
),
1187 DEF_OPT_FUNC_X("blockemm-s" , OFS(blockemm
), flags_fn
, EMM_SHARED
),
1188 DEF_OPT_FUNC_X("blockemm-g" , OFS(blockemm
), flags_fn
, EMM_GLOBAL
),
1189 DEF_OPT_FUNC_X("saveemm-unknown" , OFS(saveemm
), flags_fn
, EMM_UNKNOWN
),
1190 DEF_OPT_FUNC_X("saveemm-u" , OFS(saveemm
), flags_fn
, EMM_UNIQUE
),
1191 DEF_OPT_FUNC_X("saveemm-s" , OFS(saveemm
), flags_fn
, EMM_SHARED
),
1192 DEF_OPT_FUNC_X("saveemm-g" , OFS(saveemm
), flags_fn
, EMM_GLOBAL
),
1193 DEF_OPT_FUNC("blockemm-bylen" , 0, blockemm_bylen_fn
),
1195 DEF_OPT_INT32("lb_weight" , OFS(lb_weight
), 100),
1196 DEF_OPT_INT8("lb_force_fallback" , OFS(lb_force_fallback
), 0),
1198 DEF_OPT_FUNC("savenano" , OFS(s_nano
), nano_fn
),
1199 DEF_OPT_FUNC("blocknano" , OFS(b_nano
), nano_fn
),
1200 DEF_OPT_INT8("dropbadcws" , OFS(dropbadcws
), 0),
1201 DEF_OPT_INT8("disablecrccws" , OFS(disablecrccws
), 0),
1202 DEF_OPT_INT32("use_gpio" , OFS(use_gpio
), 0),
1203 #ifdef MODULE_PANDORA
1204 DEF_OPT_UINT8("pand_send_ecm" , OFS(pand_send_ecm
), 0),
1207 DEF_OPT_SSTR("cccversion" , OFS(cc_version
), "", SIZEOF(cc_version
)),
1208 DEF_OPT_INT8("cccmaxhops" , OFS(cc_maxhops
), DEFAULT_CC_MAXHOPS
),
1209 DEF_OPT_INT8("cccmindown" , OFS(cc_mindown
), 0),
1210 DEF_OPT_INT8("cccwantemu" , OFS(cc_want_emu
), 0),
1211 DEF_OPT_INT8("ccckeepalive" , OFS(cc_keepalive
), DEFAULT_CC_KEEPALIVE
),
1212 DEF_OPT_INT8("cccreshare" , OFS(cc_reshare
), DEFAULT_CC_RESHARE
),
1213 DEF_OPT_INT32("cccreconnect" , OFS(cc_reconnect
), DEFAULT_CC_RECONNECT
),
1214 DEF_OPT_INT8("ccchop" , OFS(cc_hop
), 0),
1217 DEF_OPT_UINT8("use_ssl" , OFS(ghttp_use_ssl
), 0),
1219 #if defined(READER_DRE) || defined(READER_DRECAS)
1220 DEF_OPT_HEX("force_ua" , OFS(force_ua
), 4),
1221 DEF_OPT_STR("exec_cmd_file" , OFS(userscript
), NULL
),
1223 #ifdef READER_DRECAS
1224 DEF_OPT_STR("stmkeys" , OFS(stmkeys
), NULL
),
1227 DEF_OPT_FUNC_X("emu_auproviders" , OFS(emu_auproviders
), ftab_fn
, FTAB_READER
| FTAB_EMUAU
),
1228 DEF_OPT_INT8("emu_datecodedenabled" , OFS(emu_datecodedenabled
), 0),
1230 DEF_OPT_INT8("deprecated" , OFS(deprecated
), 0),
1231 DEF_OPT_INT8("audisabled" , OFS(audisabled
), 0),
1232 DEF_OPT_FUNC("auprovid" , 0, auprovid_fn
),
1233 DEF_OPT_INT8("ndsversion" , OFS(ndsversion
), 0),
1234 DEF_OPT_FUNC("ratelimitecm" , 0, ratelimitecm_fn
),
1235 DEF_OPT_FUNC("ecmunique" , 0, ecmunique_fn
),
1236 DEF_OPT_FUNC("ratelimittime" , 0, ratelimittime_fn
),
1237 DEF_OPT_FUNC("srvidholdtime" , 0, srvidholdtime_fn
),
1238 DEF_OPT_FUNC("cooldown" , 0, cooldown_fn
),
1239 DEF_OPT_FUNC("cooldowndelay" , 0, cooldowndelay_fn
),
1240 DEF_OPT_FUNC("cooldowntime" , 0, cooldowntime_fn
),
1241 DEF_OPT_UINT8("read_old_classes" , OFS(read_old_classes
), 1),
1245 static inline bool in_list(const char *token
, const char *list
[])
1248 for(i
= 0; list
[i
]; i
++)
1250 if(streq(token
, list
[i
]))
1256 static bool reader_check_setting(const struct config_list
*UNUSED(clist
), void *config_data
, const char *setting
)
1258 struct s_reader
*reader
= config_data
;
1259 // These are written only when the reader is physical reader
1260 static const char *hw_only_settings
[] =
1262 "readnano", "resetcycle", "smargopatch", "autospeed", "sc8in1_dtrrts_patch", "boxid","fix07",
1263 "fix9993", "rsakey", "deskey", "ins7e", "ins7e11", "ins2e06", "k1_generic", "k1_unique", "force_irdeto", "needsemmfirst", "boxkey",
1264 "atr", "detect", "nagra_read", "mhz", "cardmhz", "readtiers", "read_old_classes", "use_gpio", "needsglobalfirst",
1265 #ifdef READER_NAGRA_MERLIN
1266 "mod1", "data50", "mod50", "key60", "exp60", "nuid", "cwekey",
1268 #if defined(READER_DRE) || defined(READER_DRECAS)
1274 "deprecated", "ndsversion",
1277 // These are written only when the reader is network reader
1278 static const char *network_only_settings
[] =
1280 "user", "inactivitytimeout", "reconnecttimeout",
1283 if(is_network_reader(reader
))
1285 if(in_list(setting
, hw_only_settings
))
1290 if(in_list(setting
, network_only_settings
))
1294 // These are not written in the config file
1295 static const char *deprecated_settings
[] =
1297 "cooldowndelay", "cooldowntime",
1300 if(in_list(setting
, deprecated_settings
))
1303 // Special settings for NEWCAMD
1304 static const char *newcamd_settings
[] =
1306 "disableserverfilter", "connectoninit",
1309 if(reader
->typ
!= R_NEWCAMD
&& in_list(setting
, newcamd_settings
))
1312 // These are written only when the reader is CCCAM
1313 static const char *cccam_settings
[] =
1315 "cccversion", "cccmaxhops", "cccmindown", "cccwantemu", "ccckeepalive",
1319 // Special settings for CCCAM
1320 if(reader
->typ
!= R_CCCAM
)
1322 if(in_list(setting
, cccam_settings
))
1325 else if(streq(setting
, "ccchop"))
1331 #ifdef MODULE_PANDORA
1332 // Special settings for PANDORA
1333 if(reader
->typ
!= R_PANDORA
&& streq(setting
, "pand_send_ecm"))
1338 // These are written only when the reader is GBOX
1339 static const char *gbox_settings
[] =
1341 "gbox_max_distance", "gbox_max_ecm_send", "gbox_reshare", "cccam_reshare", "force_remm",
1344 if(reader
->typ
!= R_GBOX
)
1346 if(in_list(setting
, gbox_settings
))
1351 return true; // Write the setting
1354 void chk_reader(char *token
, char *value
, struct s_reader
*rdr
)
1356 if(config_list_parse(reader_opts
, token
, value
, rdr
))
1358 else if(token
[0] != '#')
1359 { fprintf(stderr
, "Warning: keyword '%s' in reader section not recognized\n", token
); }
1362 void reader_set_defaults(struct s_reader
*rdr
)
1364 config_list_set_defaults(reader_opts
, rdr
);
1367 int32_t init_readerdb(void)
1369 configured_readers
= ll_create("configured_readers");
1371 FILE *fp
= open_config_file(cs_srvr
);
1376 char *value
, *token
;
1378 if(!cs_malloc(&token
, MAXLINESIZE
))
1381 struct s_reader
*rdr
;
1382 if(!cs_malloc(&rdr
, sizeof(struct s_reader
)))
1388 ll_append(configured_readers
, rdr
);
1389 while(fgets(token
, MAXLINESIZE
, fp
))
1392 if((l
= strlen(trim(token
))) < 3)
1394 if((token
[0] == '[') && (token
[l
- 1] == ']'))
1397 tag
= (!strcmp("reader", strtolower(token
+ 1)));
1398 if(rdr
->label
[0] && rdr
->typ
)
1400 struct s_reader
*newreader
;
1401 if(cs_malloc(&newreader
, sizeof(struct s_reader
)))
1403 ll_append(configured_readers
, newreader
);
1407 reader_set_defaults(rdr
);
1413 if(!(value
= strchr(token
, '=')))
1416 chk_reader(trim(strtolower(token
)), trim(value
), rdr
);
1419 LL_ITER itr
= ll_iter_create(configured_readers
);
1420 while((rdr
= ll_iter_next(&itr
))) // build active readers list
1422 reader_fixups_fn(rdr
);
1423 module_reader_set(rdr
);
1429 void free_reader(struct s_reader
*rdr
)
1431 NULLFREE(rdr
->emmfile
);
1433 ecm_whitelist_clear(&rdr
->ecm_whitelist
);
1434 ecm_hdr_whitelist_clear(&rdr
->ecm_hdr_whitelist
);
1436 ftab_clear(&rdr
->fallback_percaid
);
1437 ftab_clear(&rdr
->localcards
);
1438 ftab_clear(&rdr
->fchid
);
1439 ftab_clear(&rdr
->ftab
);
1441 NULLFREE(rdr
->cltab
.aclass
);
1442 NULLFREE(rdr
->cltab
.bclass
);
1444 caidtab_clear(&rdr
->ctab
);
1446 cecspvaluetab_clear(&rdr
->cacheex
.filter_caidtab
);
1448 lb_destroy_stats(rdr
);
1450 cs_clear_entitlement(rdr
);
1451 ll_destroy(&rdr
->ll_entitlements
);
1453 if(rdr
->csystem
&& rdr
->csystem
->card_done
)
1454 rdr
->csystem
->card_done(rdr
);
1455 NULLFREE(rdr
->csystem_data
);
1457 ll_destroy_data(&rdr
->blockemmbylen
);
1459 ll_destroy_data(&rdr
->emmstat
);
1461 aes_clear_entries(&rdr
->aes_list
);
1463 config_list_gc_values(reader_opts
, rdr
);
1467 int32_t free_readerdb(void)
1470 struct s_reader
*rdr
;
1471 LL_ITER itr
= ll_iter_create(configured_readers
);
1472 while((rdr
= ll_iter_next(&itr
)))
1477 cs_log("readerdb %d readers freed", count
);
1478 ll_destroy(&configured_readers
);
1482 int32_t write_server(void)
1484 FILE *f
= create_config_file(cs_srvr
);
1487 struct s_reader
*rdr
;
1488 LL_ITER itr
= ll_iter_create(configured_readers
);
1489 while((rdr
= ll_iter_next(&itr
)))
1493 fprintf(f
, "[reader]\n");
1494 config_list_apply_fixups(reader_opts
, rdr
);
1495 config_list_save_ex(f
, reader_opts
, rdr
, cfg
.http_full_cfg
, reader_check_setting
);
1499 return flush_config_file(f
, cs_srvr
);
1502 void reload_readerdb(void)
1504 struct s_reader
*rdr
;
1505 LL_ITER itr
= ll_iter_create(configured_readers
);
1506 while((rdr
= ll_iter_next(&itr
)))
1508 // disable the current reader
1510 restart_cardreader(rdr
,1);
1512 free_readerdb(); // release the old readerdb
1513 init_readerdb(); // reload the new readerdb
1514 init_cardreader(); // start the readers