1 #define MODULE_LOG_PREFIX "emm"
4 #include "cscrypt/md5.h"
5 #include "module-dvbapi.h"
6 #include "module-led.h"
7 #include "oscam-client.h"
8 #include "oscam-config.h"
10 #include "oscam-string.h"
11 #include "oscam-time.h"
12 #include "oscam-work.h"
13 #include "reader-common.h"
14 #include "oscam-chk.h"
15 #include "oscam-emm-cache.h"
17 const char *entitlement_type
[] = { "", "package", "PPV-Event", "chid", "tier", "class", "PBM", "admin" };
19 static struct timeb last_emm_clean
;
20 static int8_t cs_emmlen_is_blocked(struct s_reader
*rdr
, int16_t len
)
22 struct s_emmlen_range
*blocklen
;
23 if(!rdr
->blockemmbylen
)
25 LL_ITER it
= ll_iter_create(rdr
->blockemmbylen
);
26 while((blocklen
= ll_iter_next(&it
)))
28 if(blocklen
->min
<= len
&& (len
<= blocklen
->max
|| blocklen
->max
== 0))
35 * Function to filter emm by cardsystem.
36 * Every cardsystem can export a function "get_emm_filter"
38 * the emm is checked against it and returns 1 for a valid emm or 0 if not
40 static int8_t do_simple_emm_filter(struct s_reader
*rdr
, const struct s_cardsystem
*csystem
, EMM_PACKET
*ep
, int8_t cl_dvbapi
)
42 if(is_network_reader(rdr
)) { return 1; } // don't evaluate on network readers, server with local reader will check it
43 if(rdr
->typ
== R_EMU
) { return 1; } // don't evalutate on emu reader
45 //copied and enhanced from module-dvbapi.c
46 //dvbapi_start_emm_filter()
49 struct s_csystem_emm_filter
*dmx_filter
= NULL
;
50 unsigned int j
, filter_count
= 0;
52 // Call cardsystems emm filter
53 csystem
->get_emm_filter(rdr
, &dmx_filter
, &filter_count
);
55 // Only check matching emmtypes:
57 if(ep
->type
== UNKNOWN
)
58 { org_emmtype
= EMM_UNKNOWN
; }
60 { org_emmtype
= 1 << (ep
->type
- 1); }
62 // Now check all filter values
65 for(j
= 0; j
< filter_count
; j
++)
67 if(dmx_filter
[j
].enabled
== 0)
70 uint8_t emmtype
= dmx_filter
[j
].type
;
71 if(emmtype
!= org_emmtype
)
75 for(i
= 0, k
= 0; i
< 16 && k
< ep
->emmlen
&& match
; i
++, k
++)
77 mask
= dmx_filter
[j
].mask
[i
];
78 if(k
== 1 && cl_dvbapi
) // fixup for emms send by dvbapi
79 { k
+= 2; } // skip emm len bytes
82 //cs_log("**** filter %d [%d] = %02X, filter mask[%d] = %02X, flt&mask = %02X , ep->emm[%d] = %02X, ep->emm[%d] & mask = %02X ****", j, i,
83 // dmx_filter[j].filter[i], i, dmx_filter[j].mask[i], flt&mask, k, ep->emm[k], k, ep->emm[k] & mask);
84 flt
= (dmx_filter
[j
].filter
[i
] & mask
);
85 match
= (flt
== (ep
->emm
[k
] & mask
));
92 return 1; // valid emm
98 return 0; // emm filter does not match, illegal emm, return
101 static void reader_log_emm(struct s_reader
*reader
, EMM_PACKET
*ep
, int32_t count
, int32_t rc
, struct timeb
*tps
)
106 is_network_reader(reader
) ? "sent" : "written",
110 char *typedesc
[] = { "unknown", "unique", "shared", "global" };
111 struct s_client
*cl
= reader
->client
;
114 if(reader
->logemm
& (1 << rc
))
120 rdr_log(reader
, "%s emmtype=%s, len=%d (hex: 0x%.2X), cnt=%d: %s (%"PRId64
" ms)",
121 username(ep
->client
), typedesc
[ep
->type
], SCT_LEN(ep
->emm
)-3, SCT_LEN(ep
->emm
)-3, count
, rtxt
[rc
], comp_timeb(&tpe
, tps
));
126 cl
->lastemm
= time(NULL
);
130 #if defined(WEBIF) || defined(LCDSUPPORT)
135 reader
->emmerror
[ep
->type
]++;
136 reader
->webif_emmerror
[ep
->type
]++;
140 reader
->emmwritten
[ep
->type
]++;
141 reader
->webif_emmwritten
[ep
->type
]++;
145 reader
->emmskipped
[ep
->type
]++;
146 reader
->webif_emmskipped
[ep
->type
]++;
150 reader
->emmblocked
[ep
->type
]++;
151 reader
->webif_emmblocked
[ep
->type
]++;
157 int32_t emm_reader_match(struct s_reader
*reader
, uint16_t caid
, uint32_t provid
)
161 // if physical reader a card needs to be inserted
162 if(!is_network_reader(reader
) && reader
->card_status
!= CARD_INSERTED
)
165 if(reader
->audisabled
)
168 if(reader
->cwpkcaid_length
&& reader
->nuid_length
)
171 check
[0] = caid
& 0xFF;
172 if(check
[0] == reader
->cwpkcaid
[1])
179 if(reader
->caid
== 0x186D)
181 emmcaid
= reader
->caid
- 0x03;
183 else if (reader
->caid
== 0x1856)
185 emmcaid
= reader
->caid
+ 0x28;
189 emmcaid
= reader
->caid
;
195 if (!reader
->csystem
)
197 for(i
= 0; reader
->csystem
->caids
[i
]; i
++)
199 uint16_t cs_caid
= reader
->csystem
->caids
[i
];
200 if (emmcaid
&& cs_caid
== caid
)
206 if ((emmcaid
== 0) && chk_ctab_ex(caid
, &reader
->ctab
))
215 rdr_log_dbg(reader
, D_EMM
, "reader_caid %04X != emmpid caid %04X -> SKIP!", emmcaid
, caid
);
220 //if(!hexserialset(reader)) // There are cards without serial, they should get emm of type global and shared!
222 // rdr_log_dbg(reader, D_EMM, "no hexserial is set");
228 rdr_log_dbg(reader
, D_EMM
, "reader %04X match since emmpid has no provid -> SEND!", caid
);
232 uint32_t prid
= reader
->auprovid
;
234 if(caid_is_viaccess(caid
) && (prid
!= 0) && ((prid
&0xFFFFF0) != prid
)) // viaccess fixup last digit of provid is a dont care!
237 rdr_log_dbg(reader
, D_EMM
, "reader auprovid = %06X fixup to %06X (ignoring last digit)", reader
->auprovid
, prid
);
241 if(reader
->typ
== R_EMU
)
243 FILTER
*emu_provids
= get_emu_prids_for_caid(reader
, caid
);
244 if(emu_provids
!= NULL
)
246 for(i
= 0; i
< emu_provids
->nprids
; i
++)
248 if(provid
== emu_provids
->prids
[i
])
260 rdr_log_dbg(reader
, D_EMM
, "reader auprovid = %06X matching with emm provid = %06X -> SEND!", prid
, provid
);
264 for(i
= 0; i
< reader
->nprov
; i
++)
266 prid
= b2i(4, reader
->prid
[i
]);
268 if(caid_is_viaccess(caid
) && (prid
!= 0) && ((prid
&0xFFFFF0) != prid
)) // viaccess fixup last digit of provid is a dont care!
270 rdr_log_dbg(reader
, D_EMM
, "reader provid = %06X fixup to %06X (ignoring last digit)", prid
, (prid
&0xFFFFF0));
276 rdr_log_dbg(reader
, D_EMM
, "reader provid %06X matching with emm provid %06X -> SEND!", prid
, provid
);
280 if((reader
->typ
== R_CAMD35
|| reader
->typ
== R_CS378X
) && (prid
& 0xFFFF) == (provid
& 0xFFFF))
282 rdr_log_dbg(reader
, D_EMM
, "CS378: Match after fixing reader provid %06X to ??%04X and emm provid %06X to ??%04X -> SEND!", prid
, prid
&0xFFFF, provid
, provid
&0xFFFF);
286 rdr_log_dbg(reader
, D_EMM
, "reader provid %06X no match with emm provid %06X -> SKIP!", prid
, provid
);
291 static char *get_emmlog_filename(char *dest
, size_t destlen
, const char *basefilename
, const char *type
, const char *ext
)
293 char filename
[64 + 16];
294 snprintf(filename
, sizeof(filename
), "%s_%s_emm.%s", basefilename
, type
, ext
);
297 get_config_filename(dest
, destlen
, filename
);
301 const char *slash
= "/";
302 if(cfg
.emmlogdir
[cs_strlen(cfg
.emmlogdir
) - 1] == '/') { slash
= ""; }
303 snprintf(dest
, destlen
, "%s%s%s", cfg
.emmlogdir
, slash
, filename
);
308 static void saveemm(struct s_reader
*aureader
, EMM_PACKET
*ep
, const char *proceded
)
318 if(ep
->type
== UNKNOWN
)
319 { emmtype
= EMM_UNKNOWN
; }
321 { emmtype
= 1 << (ep
->type
- 1); }
322 // should this nano be saved?
323 if(((1 << (ep
->emm
[0] % 0x80)) & aureader
->s_nano
) || (aureader
->saveemm
& emmtype
))
326 localtime_r(&rawtime
, &timeinfo
); // to access LOCAL date/time info
327 int32_t emm_length
= SCT_LEN(ep
->emm
);
328 strftime(buf
, sizeof(buf
), "%Y/%m/%d %H:%M:%S", &timeinfo
);
333 fp_log
= fopen(get_emmlog_filename(token_log
, sizeof(token_log
), aureader
->label
, "global", "log"), "a");
337 fp_log
= fopen(get_emmlog_filename(token_log
, sizeof(token_log
), aureader
->label
, "shared", "log"), "a");
341 fp_log
= fopen(get_emmlog_filename(token_log
, sizeof(token_log
), aureader
->label
, "unique", "log"), "a");
346 fp_log
= fopen(get_emmlog_filename(token_log
, sizeof(token_log
), aureader
->label
, "unknown", "log"), "a");
351 rdr_log(aureader
, "ERROR: Cannot open file '%s' (errno=%d: %s)\n", token_log
, errno
, strerror(errno
));
355 if(cs_malloc(&tmp2
, emm_length
* 2 + 1))
357 fprintf(fp_log
, "%s %s ", buf
, cs_hexdump(0, ep
->hexserial
, 8, tmp
, sizeof(tmp
)));
358 fprintf(fp_log
, "%s %s\n", cs_hexdump(0, ep
->emm
, emm_length
, tmp2
, emm_length
* 2 + 1), proceded
);
360 rdr_log(aureader
, "Successfully added EMM to %s", token_log
);
367 void do_emm(struct s_client
*client
, EMM_PACKET
*ep
)
369 int32_t writeemm
= 1; // 0= dont write emm, 1=write emm, default = write
370 char *typtext
[] = {"unknown", "unique", "shared", "global"};
373 bool lastseendone
= false;
375 struct s_reader
*aureader
= NULL
;
380 cs_log("EMM size %d invalid, ignored! client %s", ep
->emmlen
, username(client
));
384 if(ep
->emmlen
> MAX_EMM_SIZE
)
386 cs_log("EMM size %d > Max EMM size %d, ignored! client %s", ep
->emmlen
, MAX_EMM_SIZE
, username(client
));
390 sct_len
= SCT_LEN(ep
->emm
);
391 if(sct_len
> ep
->emmlen
)
393 cs_log("Real EMM size %d > EMM size %d, ignored! client %s", sct_len
, ep
->emmlen
, username(client
));
396 ep
->emmlen
= sct_len
;
398 cs_log_dump_dbg(D_EMM
, ep
->emm
, ep
->emmlen
, "emm:");
401 bool cl_dvbapi
= is_dvbapi_usr(client
->account
->usr
);
402 if(client
->account
->emm_reassembly
> 1 || (client
->account
->emm_reassembly
&& cl_dvbapi
))
405 LL_ITER itr
= ll_iter_create(client
->aureader_list
);
406 while((aureader
= ll_iter_next(&itr
)))
408 if(!aureader
->enable
)
411 uint16_t caid
= b2i(2, ep
->caid
);
412 uint32_t provid
= b2i(4, ep
->provid
);
414 if(caid_is_viaccess(caid
)) // viaccess fixup last digit is a dont care!
419 if(aureader
->audisabled
)
421 rdr_log_dbg(aureader
, D_EMM
, "AU is disabled");
422 /* we have to write the log for blocked EMM here because
423 this EMM never reach the reader module where the rest
424 of EMM log is done. */
425 if(aureader
->logemm
& 0x10)
427 rdr_log(aureader
, "%s emmtype=%s, len=%d (hex: 0x%02X), idx=0, cnt=1: audisabled (0 ms)",
428 client
->account
->usr
,
430 SCT_LEN(ep
->emm
) - 3,
431 SCT_LEN(ep
->emm
) - 3);
436 if(!(aureader
->grp
& client
->grp
))
438 rdr_log_dbg(aureader
, D_EMM
, "skip emm, group mismatch");
442 // TODO: provider possibly not set yet, this is done in get_emm_type()
443 if(!emm_reader_match(aureader
, caid
, provid
))
446 const struct s_cardsystem
*csystem
= NULL
;
448 if(is_network_reader(aureader
)) // network reader (R_CAMD35 R_NEWCAMD R_CS378X R_CCCAM)
450 if(!aureader
->ph
.c_send_emm
) // no emm support
453 csystem
= get_cardsystem_by_caid(caid
);
456 rdr_log_dbg(aureader
, D_EMM
, "unable to find cardsystem for caid %04X", caid
);
462 if(aureader
->csystem_active
)
463 { csystem
= aureader
->csystem
; }
466 if(csystem
&& csystem
->get_emm_type
)
468 if(!csystem
->get_emm_type(ep
, aureader
))
470 rdr_log_dbg(aureader
, D_EMM
, "emm skipped, get_emm_type() returns error");
476 if(!ep
->skip_filter_check
&& csystem
&& csystem
->get_emm_filter
)
478 if(!do_simple_emm_filter(aureader
, csystem
, ep
, 1)) // do check with dvbapi fixup enabled
480 if(!do_simple_emm_filter(aureader
, csystem
, ep
, 0)) // do check with dvbapi fixup disabled
482 rdr_log_dbg(aureader
, D_EMM
, "emm skipped, do_simple_emm_filter() returns invalid");
489 if(csystem
&& csystem
->do_emm_reassembly
)
493 if(!csystem
->do_emm_reassembly(aureader
, client
, ep
))
494 { continue; } // skip this reader
498 rdr_log_dbg(aureader
, D_EMM
, "processing raw emm");
502 rdr_log_dbg_sensitive(aureader
, D_EMM
, "emmtype %s. Reader serial {%s}.", typtext
[ep
->type
],
503 cs_hexdump(0, aureader
->hexserial
, 8, tmp
, sizeof(tmp
)));
504 rdr_log_dbg_sensitive(aureader
, D_EMM
, "emm UA/SA: {%s}.",
505 cs_hexdump(0, ep
->hexserial
, 8, tmp
, sizeof(tmp
)));
507 client
->last
= time(NULL
);
509 int32_t is_blocked
= 0;
511 if (aureader
->fix_07
== 1 && ep
->type
== UNIQUE
)
513 if((caid
== 0x098D || caid
== 0x098C || caid
== 0x09C4) && ep
->emm
[1] == 0x70 && (ep
->emm
[8] * 0x100 + ep
->emm
[9] != 0x200))
515 rdr_log(aureader
,"emmtype 0x%04X marked as unknown for caid 0x%04X", (ep
->emm
[8] * 0x100 + ep
->emm
[9]),caid
);
519 if((caid
== 0x098D || caid
== 0x098C || caid
== 0x09C4) && ep
->emm
[1] == 0 && (ep
->emm
[4] * 0x100 + ep
->emm
[5] != 0x200))
521 rdr_log(aureader
,"emmtype 0x%04X marked as unknown for caid 0x%04X", (ep
->emm
[4] * 0x100 + ep
->emm
[5]),caid
);
525 if(caid
== 0x09AF && ep
->emm
[1] == 0x70 && ep
->emm
[11] != 2)
527 rdr_log(aureader
,"emmtype 0x%02X marked as unknown for caid 0x%04X", ep
->emm
[11],caid
);
531 if(caid
== 0x09AF && ep
->emm
[1] == 0 && ep
->emm
[7] != 2)
533 rdr_log(aureader
,"emmtype 0x%02X marked as unknown for caid 0x%04X", ep
->emm
[7],caid
);
538 #ifdef READER_CRYPTOWORKS
539 if ((ep
->type
== GLOBAL
) && ((caid
== 0x0D96) || (caid
== 0x0D98)) && ((aureader
->blockemm
& EMM_GLOBAL
) != EMM_GLOBAL
) && ((aureader
->blockemm
& EMM_SHARED
) != EMM_SHARED
) && (aureader
->needsglobalfirst
== 1))
542 cs_log_dbg(D_EMM
,"save global EMM for caid 0x%04X",caid
);
544 memcpy(aureader
->last_g_emm
, ep
, sizeof(EMM_PACKET
));
545 aureader
->last_g_emm_valid
= true;
548 aureader
->emmblocked
[ep
->type
]++;
549 aureader
->webif_emmblocked
[ep
->type
]++;
550 is_blocked
= aureader
->emmblocked
[ep
->type
];
553 if(aureader
->logemm
& 0x08)
555 rdr_log(aureader
, "%s emmtype=%s, len=%d (hex: 0x%02X), idx=0, cnt=%d: blocked & saved (0 ms)",
556 client
->account
->usr
,
562 saveemm(aureader
, ep
, "blocked & saved");
570 is_blocked
= (aureader
->blockemm
& EMM_UNKNOWN
) == EMM_UNKNOWN
;
574 is_blocked
= (aureader
->blockemm
& EMM_UNIQUE
) == EMM_UNIQUE
;
578 is_blocked
= (aureader
->blockemm
& EMM_SHARED
) == EMM_SHARED
;
582 is_blocked
= (aureader
->blockemm
& EMM_GLOBAL
) == EMM_GLOBAL
;
586 // if not already blocked we check for block by len
587 if(!is_blocked
) { is_blocked
= cs_emmlen_is_blocked(aureader
, SCT_LEN(ep
->emm
)-3) ; }
592 aureader
->emmblocked
[ep
->type
]++;
593 aureader
->webif_emmblocked
[ep
->type
]++;
594 is_blocked
= aureader
->emmblocked
[ep
->type
];
596 /* we have to write the log for blocked EMM here because
597 this EMM never reach the reader module where the rest
598 of EMM log is done. */
599 if(aureader
->logemm
& 0x08)
601 rdr_log(aureader
, "%s emmtype=%s, len=%d (hex: 0x%02X), idx=0, cnt=%d: blocked (0 ms)",
602 client
->account
->usr
,
608 saveemm(aureader
, ep
, "blocked");
612 client
->lastemm
= time((time_t *)0);
616 { client
->account
->emmok
++; }
617 first_client
->emmok
++;
622 if(aureader
->cachemm
&& !(caid_is_irdeto(caid
) || caid_is_videoguard(caid
))) // Check emmcache early:
624 uint8_t md5tmp
[MD5_DIGEST_LENGTH
];
626 MD5(ep
->emm
, SCT_LEN(ep
->emm
), md5tmp
);
628 struct s_emmcache
*emmcache
= find_emm_cache(md5tmp
); // check emm cache
629 if(emmcache
&& !lastseendone
)
631 cs_ftime(&emmcache
->lastseen
);
632 lastseendone
= true; // in case several aureaders, only do lastseen once!
635 struct s_emmstat
*emmstat
= get_emm_stat(aureader
, md5tmp
, ep
->type
);
638 rdr_log_dbg(aureader
, D_EMM
, "emm count %d rewrite %d", emmstat
->count
, aureader
->rewritemm
);
640 if(emmstat
->count
>= aureader
->rewritemm
)
642 reader_log_emm(aureader
, ep
, emmstat
->count
, 2, NULL
);
643 writeemm
= 0; // don't write emm!
644 saveemm(aureader
, ep
, "emmcache");
645 continue; // found emm match needs no further handling, proceed with next reader!
650 if(writeemm
) // only write on no cache hit or cache hit that needs further rewrite
652 EMM_PACKET
*emm_pack
;
653 if(cs_malloc(&emm_pack
, sizeof(EMM_PACKET
)))
655 #ifdef READER_CRYPTOWORKS
656 if ((ep
->type
== SHARED
) && ((caid
== 0x0D96) || (caid
== 0x0D98)) && (aureader
->last_g_emm_valid
== true) && (aureader
->needsglobalfirst
== 1))
658 EMM_PACKET
*emm_pack_global
;
659 if(cs_malloc(&emm_pack_global
, sizeof(EMM_PACKET
)))
661 rdr_log_dbg(aureader
, D_EMM
, "Last stored global EMM for caid 0x%04X is being sent to Reader first", caid
);
662 memcpy(emm_pack_global
, aureader
->last_g_emm
, sizeof(EMM_PACKET
));
663 add_job(aureader
->client
, ACTION_READER_EMM
, emm_pack_global
, sizeof(EMM_PACKET
));
664 saveemm(aureader
, aureader
->last_g_emm
, "written stored global");
665 cs_log_dump_dbg(D_EMM
,emm_pack_global
->emm
, emm_pack_global
->emmlen
, "Last stored global EMM to be written before shared EMM:");
669 rdr_log_dbg(aureader
, D_EMM
, "emm is being sent to reader");
670 memcpy(emm_pack
, ep
, sizeof(EMM_PACKET
));
671 add_job(aureader
->client
, ACTION_READER_EMM
, emm_pack
, sizeof(EMM_PACKET
));
672 saveemm(aureader
, ep
, "written");
676 } // done with this reader, process next reader!
678 if(emmnok
> 0 && emmnok
== ll_count(client
->aureader_list
))
682 { client
->account
->emmnok
++; }
683 first_client
->emmnok
++;
688 int32_t reader_do_emm(struct s_reader
*reader
, EMM_PACKET
*ep
)
690 int32_t rc
, ecs
= 0,count
= 0;
691 uint8_t md5tmp
[MD5_DIGEST_LENGTH
];
695 uint16_t caid
= b2i(2, ep
->caid
);
696 if(reader
->cachemm
&& !(caid_is_irdeto(caid
) || caid_is_videoguard(caid
)))
698 MD5(ep
->emm
, SCT_LEN(ep
->emm
), md5tmp
);
699 int64_t gone
= comp_timeb(&tps
, &last_emm_clean
);
700 if(gone
> (int64_t)1000 * 60 * 60 * 24 * 30 || gone
< 0) // dont run every time, only on first emm oscam is started and then every 30 days
702 last_emm_clean
= tps
;
703 count
= clean_stale_emm_cache_and_stat(md5tmp
, (int64_t)1000 * 60 * 60 *24 * 30); // clean global all emms from all readers after 30 days emm is last seen!
704 cs_log_dbg(D_EMM
, "Cleaned %d emm stale stats and cache entries", count
);
707 struct s_emmcache
*emmcache
= find_emm_cache(md5tmp
); // check emm cache
710 emm_edit_cache(md5tmp
, ep
, true);
713 struct s_emmstat
*emmstat
= get_emm_stat(reader
, md5tmp
, ep
->type
);
716 if(reader
->cachemm
&& emmstat
->count
>= reader
->rewritemm
)
722 ecs
= 1; // rewrite emm
725 cs_ftime(&emmstat
->firstwritten
);
726 emmstat
->lastwritten
= emmstat
->firstwritten
;
730 cs_ftime(&emmstat
->lastwritten
);
732 count
= ++emmstat
->count
;
737 cs_log("abort: oscam seems out of resources!");
742 // Ecs=0 not found in cache
743 // Ecs=1 found in cache, rewrite emm
747 if(is_network_reader(reader
))
749 rdr_log_dbg(reader
, D_READER
, "network emm reader");
750 if(reader
->ph
.c_send_emm
)
752 rc
= reader
->ph
.c_send_emm(ep
);
756 rdr_log_dbg(reader
, D_READER
, "send_emm() support missing");
762 rdr_log_dbg(reader
, D_READER
, "local emm reader");
763 rc
= cardreader_do_emm(reader
, ep
);
767 reader_log_emm(reader
, ep
, count
, rc
, &tps
);
772 void do_emm_from_file(struct s_reader
*reader
)
780 if(reader
->emmfile
[0] == '/')
781 { snprintf(token
, sizeof(token
), "%s", reader
->emmfile
); } // pathname included
783 { get_config_filename(token
, sizeof(token
), reader
->emmfile
); } // only file specified, look in confdir for this file
785 if(!(fp
= fopen(token
, "rb")))
787 rdr_log(reader
, "ERROR: Cannot open EMM file '%s' (errno=%d %s)\n", token
, errno
, strerror(errno
));
792 if(!cs_malloc(&eptmp
, sizeof(EMM_PACKET
)))
798 size_t ret
= fread(eptmp
, sizeof(EMM_PACKET
), 1, fp
);
799 if(ret
< 1 && ferror(fp
))
801 rdr_log(reader
, "ERROR: Can't read EMM from file '%s' (errno=%d %s)", token
, errno
, strerror(errno
));
809 eptmp
->caid
[0] = (reader
->caid
>> 8) & 0xFF;
810 eptmp
->caid
[1] = reader
->caid
& 0xFF;
811 if(reader
->nprov
> 0)
812 { memcpy(eptmp
->provid
, reader
->prid
[0], sizeof(eptmp
->provid
)); }
813 eptmp
->emmlen
= SCT_LEN(eptmp
->emm
);
815 const struct s_cardsystem
*csystem
= get_cardsystem_by_caid(reader
->caid
);
816 if(csystem
&& csystem
->get_emm_type
&& !csystem
->get_emm_type(eptmp
, reader
))
818 rdr_log_dbg(reader
, D_EMM
, "emm skipped, get_emm_type() returns error");
823 // save old b_nano value
824 // clear lsb and lsb+1, so no blocking, and no saving for this nano
825 uint16_t save_s_nano
= reader
->s_nano
;
826 uint16_t save_b_nano
= reader
->b_nano
;
827 uint32_t save_saveemm
= reader
->saveemm
;
829 reader
->s_nano
= reader
->b_nano
= 0;
833 rc
= cardreader_do_emm(reader
, eptmp
);
835 { rdr_log(reader
, "EMM from file %s was successfully written.", token
); }
837 { rdr_log(reader
, "ERROR: EMM read from file %s NOT processed correctly! (rc=%d)", token
, rc
); }
839 // restore old block/save settings
840 reader
->s_nano
= save_s_nano
;
841 reader
->b_nano
= save_b_nano
;
842 reader
->saveemm
= save_saveemm
;
847 void emm_sort_nanos(uint8_t *dest
, const uint8_t *src
, int32_t len
)
849 int32_t w
= 0, c
= -1, j
= 0;
855 int32_t l
= src
[j
+ 1] + 2;
860 cs_log_dbg(D_EMM
, "sortnanos: sanity check failed. Exceeding memory area. Probably corrupted nanos!");
861 memset(dest
, 0, len
); // zero out everything
864 memcpy(&dest
[w
], &src
[j
], l
);
867 else if(src
[j
] > c
&& src
[j
] < n
)