Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Jan 26th, 2011  |  syntax: C  |  size: 27.58 KB  |  views: 238  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /* 2008-2009 (C) Upek, inc.
  2.  * BSAPI sample Biometry
  3.  *
  4.  * This sample shows how to manage set of templates in memory. It allows to
  5.  * add new templates into the set (enroll), delete a finger from the template
  6.  * set and match finger against the template set or one finger from it.
  7.  *
  8.  * Real application could store the templates in database and make other
  9.  * complex things.
  10.  */
  11.  
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <assert.h>
  16. #include <dirent.h>
  17. #include <sys/types.h>
  18.  
  19. #if defined __APPLE__  &&  defined __MACH__
  20.     #include <BSApi/bsapi.h>  /* Mac OS X */
  21. #else
  22.     #include <bsapi.h>  /* other OSes */
  23. #endif
  24.  
  25.  
  26. /* Used to supress compiler warnings */
  27. #ifndef UNREFERENCED_PARAMETER
  28.     #define UNREFERENCED_PARAMETER(param)   (void)param
  29. #endif
  30.  
  31.  
  32. /* Writes info about last error.
  33.  */
  34. static void
  35. status_info(ABS_STATUS status)
  36. {
  37.     ABS_DWORD code;
  38.     const ABS_CHAR* message;
  39.    
  40.     if(status == ABS_STATUS_OK)
  41.         return;
  42.    
  43.     /* ABSGetLastErrorInfo() provides some diagnostical informations
  44.      * about the last BSAPI error which occured in the current thread.
  45.      *
  46.      * Please note that in real applications these informations are
  47.      * not intended for end user.
  48.      */
  49.     ABSGetLastErrorInfo(&code, &message);
  50.     printf("   status: %ld\n", (long)status);
  51.     printf("   code:   %ld\n", (long)code);
  52.     printf("   message: '%s'\n", message);
  53. }
  54.  
  55.  
  56. /* Callback is the primary way how the interactive biometric operations
  57.  * can interract with the user. Each BSAPI function which expects user
  58.  * to interact with the fingerprint sensor, takes poitner to structure
  59.  * ABS_OPERATION as a parameter. One of its members is poitner to a
  60.  * function.
  61.  *
  62.  * BSAPI uses the function as a communication channel between the biometry
  63.  * logic and user.
  64.  *
  65.  * The callback is the way how to bind the biometry to GUI in your
  66.  * applications.
  67.  */
  68. static void BSAPI
  69. callback(const ABS_OPERATION* p_operation, ABS_DWORD msg, void* data)
  70. {
  71.     UNREFERENCED_PARAMETER(p_operation);
  72.    
  73.     switch(msg) {
  74.         /* These messages just inform us how the interactive operation
  75.          * progresses. Typical applications do not need it. */
  76.         case ABS_MSG_PROCESS_BEGIN:
  77.         case ABS_MSG_PROCESS_END:
  78.             break;
  79.            
  80.         /* On some platforms, the biometric operastion can be suspended
  81.          * when other process acquires sensor for other operation. */
  82.         case ABS_MSG_PROCESS_SUSPEND:
  83.             printf("   operation has been suspended\n");
  84.             break;
  85.         case ABS_MSG_PROCESS_RESUME:
  86.             printf("   operation has been resumed\n");
  87.             break;
  88.            
  89.         /* Sometimes some info how the operation progresses is sent. */
  90.         case ABS_MSG_PROCESS_PROGRESS:
  91.         {
  92.             ABS_PROCESS_PROGRESS_DATA* progress_data =
  93.                                     (ABS_PROCESS_PROGRESS_DATA*) data;
  94.             if(progress_data->Percentage <= 100) {
  95.                 printf("   operation in progress (%d%%)...\n",
  96.                                             (int)progress_data->Percentage);
  97.             } else {
  98.                 printf("   operation in progress...\n");
  99.             }
  100.             break;
  101.         }
  102.         case ABS_MSG_PROCESS_SUCCESS:
  103.             printf("   success\n");
  104.             break;
  105.         case ABS_MSG_PROCESS_FAILURE:
  106.             printf("   failure\n");
  107.             break;
  108.        
  109.         /* Prompt messages should inform the user that he should do
  110.          * something. */
  111.         case ABS_MSG_PROMPT_SCAN:
  112.             printf("   swipe the finger\n");
  113.             break;
  114.         case ABS_MSG_PROMPT_TOUCH:
  115.             printf("   touch the sensor\n");
  116.             break;
  117.         case ABS_MSG_PROMPT_KEEP:
  118.             printf("   keep finger on the sensor\n");
  119.             break;
  120.         case ABS_MSG_PROMPT_LIFT:
  121.             printf("   lift your finger away from the sensor\n");
  122.             break;
  123.         case ABS_MSG_PROMPT_CLEAN:
  124.             printf("   clean the sensor\n");
  125.             break;
  126.        
  127.         /* Quality messages come if something went wrong. E.g. the user
  128.          * did not scan his finger in the right way. */
  129.         case ABS_MSG_QUALITY_CENTER_HARDER:
  130.             printf("   bad quality: center and harder\n");
  131.             break;
  132.         case ABS_MSG_QUALITY_CENTER:
  133.             printf("   bad quality: center\n");
  134.             break;
  135.         case ABS_MSG_QUALITY_TOO_LEFT:
  136.             printf("   bad quality: too left\n");
  137.             break;
  138.         case ABS_MSG_QUALITY_TOO_RIGHT:
  139.             printf("   bad quality: too right\n");
  140.             break;
  141.         case ABS_MSG_QUALITY_HARDER:
  142.             printf("   bad quality: harder\n");
  143.             break;
  144.         case ABS_MSG_QUALITY_TOO_LIGHT:
  145.             printf("   bad quality: too light\n");
  146.             break;
  147.         case ABS_MSG_QUALITY_TOO_DRY:
  148.             printf("   bad quality: too dry\n");
  149.             break;
  150.         case ABS_MSG_QUALITY_TOO_SMALL:
  151.             printf("   bad quality: too small\n");
  152.             break;
  153.         case ABS_MSG_QUALITY_TOO_SHORT:
  154.             printf("   bad quality: too short\n");
  155.             break;
  156.         case ABS_MSG_QUALITY_TOO_HIGH:
  157.             printf("   bad quality: too high\n");
  158.             break;
  159.         case ABS_MSG_QUALITY_TOO_LOW:
  160.             printf("   bad quality: too low\n");
  161.             break;
  162.         case ABS_MSG_QUALITY_TOO_FAST:
  163.             printf("   bad quality: too fast\n");
  164.             break;
  165.         case ABS_MSG_QUALITY_TOO_SKEWED:
  166.             printf("   bad quality: too skewed\n");
  167.             break;
  168.         case ABS_MSG_QUALITY_TOO_DARK:
  169.             printf("   bad quality: too dark\n");
  170.             break;
  171.         case ABS_MSG_QUALITY_BACKWARD:
  172.             printf("   bad quality: backward movement detected\n");
  173.             break;
  174.         case ABS_MSG_QUALITY_JOINT:
  175.             printf("   bad quality: joint detected\n");
  176.             break;
  177.        
  178.         /* Navigation messages are sent only from ABSNavigate. Its not used
  179.          * in this sample but we list the messages here for completeness. */
  180.         case ABS_MSG_NAVIGATE_CHANGE:
  181.         case ABS_MSG_NAVIGATE_CLICK:
  182.             break;
  183.            
  184.         /* Real application would probably use some GUI to provide feedback
  185.          * for user. On these messages the GUI dialog should be made vsiible
  186.          * and invisible respectivelly. */
  187.         case ABS_MSG_DLG_SHOW:
  188.         case ABS_MSG_DLG_HIDE:
  189.             break;
  190.            
  191.         /* Idle message can come only if flag ABS_OPERATION_FLAG_USE_IDLE
  192.          * was specified in ABS_OPERATION::dwFlags (i.e. never in this sample).
  193.          * If the flag is specified, this message comes very often, hence
  194.          * giving the callback a chance to cancel the operation with
  195.          * ABSCancelOperation() without long time delays. In multithreaded
  196.          * applications, canceling the operation from another thread can be
  197.          * better alternative. Consult BSAPI documentation for more info about
  198.          * the topic. */
  199.         case ABS_MSG_IDLE:
  200.             break;
  201.     }
  202. }
  203.  
  204.  
  205. /* Maximal template set size. */
  206. #define TSET_SIZE        16
  207.  
  208. /* We use trivial template set representation, as an array of pointers
  209.  * to ABS_BIR. Unused slots are set to NULL. */
  210. static ABS_BIR* tset[TSET_SIZE];
  211.  
  212. /* 0 - BIR was obtained via a ABS_* call (and thus should be freed
  213.  *     by ABSFree()),
  214.  * 1 - BIR was created manually and should be freed with free(). */
  215. static char tsetAttr[TSET_SIZE];
  216.  
  217. /* BSAPI session handle. */
  218. static ABS_CONNECTION conn = 0;
  219.  
  220.  
  221.  
  222. /* Pointer to ABS_OPERATION is taken as a parameter by those BSAPI
  223.  * funtions which work as interactive operation. The main purpose of it is
  224.  * to pass pointer to the callback function into the interactive functions.
  225.  *
  226.  * It also allows to specifie some flags and/or timeout.
  227.  *
  228.  * In this sample we reuse this one operation instance. In real complex
  229.  * application you may need to use special ABS_OPERATION instance for
  230.  * each BSAPI interactive operation. This allows you to use specialized
  231.  * callback for them, past various flags etc.
  232.  */
  233. static ABS_OPERATION op = {
  234.     /* ID of the operation. We don't need to identify the operation in this
  235.      * sample. When non-zero, the ID identifies the operation and allows it
  236.      * to be canceled from any other thread with ABSCancelOperation(). */
  237.     0,        
  238.    
  239.     /* Arbitrary pointer, which allows application to pass any data into
  240.      * the callback. Not used in this sample. */
  241.     NULL,      
  242.    
  243.     /* Pointer to a simple callback implementation function. */
  244.     callback,  
  245.    
  246.     /* Timeout. For example, lets set timeout to 60 sec. Note the value does
  247.      * not limit how long the operation (e.g. ABSVerify()) can take. The
  248.      * timeout only specifies time the operation waits for user to put his
  249.      * finger on a sensor. Zero would mean no timeout (i.e. the operation can
  250.      * never end if user never puts his finger on the sensor.) */
  251.     60000,
  252.    
  253.     /* By default BSAPI places short time delays between sending some important
  254.      * callback messages. The purpose of this is to guarantee that if multiple
  255.      * messages come very closely in sequence, then the user still has enough
  256.      * time to see all the messages and not just the lat one of the fast
  257.      * sequence.
  258.      *
  259.      * For application developer, this simplifies callback implementation
  260.      * which in most cases can be just showing an appropriate message in a
  261.      * window or dialog.
  262.      *
  263.      * However the time delays are not needed when user can see all history
  264.      * of the messages, e.g. (as in this sample) the messages are outputted
  265.      * to standard output stream. Hence we disable the time delays with with
  266.      * the flag ABS_OPERATION_FLAG_LL_CALLBACK here. */
  267.     ABS_OPERATION_FLAG_LL_CALLBACK
  268. };
  269.  
  270.  
  271. /* Helper function, asking the user to choose what slot in the template set
  272.  * to work with. Returns number of the slot or -1 if the slot can not be used.
  273.  */
  274. static int
  275. choose_slot(const char* msg)
  276. {
  277.     int slot;
  278.    
  279.     printf("%s: ", msg);
  280.     scanf("%d", &slot);
  281.     if(slot < 0  ||  slot >= TSET_SIZE) {
  282.         printf("No such slot.\n");
  283.         return -1;
  284.     }
  285.     if(tset[slot] == NULL) {
  286.         printf("Slot %d is not enrolled.\n", slot);
  287.         return -1;
  288.     }
  289.    
  290.     return slot;
  291. }
  292.  
  293. /* Open BSAPI session. Note that this sample allows only one session
  294.  * at a time to be opened. */
  295. static void
  296. cmd_open(void)
  297. {
  298.     ABS_STATUS res;
  299.     ABS_DEVICE_LIST* dev_list;
  300.     int dev_index;
  301.    
  302.     printf("Openening a session...\n");
  303.    
  304.     /* Check whether it's not already open. It is possible to use multiple
  305.      * sessions from one process, but it would make this sample much more
  306.      * copmplex, and most applications do not need that anyway. */
  307.     if(conn != 0) {
  308.         printf("The session is already open.\n");
  309.         return;
  310.     }
  311.    
  312.     /* Enumerate all supported USB devices and decide which one of them to
  313.      * use. */
  314.     res = ABSEnumerateDevices("usb", &dev_list);
  315.     if(res != ABS_STATUS_OK) {
  316.         printf("ABSEnumerateDevices() failed.\n");
  317.         status_info(res);
  318.         return;
  319.     }
  320.     if(dev_list->NumDevices == 0) {
  321.         printf("No fingerprint device found.\n");
  322.         return;
  323.     }
  324.     if(dev_list->NumDevices == 1) {
  325.         /* There is a single device, so take it. */
  326.         dev_index = 0;
  327.     } else {
  328.         /* There is more then one device connected: Ask user which one
  329.          * of them to use. */
  330.         int i;
  331.        
  332.         printf("Found devices: \n");
  333.         for(i = 0; i < (int)dev_list->NumDevices; i++)
  334.             printf("   %d  %s\n", i, dev_list->List[i].DsnSubString);
  335.         printf("Enter number of device you want to use: ");
  336.         scanf("%d", &dev_index);
  337.         if(dev_index < 0  ||  dev_index >= (int)dev_list->NumDevices) {
  338.             printf("No such device.\n");
  339.             return;
  340.         }
  341.     }
  342.    
  343.     /* Open the selected device. */
  344.     printf("Opening device '%s'...\n", dev_list->List[dev_index].DsnSubString);
  345.     res = ABSOpen(dev_list->List[dev_index].DsnSubString, &conn);
  346.     if(res != ABS_STATUS_OK) {
  347.         ABSFree(dev_list);
  348.         printf("ABSOpen() failed.\n");
  349.         status_info(res);
  350.         return;
  351.     }
  352.    
  353.     /* Release memory allocated for the device list. */
  354.     ABSFree(dev_list);
  355.    
  356.     printf("Opened successfully.\n");
  357. }
  358.  
  359. /* Close BSAPI session */
  360. static void
  361. cmd_close(void)
  362. {
  363.     ABS_STATUS res;
  364.    
  365.     printf("Closing the current session...\n");
  366.    
  367.     /* close the connection */    
  368.     res = ABSClose(conn);
  369.     if(res != ABS_STATUS_OK) {
  370.         printf("ABSClose() failed.\n");
  371.         status_info(res);
  372.         return;
  373.     }
  374.     conn = 0;
  375. }
  376.  
  377. /* Add (enroll) new template into the template set. */
  378. static void
  379. cmd_add(void)
  380. {
  381.     int i;
  382.     int slot = -1;
  383.     ABS_STATUS res;
  384.    
  385.     printf("Add new template...\n");
  386.    
  387.     /* find an empty slot */
  388.     for(i = 0; i < TSET_SIZE; i++) {
  389.         if(tset[i] == NULL) {
  390.             slot = i;
  391.             break;
  392.         }
  393.     }    
  394.     if(slot < 0) {
  395.         printf("Cannot add new template. The template set is full.\n");
  396.         return;
  397.     }
  398.    
  399.     /* enroll the tamplate into the slot */
  400.     res = ABSEnroll(conn, &op, &tset[slot], 0);
  401.     if(res != ABS_STATUS_OK) {
  402.         printf("ABSEnroll() failed.\n");
  403.         status_info(res);
  404.         return;
  405.     }
  406.    
  407.     printf("Successfully enrolled into the template set as slot #%d.\n", slot);
  408. }
  409.  
  410. /* Import a template from a file into the template set. */
  411. static void
  412. cmd_import(void)
  413. {
  414.     int i;
  415.     int slot = -1;
  416.     char templateFileName[1024];
  417.     FILE *f;
  418.     long fileSize;
  419.    
  420.     printf("Import a template...\n");
  421.    
  422.     /* find an empty slot */
  423.     for(i = 0; i < TSET_SIZE; i++) {
  424.         if(tset[i] == NULL) {
  425.             slot = i;
  426.             break;
  427.         }
  428.     }    
  429.     if(slot < 0) {
  430.         printf("Cannot add new template. The template set is full.\n");
  431.         return;
  432.     }
  433.    
  434.     /* ask user for the filename */
  435.     printf("Please enter template file name: ");
  436.     if (scanf("%s", templateFileName) != 1) {
  437.         printf("Cannot get the file name.\n");
  438.         return;
  439.     }
  440.  
  441.     f = fopen(templateFileName, "rb");
  442.     if (f == NULL) {
  443.         printf("Cannot open file '%s'.\n", templateFileName);
  444.         return;
  445.     }
  446.  
  447.     if (fseek(f, 0, SEEK_END) != 0) {
  448.         printf("Cannot seek in file '%s'.\n", templateFileName);
  449.         fclose(f);
  450.         return;
  451.     }
  452.  
  453.     fileSize = ftell(f);
  454.     if (fileSize < 0) {
  455.         printf("Cannot determine the size of file '%s'.\n", templateFileName);
  456.         fclose(f);
  457.         return;
  458.     }
  459.  
  460.     if (fseek(f, 0, SEEK_SET) != 0) {
  461.         printf("Cannot seek back in file '%s'.\n", templateFileName);
  462.         fclose(f);
  463.         return;
  464.     }
  465.  
  466.     tset[slot] = (ABS_BIR*)malloc(fileSize);
  467.     if (tset[slot] == NULL) {
  468.         printf("Cannot allocate %ld bytes.\n", fileSize);
  469.         fclose(f);
  470.         return;
  471.     }
  472.  
  473.     if (fread(tset[slot], fileSize, 1, f) != 1) {
  474.         printf("Cannot read %ld bytes from file '%s'.\n", fileSize,
  475.             templateFileName);
  476.         free(tset[slot]);
  477.         tset[slot] = NULL;
  478.         fclose(f);
  479.         return;
  480.     }
  481.  
  482.     tsetAttr[slot] = 1;
  483.  
  484.     fclose(f);
  485.     printf("Successfully imported into the template set as slot #%d.\n", slot);
  486. }
  487.  
  488. /* Export a template from the template set into a file. */
  489. static void
  490. cmd_export(void)
  491. {
  492.     int slot;
  493.     char templateFileName[1024];
  494.     FILE *f;
  495.  
  496.     printf("Exporting a template from the template set...\n");
  497.  
  498.     /* Ask user which templates to compare */
  499.     slot = choose_slot("Enter slot number of template to export");
  500.     if(slot < 0)
  501.         return;
  502.  
  503.     /* ask user for the filename */
  504.     printf("Please enter template file name: ");
  505.     if (scanf("%s", templateFileName) != 1) {
  506.         printf("Cannot get the file name.\n");
  507.         return;
  508.     }
  509.  
  510.     f = fopen(templateFileName, "wb");
  511.     if (f == NULL) {
  512.         printf("Cannot open file '%s'.\n", templateFileName);
  513.         return;
  514.     }
  515.  
  516.     if (fwrite(tset[slot], tset[slot]->Header.Length, 1, f) != 1) {
  517.         printf("Cannot write %u bytes to file '%s'.\n",
  518.             tset[slot]->Header.Length, templateFileName);
  519.         fclose(f);
  520.         return;
  521.     }
  522.  
  523.     fclose(f);
  524.     printf("Successfully exported template from the slot #%d to file '%s'.\n",
  525.         slot, templateFileName);
  526. }
  527.  
  528. /* Remove one slot from the template set */
  529. static void
  530. cmd_delete(void)
  531. {
  532.     int slot;
  533.    
  534.     printf("Delete a template from the template set...\n");
  535.    
  536.     /* Ask user which slot to delete */
  537.     slot = choose_slot("Enter slot number to delete from template set");
  538.     if(slot < 0)
  539.         return;
  540.    
  541.     /* And just do it */
  542.     if (tsetAttr[slot] != 0)
  543.         free(tset[slot]);
  544.     else
  545.         ABSFree(tset[slot]);
  546.     tset[slot] = NULL;
  547.     printf("Successfully deleted slot %d\n", slot);
  548. }
  549. static void
  550. cmd_import_all(void)
  551. {
  552.     int i;
  553.     int slot = -1;
  554.         FILE *f;
  555.     long fileSize;
  556.        
  557.         DIR *dp;
  558.         struct dirent *ep;
  559.         chdir("/tmp/lates/");  
  560.         dp = opendir ("./");
  561.  
  562. if (dp != NULL)
  563.   {
  564.     while (ep = readdir (dp)){
  565.          
  566.                 if(ep->d_name[0]=='.') continue;
  567.                 int l = strlen(s); if (s[l - 1] != 't' && s[l - 2] != '.') continue;
  568.                         for(i = 0; i < TSET_SIZE; i++) {
  569.         if(tset[i] == NULL) {
  570.             slot = i;
  571.             break;
  572.         }
  573.     }    
  574.                         if(slot < 0) {
  575.                                 printf("Cannot add new template. The template set is full.\n");
  576.                                 return;
  577.     }
  578.                         printf(ep->d_name);
  579.                         f = fopen(ep->d_name, "rb");
  580.                         if (f == NULL) {
  581.                                 printf("Cannot open file '%s'.\n", ep->d_name);
  582.                                 return;
  583.     }
  584.  
  585.                         if (fseek(f, 0, SEEK_END) != 0) {
  586.                                 printf("Cannot seek in file '%s'.\n", ep->d_name);
  587.                                 fclose(f);
  588.                         return;
  589.     }
  590.  
  591.                         fileSize = ftell(f);
  592.                         if (fileSize < 0) {
  593.                                 printf("Cannot determine the size of file '%s'.\n", ep->d_name);
  594.                                 fclose(f);
  595.                                 return;
  596.     }
  597.  
  598.                         if (fseek(f, 0, SEEK_SET) != 0) {
  599.                                 printf("Cannot seek back in file '%s'.\n", ep->d_name);
  600.                                 fclose(f);
  601.                                 return;
  602.     }
  603.  
  604.                         tset[slot] = (ABS_BIR*)malloc(fileSize);
  605.                         if (tset[slot] == NULL) {
  606.                                 printf("Cannot allocate %ld bytes.\n", fileSize);
  607.                                 fclose(f);
  608.                                 return;
  609.     }
  610.  
  611.                         if (fread(tset[slot], fileSize, 1, f) != 1) {
  612.                                 printf("Cannot read %ld bytes from file '%s'.\n", fileSize,
  613.                                 ep->d_name);
  614.                                 free(tset[slot]);
  615.                                 tset[slot] = NULL;
  616.                                 fclose(f);
  617.                                 return;
  618.     }
  619.  
  620.                         tsetAttr[slot] = 1;
  621.  
  622.                         fclose(f);
  623.         }
  624.     (void) closedir (dp);
  625.         }
  626. }
  627. /* Remove all templates stored in the template set */
  628. static void
  629. cmd_delete_all(void)
  630. {
  631.     int i;
  632.    
  633.     printf("Delete all templates from the template set...\n");
  634.    
  635.     /* Remove all templates in the template set */
  636.     for(i = 0; i < TSET_SIZE; i++) {
  637.         if(tset[i] != NULL) {
  638.             if (tsetAttr[i] != 0)
  639.                 free(tset[i]);
  640.             else
  641.                 ABSFree(tset[i]);
  642.             tset[i] = NULL;
  643.         }
  644.     }
  645.     printf("Successfully deleted all slots\n");
  646. }
  647.  
  648. /* This function only lists which slots on the template sets are used
  649.  * (i.e. which contain an enrolled template). */
  650. static void
  651. cmd_list(void)
  652. {
  653.     int i;
  654.     int empty = 1;
  655.    
  656.     printf("Listing which slots are used (enrolled)...\n");
  657.     printf("Enrolled slots: ");
  658.    
  659.     for(i = 0; i < TSET_SIZE; i++) {
  660.         if(tset[i] != NULL) {
  661.             printf("%d ", i);
  662.             empty = 0;
  663.         }
  664.     }
  665.    
  666.     if(empty)
  667.         printf("none\n");
  668.     else
  669.         printf("\n");
  670. }
  671.  
  672. /* Verify user's finger against one template in the set */
  673. static void
  674. cmd_verify(void)
  675. {
  676.     int slot;
  677.     ABS_STATUS res;
  678.     ABS_LONG matching_slot;
  679.    
  680.     printf("Verify user's finger against a template in template set...\n");
  681.    
  682.     /* Ask user which template to compare with */
  683.     slot = choose_slot("Enter slot number to match against");
  684.     if(slot < 0)
  685.         return;
  686.    
  687.     /* And just do it. Note that matching_slot is set to index of the
  688.      * matching slot in the template set or -1 is no one matches. Here
  689.      * we pass in only the one template we are interested in, so in case of
  690.      * match it will be zero. */
  691.     res = ABSVerify(conn, &op, 1, &tset[slot], &matching_slot, 0);
  692.     if(res != ABS_STATUS_OK) {
  693.         printf("ABSVerify() failed\n");
  694.         status_info(res);
  695.         return;
  696.     }    
  697.     if(matching_slot == 0) {
  698.         printf("Match\n");
  699.     } else if(matching_slot < 0) {
  700.         printf("No match\n");
  701.     } else {
  702.         /* this never happen */
  703.         assert(0);
  704.     }
  705. }
  706.  
  707. /* Here we compare the user's finger with all templates stored in the set */
  708. static void
  709. cmd_verify_all(void)
  710. {
  711.     int i;
  712.     ABS_BIR* tmp_tset[TSET_SIZE];
  713.     int tmp_slot[TSET_SIZE];
  714.     ABS_DWORD count = 0;
  715.     ABS_STATUS res;
  716.     ABS_LONG index;
  717.    
  718.     printf("Verify user's finger against all templates in template set...\n");
  719.    
  720.     /* Functions ABSVerify accepts an arbitrary count of templates to verify
  721.      * the scanned finger against. It expects pointers to the templates in an
  722.      * array of pointers to ABS_BIR structures. This matches our template
  723.      * set representation, however our template set might have some gaps
  724.      * (NULLs) in the array, so we copy the BIR pointers to a temporary array
  725.      * without the gaps (i.e. NULL values can be only on tail of the array).
  726.      * Therefore we also have to save the original index so we can map the
  727.      * resulting matching index to the original slot number.
  728.      *
  729.      * During the work we also count how many templates are in the set.
  730.      */
  731.     for(i = 0; i < TSET_SIZE; i++) {
  732.         if(tset[i] != NULL) {
  733.             tmp_tset[count] = tset[i];
  734.             tmp_slot[count] = i;
  735.             count++;
  736.         }
  737.     }
  738.     if(count == 0) {
  739.         printf("The template set is empty.\n");
  740.         return;
  741.     }
  742.  
  743.     /* Now we can compare the finger against all the templates in the
  744.      * temporary array */
  745.     res = ABSVerify(conn, &op, count, tmp_tset, &index, 0);
  746.     if(res != ABS_STATUS_OK) {
  747.         printf("ABSVerify() failed\n");
  748.         status_info(res);
  749.         return;
  750.     }
  751.    
  752.     /* Find out the slot number (index in the tset array) */
  753.     if(index >= 0) {
  754.         printf("Slot %d matches.\n", tmp_slot[index]);
  755.     } else {
  756.         printf("No slot matches.\n");
  757.     }
  758. }
  759.  
  760. /* Here we compare two templates from the template set */
  761. static void
  762. cmd_verify_match(void)
  763. {
  764.     int slot1, slot2;
  765.     ABS_STATUS res;
  766.     ABS_BOOL match;
  767.    
  768.     printf("Comparing two templates in the template set...\n");
  769.    
  770.     /* Ask user which templates to compare */
  771.     slot1 = choose_slot("Enter slot number of template 1 to compare");
  772.     if(slot1 < 0)
  773.         return;
  774.     slot2 = choose_slot("Enter slot number of template 2 to compare");
  775.     if(slot2 < 0)
  776.         return;
  777.    
  778.     /* Now compare the two templates. Note this is not interactive operation.
  779.      * I.e. the user is not asked to manipulate with the sensor, nor the
  780.      * function takes pointer to ABS_OPERATION. */
  781.     res = ABSVerifyMatch(conn, tset[slot1], tset[slot2], &match, 0);
  782.     if(res != ABS_STATUS_OK) {
  783.         printf("ABSVerifyMatch() failed.\n");
  784.         status_info(res);
  785.         return;
  786.     }
  787.     if(match)
  788.         printf("Templates %d and %d do match.\n", slot1, slot2);
  789.     else
  790.         printf("Templates %d and %d do NOT match.\n", slot1, slot2);
  791. }
  792.  
  793. /* Writes down simple help. */
  794. static void
  795. cmd_help(void)
  796. {
  797.     printf("Press any of the following keys to do the corresponding action:\n");
  798.     printf("   o ... open BSAPI session\n");
  799.     printf("   c ... close the BSAPI session\n");
  800.     printf("   a ... add new template into the template set\n");
  801.     printf("   i ... import a template into the template set\n");
  802.     printf("   e ... export a template from the template set to a file\n");
  803.     printf("   d ... delete template from the template set\n");
  804.     printf("   D ... delete all templates from the template set\n");
  805.     printf("   l ... list templates in the template set\n");
  806.     printf("   v ... verify finger against one template\n");
  807.     printf("   V ... verify finger against complete template set\n");
  808.     printf("   m ... match two templates from the template set\n");
  809.     printf("   h ... writes down this help message\n");
  810.     printf("   q ... quit this sample program\n");
  811. }
  812.  
  813. int
  814. main(int argc, char** argv)
  815. {
  816.     ABS_STATUS res;
  817.     int i;
  818.     int done = 0;
  819.     char buffer[256];
  820.    
  821.     UNREFERENCED_PARAMETER(argc);
  822.     UNREFERENCED_PARAMETER(argv);
  823.    
  824.     printf(
  825.         "This sample shows BSAPI as it can be used in typical real application\n"
  826.         "The sample keeps a fingerprint template set in memory and provides\n"
  827.         "functions for manipulating with the template set as adding new\n"
  828.         "template into it (enrollment), removing it, various verification\n"
  829.         "and matching functions.\n"
  830.         "\n"
  831.         "Note that when started, it does not open session to the device\n"
  832.         "automatically so before you can use any command operating with\n"
  833.         "the fingerprint device you have to open it with 'o'.\n"
  834.         "\n"
  835.         "In this regard behavior of the sample may differ from real life\n"
  836.         "applications which may call ABSOpen() just after ABSInitialize().\n"
  837.         "\n"
  838.         "This design was chosen so that you can manually close and reopen\n"
  839.         "the session, and that you can see which functions require an open\n"
  840.         "session and which do not.\n"
  841.         "\n"
  842.     );
  843.    
  844.     /* initialize BSAPI */
  845.     res = ABSInitialize();
  846.     if(res != ABS_STATUS_OK) {
  847.         printf("ABSInitilize() failed\n");
  848.         status_info(res);
  849.         return -1;
  850.     }
  851.    
  852.     /* ensure the template set is empty */
  853.     for(i = 0; i < TSET_SIZE; i++)
  854.     {
  855.         tset[i] = NULL;
  856.         tsetAttr[i] = 0;
  857.     }
  858.  
  859.     /* On the start, always show the help */
  860.     cmd_help();
  861.  
  862.     while(!done) {
  863.         /* Ask the use what to do... */
  864.         printf("\n");
  865.         printf("\n>> ");
  866.         scanf("%s", buffer);
  867.        
  868.         /* ...and then just do that. */
  869.         switch(buffer[0]) {
  870.             case 'o': cmd_open(); break;
  871.             case 'c': cmd_close(); break;
  872.             case 'a': cmd_add();  break;
  873.             case 'i': cmd_import();  break;
  874.             case 'e': cmd_export();  break;
  875.             case 'd': cmd_delete(); break;
  876.             case 'D': cmd_delete_all(); break;
  877.             case 'l': cmd_list(); break;
  878.             case 'v': cmd_verify(); break;
  879.             case 'V': cmd_verify_all(); break;
  880.             case 'm': cmd_verify_match(); break;
  881.                         case 'I': cmd_import_all(); break;
  882.             case 'q': done = 1; break;
  883.            
  884.             case '?':
  885.             case 'h': cmd_help(); break;
  886.            
  887.             default:  
  888.                 printf("Unknown command. Press 'h' to get help.\n");
  889.                 break;
  890.         }
  891.     }
  892.  
  893.     /* Release any templates kept in the template set. */
  894.     for(i = 0; i < TSET_SIZE; i++) {
  895.         if(tset[i] != NULL) {
  896.             if (tsetAttr[i] != 0)
  897.                 free(tset[i]);
  898.             else
  899.                 ABSFree(tset[i]);
  900.             tset[i] = NULL;
  901.         }
  902.     }
  903.    
  904.     /* If BSAPI session is opened, close it */
  905.     if(conn != 0)
  906.         cmd_close();
  907.    
  908.     /* Free any resources allocated in ABSInitialize. */
  909.     ABSTerminate();
  910.    
  911.     return 0;
  912. }