![]() |
The needed gxsdldr.c loader file is included directly:
The __lib__.h
file contains some library functions used only in the sample programs, such as the lib_function_start
and lib_function_end
functions that implement the simple command line interface and measures the elapsed time between the two function calls.
#include "../__lib__.h"
The make_bac helper function, reading MRZ from the document and using it to make BAC:
/* The make_bac helper function, reading MRZ from the document and using it to make BAC */ int make_bac(gxHANDLE hpr, char* card) { int j,l; gxVARIANT pdoc; int pages; char *mrz[3]; /* Setting only infra light for capture */ lib_function_start("\t- Setting infra light"); if (pr_getlightmask(hpr,&pages,PR_LIGHT_INFRA,0) && pr_setpagelight(hpr,1,(gxu32*)&pages)) lib_function_end(); else return lib_displ_err(); /* Capturing images */ lib_function_start("\t- Capturing images"); if (pr_capture(hpr)) lib_function_end(); else return lib_displ_err(); /* Reading MRZ */ lib_function_start("\t- Reading MRZ"); if (pr_getmrz(hpr, 0, PR_LIGHT_INFRA, PR_IT_ORIGINAL, &pdoc)) lib_function_end(); else return lib_displ_err(); if (!pdoc) {printf("No MRZ data found!\n"); return -1;} for (j=0; j<3; j++) { mrz[j] = (char*) malloc(45); memset(mrz[j], 0 ,45); l = 45; pr_getfieldfromdoca(hpr, pdoc, PR_DF_MRZ1 + j, mrz[j], &l, 0, 0); } gx_disposevariant(&pdoc); /* Making BAC */ lib_function_start("\t- Making BAC"); if (pr_makebaca(hpr, card, (const char **)mrz, strlen(mrz[2]) ? 3 : 2)) { for (j=0; j<3; j++) free(mrz[j]); lib_function_end(); } else { for (j=0; j<3; j++) free(mrz[j]); return lib_displ_err(); } return 0; }
The resolve_dg1 helper function, parsing EF_DG1
and displaying MRZ information:
/* The resolve_dg1 helper function, parsing EF_DG1 and displaying MRZ information */ int resolve_dg1(gxHANDLE hpr, void * data, int sdata) { int error_code = 0; gxVARIANT pdoc; char text[256]; int stext; lib_function_start("\t- Resolving DG1"); if (pr_resolverfiddata(hpr, data, sdata, &pdoc)) { if (!pdoc) lib_error("No MRZ data found!"); else { lib_function_end(); lib_write_line("\t- MRZ data:"); stext = sizeof(text); if (pr_getfieldfromdoca(hpr, pdoc, PR_DF_RFID_MRZ, text, &stext, NULL, 0)) { char s[45]; gx_snprintf(s, 44, text); s[44] = 0; lib_write_line("\t\t %s", s); gx_snprintf(s, 44, text+44); s[44] = 0; lib_write_line("\t\t %s", s); } else { error_code = lib_displ_err(); } if (pdoc) gx_disposevariant(&pdoc); } } else { error_code = lib_displ_err(); } return error_code; }
The resolve_dg2 helper function, parsing EF_DG2
and saving the face image:
/* The resolve_dg2 helper function, parsing EF_DG2 and saving the face image */ int resolve_dg2(gxHANDLE hpr, void * data, int sdata) { int error_code = 0; gxVARIANT pdoc; gxIMAGE *img = NULL; lib_function_start("\t- Resolving"); if (pr_resolverfiddata(hpr, data, sdata, &pdoc)) { if (!pdoc) lib_error("No image data found!"); else { lib_function_end(); lib_function_start("\t- Saving image"); if (pr_getgximagefromdoc(hpr, pdoc, PR_DF_RFID_FACE, &img)) { if (gx_saveimagea(gx_direct(GX_CALL_GROUP_GX_IMAGE), img, "face.jpg", GX_JPEG)) lib_function_end(); else error_code = lib_displ_err(); gx_unrefimage(gx_direct(GX_CALL_GROUP_GX_IMAGE), img); } else { error_code = lib_displ_err(); } if (pdoc) gx_disposevariant(&pdoc); } } else { error_code = lib_displ_err(); } return error_code; }
The main function:
int main() { int i; char ** cardlist=0; int numcards=0; void * data=NULL; int sdata = 0, srfid_files = 4; unsigned int rfid_files = 0; char path[64], fn[32]; gxVARIANT pdoc = NULL;
Opening the Passport Reader system:
/* Opening the PR system */ gxHANDLE hpr; /* handle for the PR system */ lib_function_start("Opening system files"); if (gx_openmodulea(&hpr,"prapi","default")) lib_function_end(); else { lib_displ_err(); return 0; }
Connecting to the first device. If no device is connected then the pr_usedevicen() function returns false and the program ends:
/* Connecting to the first device */ lib_function_start("Connecting to the first device"); if (pr_usedevicen(hpr,0,PR_UMODE_FULL_CONTROL)) { lib_function_end(); } else { lib_displ_err(); gx_closehandle(&hpr); return 0; }
The main loop begins:
while(!lib_kbhit()) { lib_process_start("RFID");
Searching for RFID cards:
/* Searching for RFID cards */ lib_function_start("Searching for RFID cards ..."); if (pr_getrfidcardlista(hpr, &cardlist, &numcards)) { lib_function_end();
Connecting to the first chip:
/* Connecting to the first chip */ lib_function_start("Connecting to the RFID chip"); if (pr_connectrfidcarda(hpr, cardlist[0])) lib_function_end(); else { lib_displ_err(); continue; } lib_write_line("Serial no.: %s", cardlist[0]);
Reading EF_COM first to determine the available files on the chip. In case of BAC protected chip the reading process returns GX_EACCES, which means that the Basic Access Control procedure must be executed in order to access the chip.
/* Initializing chip reading */ lib_function_start("Initializing chip reading"); if (pr_getrfidfilea(hpr, cardlist[0], PR_RFID_EF_COM, &data, &sdata)) lib_function_end(); else { lib_displ_err(); if (gx_geterrorcode() != GX_EACCES) continue; if(make_bac(hpr, cardlist[0])) continue; lib_function_start("Initializing chip reading"); if (pr_getrfidfilea(hpr, cardlist[0], PR_RFID_EF_COM, &data, &sdata)) lib_function_end(); else {lib_displ_err(); continue;} }
Parsing the EF_COM
and getting the information about the available files on the chip:
/* Getting available files */ lib_function_start("\t- Available files"); gx_snprintf(path, sizeof(path), "C,D=%i/L,V=%i/C,D=%i", PRV_FIELDLIST, PR_DF_RFID_FIELDS|PR_DFE_DOCUMENT_DESCRIPTOR, PRV_RFIDDIR); if ( !pr_resolverfiddata(hpr, data, sdata, &pdoc) || !gx_convertvariantbypatha(pdoc, path, 0, GX_VARIANT_INT, &srfid_files, 0, &rfid_files, srfid_files) ) { lib_displ_err(); if (pdoc) gx_disposevariant(&pdoc); if (data) {gx_globalfree(data); data = NULL; sdata = 0;} continue; } if (pdoc) gx_disposevariant(&pdoc); if (data) {gx_globalfree(data); data = NULL; sdata = 0;} for (i=PR_RFID_EF_DG1; i<=PR_RFID_EF_DG16; i++) if (((1<<i) & rfid_files)) lib_write("DG%i ", i); lib_function_end();
Reading available files, saving and resolving them
/* Reading available files, saving and resolving them */ for (i=PR_RFID_EF_DG1; i<=PR_RFID_EF_DG2; i++) { if (!((1<<i) & rfid_files)) continue; gx_snprintf(fn, 32, "EF_DG%i.dat", i); lib_function_start("Reading %s", fn); if (pr_getrfidfilea(hpr, cardlist[0], i, &data, &sdata)) lib_function_end(); else {lib_displ_err(); continue;} lib_function_start("\t- Saving %s", fn); if (!lib_save(fn, data, sdata)) lib_error("File write error!"); else lib_function_end(); if (i == PR_RFID_EF_DG1) resolve_dg1(hpr, data, sdata); if (i == PR_RFID_EF_DG2) resolve_dg2(hpr, data, sdata); if (data) {gx_globalfree(data); data = NULL; sdata = 0;} }
Disconnecting from the chip:
/* Disconnecting from the chip */ lib_function_start("Disconnecting from the RFID chip"); if (pr_disconnectrfidcarda(hpr, cardlist[0])) lib_function_end(); else lib_displ_err();
The main loop ends:
lib_process_end(); lib_wait_for_sec(3); }
Closing the device:
/* Closing the device */ lib_function_start("Closing the device"); if (pr_closedevice(hpr)) { lib_function_end(); } else { lib_displ_err(); }
Closing the Passport Reader system:
/* Closing the PR system */ lib_function_start("Closing the PR system"); if (gx_closehandle(&hpr)) { lib_function_end(); } else { lib_displ_err(); }
The sample program ends printing some statistic information:
return lib_print_stat();
}
The complete source code:
#include "prapi.h" #include "gxsdldr.c" #include "../__lib__.h" /* The make_bac helper function, reading MRZ from the document and using it to make BAC */ int make_bac(gxHANDLE hpr, char* card) { int j,l; gxVARIANT pdoc; int pages; char *mrz[3]; /* Setting only infra light for capture */ lib_function_start("\t- Setting infra light"); if (pr_getlightmask(hpr,&pages,PR_LIGHT_INFRA,0) && pr_setpagelight(hpr,1,(gxu32*)&pages)) lib_function_end(); else return lib_displ_err(); /* Capturing images */ lib_function_start("\t- Capturing images"); if (pr_capture(hpr)) lib_function_end(); else return lib_displ_err(); /* Reading MRZ */ lib_function_start("\t- Reading MRZ"); if (pr_getmrz(hpr, 0, PR_LIGHT_INFRA, PR_IT_ORIGINAL, &pdoc)) lib_function_end(); else return lib_displ_err(); if (!pdoc) {printf("No MRZ data found!\n"); return -1;} for (j=0; j<3; j++) { mrz[j] = (char*) malloc(45); memset(mrz[j], 0 ,45); l = 45; pr_getfieldfromdoca(hpr, pdoc, PR_DF_MRZ1 + j, mrz[j], &l, 0, 0); } gx_disposevariant(&pdoc); /* Making BAC */ lib_function_start("\t- Making BAC"); if (pr_makebaca(hpr, card, (const char **)mrz, strlen(mrz[2]) ? 3 : 2)) { for (j=0; j<3; j++) free(mrz[j]); lib_function_end(); } else { for (j=0; j<3; j++) free(mrz[j]); return lib_displ_err(); } return 0; } /* The resolve_dg1 helper function, parsing EF_DG1 and displaying MRZ information */ int resolve_dg1(gxHANDLE hpr, void * data, int sdata) { int error_code = 0; gxVARIANT pdoc; char text[256]; int stext; lib_function_start("\t- Resolving DG1"); if (pr_resolverfiddata(hpr, data, sdata, &pdoc)) { if (!pdoc) lib_error("No MRZ data found!"); else { lib_function_end(); lib_write_line("\t- MRZ data:"); stext = sizeof(text); if (pr_getfieldfromdoca(hpr, pdoc, PR_DF_RFID_MRZ, text, &stext, NULL, 0)) { char s[45]; gx_snprintf(s, 44, text); s[44] = 0; lib_write_line("\t\t %s", s); gx_snprintf(s, 44, text+44); s[44] = 0; lib_write_line("\t\t %s", s); } else { error_code = lib_displ_err(); } if (pdoc) gx_disposevariant(&pdoc); } } else { error_code = lib_displ_err(); } return error_code; } /* The resolve_dg2 helper function, parsing EF_DG2 and saving the face image */ int resolve_dg2(gxHANDLE hpr, void * data, int sdata) { int error_code = 0; gxVARIANT pdoc; gxIMAGE *img = NULL; lib_function_start("\t- Resolving"); if (pr_resolverfiddata(hpr, data, sdata, &pdoc)) { if (!pdoc) lib_error("No image data found!"); else { lib_function_end(); lib_function_start("\t- Saving image"); if (pr_getgximagefromdoc(hpr, pdoc, PR_DF_RFID_FACE, &img)) { if (gx_saveimagea(gx_direct(GX_CALL_GROUP_GX_IMAGE), img, "face.jpg", GX_JPEG)) lib_function_end(); else error_code = lib_displ_err(); gx_unrefimage(gx_direct(GX_CALL_GROUP_GX_IMAGE), img); } else { error_code = lib_displ_err(); } if (pdoc) gx_disposevariant(&pdoc); } } else { error_code = lib_displ_err(); } return error_code; } int main() { int i; char ** cardlist=0; int numcards=0; void * data=NULL; int sdata = 0, srfid_files = 4; unsigned int rfid_files = 0; char path[64], fn[32]; gxVARIANT pdoc = NULL; /* Opening the PR system */ gxHANDLE hpr; /* handle for the PR system */ lib_function_start("Opening system files"); if (gx_openmodulea(&hpr,"prapi","default")) lib_function_end(); else { lib_displ_err(); return 0; } /* Connecting to the first device */ lib_function_start("Connecting to the first device"); if (pr_usedevicen(hpr,0,PR_UMODE_FULL_CONTROL)) { lib_function_end(); } else { lib_displ_err(); gx_closehandle(&hpr); return 0; } while(!lib_kbhit()) { lib_process_start("RFID"); /* Searching for RFID cards */ lib_function_start("Searching for RFID cards ..."); if (pr_getrfidcardlista(hpr, &cardlist, &numcards)) { lib_function_end(); if (numcards == 0) { lib_write_line("No card found"); } else { lib_write_line(""); do { /* Connecting to the first chip */ lib_function_start("Connecting to the RFID chip"); if (pr_connectrfidcarda(hpr, cardlist[0])) lib_function_end(); else { lib_displ_err(); continue; } lib_write_line("Serial no.: %s", cardlist[0]); /* Initializing chip reading */ lib_function_start("Initializing chip reading"); if (pr_getrfidfilea(hpr, cardlist[0], PR_RFID_EF_COM, &data, &sdata)) lib_function_end(); else { lib_displ_err(); if (gx_geterrorcode() != GX_EACCES) continue; if(make_bac(hpr, cardlist[0])) continue; lib_function_start("Initializing chip reading"); if (pr_getrfidfilea(hpr, cardlist[0], PR_RFID_EF_COM, &data, &sdata)) lib_function_end(); else {lib_displ_err(); continue;} } /* Getting available files */ lib_function_start("\t- Available files"); gx_snprintf(path, sizeof(path), "C,D=%i/L,V=%i/C,D=%i", PRV_FIELDLIST, PR_DF_RFID_FIELDS|PR_DFE_DOCUMENT_DESCRIPTOR, PRV_RFIDDIR); if ( !pr_resolverfiddata(hpr, data, sdata, &pdoc) || !gx_convertvariantbypatha(pdoc, path, 0, GX_VARIANT_INT, &srfid_files, 0, &rfid_files, srfid_files) ) { lib_displ_err(); if (pdoc) gx_disposevariant(&pdoc); if (data) {gx_globalfree(data); data = NULL; sdata = 0;} continue; } if (pdoc) gx_disposevariant(&pdoc); if (data) {gx_globalfree(data); data = NULL; sdata = 0;} for (i=PR_RFID_EF_DG1; i<=PR_RFID_EF_DG16; i++) if (((1<<i) & rfid_files)) lib_write("DG%i ", i); lib_function_end(); /* Reading available files, saving and resolving them */ for (i=PR_RFID_EF_DG1; i<=PR_RFID_EF_DG2; i++) { if (!((1<<i) & rfid_files)) continue; gx_snprintf(fn, 32, "EF_DG%i.dat", i); lib_function_start("Reading %s", fn); if (pr_getrfidfilea(hpr, cardlist[0], i, &data, &sdata)) lib_function_end(); else {lib_displ_err(); continue;} lib_function_start("\t- Saving %s", fn); if (!lib_save(fn, data, sdata)) lib_error("File write error!"); else lib_function_end(); if (i == PR_RFID_EF_DG1) resolve_dg1(hpr, data, sdata); if (i == PR_RFID_EF_DG2) resolve_dg2(hpr, data, sdata); if (data) {gx_globalfree(data); data = NULL; sdata = 0;} } /* Disconnecting from the chip */ lib_function_start("Disconnecting from the RFID chip"); if (pr_disconnectrfidcarda(hpr, cardlist[0])) lib_function_end(); else lib_displ_err(); } while(false); } if (cardlist) {gx_globalfree(cardlist); cardlist = NULL;} } else { lib_displ_err(); } lib_process_end(); lib_wait_for_sec(3); } /* Closing the device */ lib_function_start("Closing the device"); if (pr_closedevice(hpr)) { lib_function_end(); } else { lib_displ_err(); } /* Closing the PR system */ lib_function_start("Closing the PR system"); if (gx_closehandle(&hpr)) { lib_function_end(); } else { lib_displ_err(); } return lib_print_stat(); }
The needed gxsdldr.c loader file is included directly:
The __lib__.h
file contains some library functions used only in the sample programs, such as the lib_function_start
and lib_function_end
functions that implement the simple command line interface and measures the elapsed time between the two function calls.
#include "../__lib__.h"
The load_certificates helper function, loading the certificate files:
/* The load_certificates helper function, loading the certificate files */ int load_certificates(gxHANDLE hpr) { int i,l; char *pk; char **list = NULL; /* Loading certificates */ l = lib_filelist("../../../data/certs", "*.cer", &list); for (i=0; i<l; i++) { lib_function_start("Loading sample certificate: %s", list[i]); if (pr_loadcertfilea(hpr, list[i], NULL)) lib_function_end(); else lib_displ_err(); free(list[i]); } /* Loading CV certificates */ l = lib_filelist("../../../data/certs", "*.cvcert", &list); for (i=0; i<l; i++) { lib_function_start("Loading sample CV certificate: %s", list[i]); pk = (char*)malloc(strlen(list[i]) - strlen("cvcert") + strlen("pkcs8") + 1); if (pk) { gx_strncpy(pk, list[i], strlen(list[i]) - strlen("cvcert") + 1); gx_strncpy(pk + strlen(list[i]) - strlen("cvcert"), "pkcs8", strlen("pkcs8") + 1); } if (pr_loadcertfilea(hpr, list[i], lib_isfile(pk) ? pk: NULL)) lib_function_end(); else lib_displ_err(); free(list[i]); if (pk) free(pk); } return 0; }
The make_bac helper function, reading MRZ from the document and using it to make BAC:
/* The make_bac helper function, reading MRZ from the document and using it to make BAC */ int make_bac(gxHANDLE hpr, char* card) { int j,l; gxVARIANT pdoc; int pages; char *mrz[3]; /* Setting only infra light for capture */ lib_function_start("\t- Setting infra light"); if (pr_getlightmask(hpr,&pages,PR_LIGHT_INFRA,0) && pr_setpagelight(hpr,1,(gxu32*)&pages)) lib_function_end(); else return lib_displ_err(); /* Capturing images */ lib_function_start("\t- Capturing images"); if (pr_capture(hpr)) lib_function_end(); else return lib_displ_err(); /* Reading MRZ */ lib_function_start("\t- Reading MRZ"); if (pr_getmrz(hpr, 0, PR_LIGHT_INFRA, PR_IT_ORIGINAL, &pdoc)) lib_function_end(); else return lib_displ_err(); if (!pdoc) {printf("No MRZ data found!\n"); return -1;} for (j=0; j<3; j++) { mrz[j] = (char*) malloc(45); memset(mrz[j], 0 ,45); l = 45; pr_getfieldfromdoca(hpr, pdoc, PR_DF_MRZ1 + j, mrz[j], &l, 0, 0); } gx_disposevariant(&pdoc); /* Making BAC */ lib_function_start("\t- Making BAC"); if (pr_makebaca(hpr, card, (const char **)mrz, strlen(mrz[2]) ? 3 : 2)) { for (j=0; j<3; j++) free(mrz[j]); lib_function_end(); } else { for (j=0; j<3; j++) free(mrz[j]); return lib_displ_err(); } return 0; }
The resolve_dg1 helper function, parsing EF_DG1
and displaying MRZ information:
/* The resolve_dg1 helper function, parsing EF_DG1 and displaying MRZ information */ int resolve_dg1(gxHANDLE hpr, void * data, int sdata) { int error_code = 0; gxVARIANT pdoc; char text[256]; int stext; lib_function_start("\t- Resolving DG1"); if (pr_resolverfiddata(hpr, data, sdata, &pdoc)) { if (!pdoc) lib_error("No MRZ data found!"); else { lib_function_end(); lib_write_line("\t- MRZ data:"); stext = sizeof(text); if (pr_getfieldfromdoca(hpr, pdoc, PR_DF_RFID_MRZ, text, &stext, NULL, 0)) { char s[45]; gx_snprintf(s, 44, text); s[44] = 0; lib_write_line("\t\t %s", s); gx_snprintf(s, 44, text+44); s[44] = 0; lib_write_line("\t\t %s", s); } else { error_code = lib_displ_err(); } if (pdoc) gx_disposevariant(&pdoc); } } else { error_code = lib_displ_err(); } return error_code; }
The resolve_dg2 helper function, parsing EF_DG2
and saving the face image:
/* The resolve_dg2 helper function, parsing EF_DG2 and saving the face image */ int resolve_dg2(gxHANDLE hpr, void * data, int sdata) { int error_code = 0; gxVARIANT pdoc; gxIMAGE *img = NULL; lib_function_start("\t- Resolving"); if (pr_resolverfiddata(hpr, data, sdata, &pdoc)) { if (!pdoc) lib_error("No image data found!"); else { lib_function_end(); lib_function_start("\t- Saving image"); if (pr_getgximagefromdoc(hpr, pdoc, PR_DF_RFID_FACE, &img)) { if (gx_saveimagea(gx_direct(GX_CALL_GROUP_GX_IMAGE), img, "face.jpg", GX_JPEG)) lib_function_end(); else error_code = lib_displ_err(); gx_unrefimage(gx_direct(GX_CALL_GROUP_GX_IMAGE), img); } else { error_code = lib_displ_err(); } if (pdoc) gx_disposevariant(&pdoc); } } else { error_code = lib_displ_err(); } return error_code; }
The main function:
int main() { int i; char ** cardlist=0; int numcards=0; void * data=NULL; int sdata = 0, srfid_files = 4; unsigned int rfid_files = 0; char path[64], fn[32]; gxVARIANT pdoc = NULL;
Opening the Passport Reader system:
/* Opening the PR system */ gxHANDLE hpr; /* handle for the PR system */ lib_function_start("Opening system files"); if (gx_openmodulea(&hpr,"prapi","default")) lib_function_end(); else { lib_displ_err(); return 0; }
Connecting to the first device. If no device is connected then the pr_usedevicen() function returns false and the program ends:
/* Connecting to the first device */ lib_function_start("Connecting to the first device"); if (pr_usedevicen(hpr,0,PR_UMODE_FULL_CONTROL)) { lib_function_end(); } else { lib_displ_err(); gx_closehandle(&hpr); return 0; }
Loading the certificates for authentication:
/* Loading certificates */ lib_write_line("Loading certificates"); load_certificates(hpr);
The main loop begins:
while(!lib_kbhit()) { lib_process_start("RFID");
Searching for RFID cards:
/* Searching for RFID cards */ lib_function_start("Searching for RFID cards ..."); if (pr_getrfidcardlista(hpr, &cardlist, &numcards)) { lib_function_end();
Connecting to the first chip:
/* Connecting to the first chip */ lib_function_start("Connecting to the RFID chip"); if (pr_connectrfidcarda(hpr, cardlist[0])) lib_function_end(); else { lib_displ_err(); continue; } lib_write_line("Serial no.: %s", cardlist[0]);
Reading EF_COM first to determine the available files on the chip. In case of BAC protected chip the reading process returns GX_EACCES, which means that the Basic Access Control procedure must be executed in order to access the chip.
/* Initializing chip reading */ lib_function_start("Initializing chip reading"); if (pr_getrfidfilea(hpr, cardlist[0], PR_RFID_EF_COM, &data, &sdata)) lib_function_end(); else { lib_displ_err(); if (gx_geterrorcode() != GX_EACCES) continue; if(make_bac(hpr, cardlist[0])) continue; lib_function_start("Initializing chip reading"); if (pr_getrfidfilea(hpr, cardlist[0], PR_RFID_EF_COM, &data, &sdata)) lib_function_end(); else {lib_displ_err(); continue;} }
Parsing the EF_COM
and getting the information about the available files on the chip:
/* Getting available files */ lib_function_start("\t- Available files"); gx_snprintf(path, sizeof(path), "C,D=%i/L,V=%i/C,D=%i", PRV_FIELDLIST, PR_DF_RFID_FIELDS|PR_DFE_DOCUMENT_DESCRIPTOR, PRV_RFIDDIR); if ( !pr_resolverfiddata(hpr, data, sdata, &pdoc) || !gx_convertvariantbypatha(pdoc, path, 0, GX_VARIANT_INT, &srfid_files, 0, &rfid_files, srfid_files) ) { lib_displ_err(); if (pdoc) gx_disposevariant(&pdoc); if (data) {gx_globalfree(data); data = NULL; sdata = 0;} continue; } if (pdoc) gx_disposevariant(&pdoc); if (data) {gx_globalfree(data); data = NULL; sdata = 0;} for (i=PR_RFID_EF_DG1; i<=PR_RFID_EF_DG16; i++) if (((1<<i) & rfid_files)) lib_write("DG%i ", i); lib_function_end();
Making Passive Authentication to check the integrity of the chip data:
/* Making Passive Authentication */ lib_function_start("\t- Making Passive Authentication"); if (pr_makepassiveautha(hpr, cardlist[0])) lib_function_end(); else lib_displ_err();
Making Active Authentication if EF_DG15
exists:
/* Making Active Authentication */ if ((1 << PR_RFID_EF_DG15) & rfid_files) { lib_function_start("\t- Making Active Authentication"); if (pr_makeactiveautha(hpr, cardlist[0])) lib_function_end(); else lib_displ_err(); }
Reading available files, saving and resolving them
/* Reading available files, saving and resolving them */ for (i=PR_RFID_EF_DG1; i<=PR_RFID_EF_DG16; i++) { if (i == PR_RFID_EF_DG3 || i == PR_RFID_EF_DG4) continue; if (!((1<<i) & rfid_files)) continue; gx_snprintf(fn, 32, "EF_DG%i.dat", i); lib_function_start("Reading %s", fn); if (pr_getrfidfilea(hpr, cardlist[0], i, &data, &sdata)) lib_function_end(); else {lib_displ_err(); continue;} lib_function_start("\t- Saving %s", fn); if (!lib_save(fn, data, sdata)) lib_error("File write error!"); else lib_function_end(); if (i == PR_RFID_EF_DG1) resolve_dg1(hpr, data, sdata); if (i == PR_RFID_EF_DG2) resolve_dg2(hpr, data, sdata); if (data) {gx_globalfree(data); data = NULL; sdata = 0;} }
Disconnecting from the chip:
/* Disconnecting from the chip */ lib_function_start("Disconnecting from the RFID chip"); if (pr_disconnectrfidcarda(hpr, cardlist[0])) lib_function_end(); else lib_displ_err();
The main loop ends:
lib_process_end(); lib_wait_for_sec(3); }
Closing the device:
/* Closing the device */ lib_function_start("Closing the device"); if (pr_closedevice(hpr)) { lib_function_end(); } else { lib_displ_err(); }
Closing the Passport Reader system:
/* Closing the PR system */ lib_function_start("Closing the PR system"); if (gx_closehandle(&hpr)) { lib_function_end(); } else { lib_displ_err(); }
The sample program ends printing some statistic information:
return lib_print_stat();
}
The complete source code:
#include "prapi.h" #include "gxsdldr.c" #include "../__lib__.h" /* The load_certificates helper function, loading the certificate files */ int load_certificates(gxHANDLE hpr) { int i,l; char *pk; char **list = NULL; /* Loading certificates */ l = lib_filelist("../../../data/certs", "*.cer", &list); for (i=0; i<l; i++) { lib_function_start("Loading sample certificate: %s", list[i]); if (pr_loadcertfilea(hpr, list[i], NULL)) lib_function_end(); else lib_displ_err(); free(list[i]); } /* Loading CV certificates */ l = lib_filelist("../../../data/certs", "*.cvcert", &list); for (i=0; i<l; i++) { lib_function_start("Loading sample CV certificate: %s", list[i]); pk = (char*)malloc(strlen(list[i]) - strlen("cvcert") + strlen("pkcs8") + 1); if (pk) { gx_strncpy(pk, list[i], strlen(list[i]) - strlen("cvcert") + 1); gx_strncpy(pk + strlen(list[i]) - strlen("cvcert"), "pkcs8", strlen("pkcs8") + 1); } if (pr_loadcertfilea(hpr, list[i], lib_isfile(pk) ? pk: NULL)) lib_function_end(); else lib_displ_err(); free(list[i]); if (pk) free(pk); } return 0; } /* The make_bac helper function, reading MRZ from the document and using it to make BAC */ int make_bac(gxHANDLE hpr, char* card) { int j,l; gxVARIANT pdoc; int pages; char *mrz[3]; /* Setting only infra light for capture */ lib_function_start("\t- Setting infra light"); if (pr_getlightmask(hpr,&pages,PR_LIGHT_INFRA,0) && pr_setpagelight(hpr,1,(gxu32*)&pages)) lib_function_end(); else return lib_displ_err(); /* Capturing images */ lib_function_start("\t- Capturing images"); if (pr_capture(hpr)) lib_function_end(); else return lib_displ_err(); /* Reading MRZ */ lib_function_start("\t- Reading MRZ"); if (pr_getmrz(hpr, 0, PR_LIGHT_INFRA, PR_IT_ORIGINAL, &pdoc)) lib_function_end(); else return lib_displ_err(); if (!pdoc) {printf("No MRZ data found!\n"); return -1;} for (j=0; j<3; j++) { mrz[j] = (char*) malloc(45); memset(mrz[j], 0 ,45); l = 45; pr_getfieldfromdoca(hpr, pdoc, PR_DF_MRZ1 + j, mrz[j], &l, 0, 0); } gx_disposevariant(&pdoc); /* Making BAC */ lib_function_start("\t- Making BAC"); if (pr_makebaca(hpr, card, (const char **)mrz, strlen(mrz[2]) ? 3 : 2)) { for (j=0; j<3; j++) free(mrz[j]); lib_function_end(); } else { for (j=0; j<3; j++) free(mrz[j]); return lib_displ_err(); } return 0; } /* The resolve_dg1 helper function, parsing EF_DG1 and displaying MRZ information */ int resolve_dg1(gxHANDLE hpr, void * data, int sdata) { int error_code = 0; gxVARIANT pdoc; char text[256]; int stext; lib_function_start("\t- Resolving DG1"); if (pr_resolverfiddata(hpr, data, sdata, &pdoc)) { if (!pdoc) lib_error("No MRZ data found!"); else { lib_function_end(); lib_write_line("\t- MRZ data:"); stext = sizeof(text); if (pr_getfieldfromdoca(hpr, pdoc, PR_DF_RFID_MRZ, text, &stext, NULL, 0)) { char s[45]; gx_snprintf(s, 44, text); s[44] = 0; lib_write_line("\t\t %s", s); gx_snprintf(s, 44, text+44); s[44] = 0; lib_write_line("\t\t %s", s); } else { error_code = lib_displ_err(); } if (pdoc) gx_disposevariant(&pdoc); } } else { error_code = lib_displ_err(); } return error_code; } /* The resolve_dg2 helper function, parsing EF_DG2 and saving the face image */ int resolve_dg2(gxHANDLE hpr, void * data, int sdata) { int error_code = 0; gxVARIANT pdoc; gxIMAGE *img = NULL; lib_function_start("\t- Resolving"); if (pr_resolverfiddata(hpr, data, sdata, &pdoc)) { if (!pdoc) lib_error("No image data found!"); else { lib_function_end(); lib_function_start("\t- Saving image"); if (pr_getgximagefromdoc(hpr, pdoc, PR_DF_RFID_FACE, &img)) { if (gx_saveimagea(gx_direct(GX_CALL_GROUP_GX_IMAGE), img, "face.jpg", GX_JPEG)) lib_function_end(); else error_code = lib_displ_err(); gx_unrefimage(gx_direct(GX_CALL_GROUP_GX_IMAGE), img); } else { error_code = lib_displ_err(); } if (pdoc) gx_disposevariant(&pdoc); } } else { error_code = lib_displ_err(); } return error_code; } int main() { int i; char ** cardlist=0; int numcards=0; void * data=NULL; int sdata = 0, srfid_files = 4; unsigned int rfid_files = 0; char path[64], fn[32]; gxVARIANT pdoc = NULL; /* Opening the PR system */ gxHANDLE hpr; /* handle for the PR system */ lib_function_start("Opening system files"); if (gx_openmodulea(&hpr,"prapi","default")) lib_function_end(); else { lib_displ_err(); return 0; } /* Connecting to the first device */ lib_function_start("Connecting to the first device"); if (pr_usedevicen(hpr,0,PR_UMODE_FULL_CONTROL)) { lib_function_end(); } else { lib_displ_err(); gx_closehandle(&hpr); return 0; } /* Loading certificates */ lib_write_line("Loading certificates"); load_certificates(hpr); while(!lib_kbhit()) { lib_process_start("RFID"); /* Searching for RFID cards */ lib_function_start("Searching for RFID cards ..."); if (pr_getrfidcardlista(hpr, &cardlist, &numcards)) { lib_function_end(); if (numcards == 0) { lib_write_line("No card found"); } else { lib_write_line(""); do { /* Connecting to the first chip */ lib_function_start("Connecting to the RFID chip"); if (pr_connectrfidcarda(hpr, cardlist[0])) lib_function_end(); else { lib_displ_err(); continue; } lib_write_line("Serial no.: %s", cardlist[0]); /* Initializing chip reading */ lib_function_start("Initializing chip reading"); if (pr_getrfidfilea(hpr, cardlist[0], PR_RFID_EF_COM, &data, &sdata)) lib_function_end(); else { lib_displ_err(); if (gx_geterrorcode() != GX_EACCES) continue; if(make_bac(hpr, cardlist[0])) continue; lib_function_start("Initializing chip reading"); if (pr_getrfidfilea(hpr, cardlist[0], PR_RFID_EF_COM, &data, &sdata)) lib_function_end(); else {lib_displ_err(); continue;} } /* Getting available files */ lib_function_start("\t- Available files"); gx_snprintf(path, sizeof(path), "C,D=%i/L,V=%i/C,D=%i", PRV_FIELDLIST, PR_DF_RFID_FIELDS|PR_DFE_DOCUMENT_DESCRIPTOR, PRV_RFIDDIR); if ( !pr_resolverfiddata(hpr, data, sdata, &pdoc) || !gx_convertvariantbypatha(pdoc, path, 0, GX_VARIANT_INT, &srfid_files, 0, &rfid_files, srfid_files) ) { lib_displ_err(); if (pdoc) gx_disposevariant(&pdoc); if (data) {gx_globalfree(data); data = NULL; sdata = 0;} continue; } if (pdoc) gx_disposevariant(&pdoc); if (data) {gx_globalfree(data); data = NULL; sdata = 0;} for (i=PR_RFID_EF_DG1; i<=PR_RFID_EF_DG16; i++) if (((1<<i) & rfid_files)) lib_write("DG%i ", i); lib_function_end(); /* Making Passive Authentication */ lib_function_start("\t- Making Passive Authentication"); if (pr_makepassiveautha(hpr, cardlist[0])) lib_function_end(); else lib_displ_err(); /* Making Active Authentication */ if ((1 << PR_RFID_EF_DG15) & rfid_files) { lib_function_start("\t- Making Active Authentication"); if (pr_makeactiveautha(hpr, cardlist[0])) lib_function_end(); else lib_displ_err(); } /* Reading available files, saving and resolving them */ for (i=PR_RFID_EF_DG1; i<=PR_RFID_EF_DG16; i++) { if (i == PR_RFID_EF_DG3 || i == PR_RFID_EF_DG4) continue; if (!((1<<i) & rfid_files)) continue; gx_snprintf(fn, 32, "EF_DG%i.dat", i); lib_function_start("Reading %s", fn); if (pr_getrfidfilea(hpr, cardlist[0], i, &data, &sdata)) lib_function_end(); else {lib_displ_err(); continue;} lib_function_start("\t- Saving %s", fn); if (!lib_save(fn, data, sdata)) lib_error("File write error!"); else lib_function_end(); if (i == PR_RFID_EF_DG1) resolve_dg1(hpr, data, sdata); if (i == PR_RFID_EF_DG2) resolve_dg2(hpr, data, sdata); if (data) {gx_globalfree(data); data = NULL; sdata = 0;} } /* Disconnecting from the chip */ lib_function_start("Disconnecting from the RFID chip"); if (pr_disconnectrfidcarda(hpr, cardlist[0])) lib_function_end(); else lib_displ_err(); } while(false); } if (cardlist) {gx_globalfree(cardlist); cardlist = NULL;} } else { lib_displ_err(); } lib_process_end(); lib_wait_for_sec(3); } /* Closing the device */ lib_function_start("Closing the device"); if (pr_closedevice(hpr)) { lib_function_end(); } else { lib_displ_err(); } /* Closing the PR system */ lib_function_start("Closing the PR system"); if (gx_closehandle(&hpr)) { lib_function_end(); } else { lib_displ_err(); } return lib_print_stat(); }
The needed gxsdldr.c loader file is included directly:
The __lib__.h
file contains some library functions used only in the sample programs, such as the lib_function_start
and lib_function_end
functions that implement the simple command line interface and measures the elapsed time between the two function calls.
The load_certificates helper function, loading the certificate files:
The make_bac helper function, reading MRZ from the document and using it to make BAC:
The resolve_dg1 helper function, parsing EF_DG1
and displaying MRZ information:
The resolve_dg2 helper function, parsing EF_DG2
and saving the face image:
The main function:
Opening the Passport Reader system:
Connecting to the first device. If no device is connected then the pr_usedevicen() function returns false and the program ends:
Loading the certificates for authentication:
The main loop begins:
Searching for RFID cards:
Connecting to the first chip:
Reading EF_COM first to determine the available files on the chip. In case of BAC protected chip the reading process returns GX_EACCES, which means that the Basic Access Control procedure must be executed in order to access the chip.
Parsing the EF_COM
and getting the information about the available files on the chip:
Making Chip Authentication if EF_DG14
exists:
Making Passive Authentication to check the integrity of the chip data:
Making Active Authentication if EF_DG15
exists:
Making Terminal Authentication if EF_DG14
exists:
Reading available files, checking the hash, saving and resolving them:
Disconnecting from the chip:
The main loop ends:
Closing the device:
Closing the Passport Reader system:
The sample program ends printing some statistic information:
The complete source code: