Advertisement
Guest User

fpserv_async.cpp

a guest
Jun 5th, 2012
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.14 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #include <unistd.h>
  6. #include <signal.h>
  7.  
  8. #include "fpserv_async.h"
  9.  
  10. // Notes: you cannot call a Start function from a callback. I don't know why;
  11. // libfprint throws an error.
  12. bool FPReader::fp_initialized = false;
  13.  
  14. void FPReader::InitializeFP() {
  15.   if(fp_init() != 0) {
  16.     printf("ERROR: libfprint failed to initialize\n");
  17.     exit(0);
  18.   }
  19.   fp_set_debug(1000);
  20.  
  21.   fp_initialized = true;
  22. }
  23.  
  24. FPReader::FPReader() {
  25.   if(!fp_initialized) {
  26.     FPReader::InitializeFP();
  27.     fp_initialized = true;
  28.   }
  29.  
  30.   device = NULL;
  31.   state = NONE;
  32.   next = NONE;
  33.  
  34.   db = new DB();
  35.   if(db) {
  36.     users = db->GetUsers();
  37.     printf("Loaded %d fingerprints.\n", users.size());
  38.   } else {
  39.     printf("Fingerprint DB failed to load.");
  40.   }
  41.  
  42.   user_array = NULL;
  43.   SetUsersArray();
  44.  
  45.   OpenDevice();
  46. }
  47.  
  48. FPReader::~FPReader() {
  49.   if(device) {
  50.     fp_dev_close(device);
  51.   }
  52.   fp_exit();
  53. }
  54.  
  55. // This marks a new state that we hope to be in.
  56. // Eventually, FPReader will swing itself around to be in this state.
  57. // Try calling UpdateState a few times.
  58. void FPReader::ChangeState(SingleState newstate) {
  59.   printf("Changing state from %s to %s.\n", STATESTRING(state), STATESTRING(newstate));
  60.   next = newstate;
  61. }
  62.  
  63. // Effects a state change.
  64. // If called with NONE, will look at the next instance variable
  65. void FPReader::UpdateState() {
  66.   if(state == NONE && next == IDENTIFYING) {
  67.     StartIdentify();
  68.     state = IDENTIFYING;
  69.     next = NONE;
  70.   }
  71.   if(state == NONE && next == ENROLLING) {
  72.     StartEnroll();
  73.     state = ENROLLING;
  74.     next = NONE;
  75.   }
  76.  
  77.   if(state == WAITING && next == IDENTIFYING) {
  78.     // Do nothing
  79.   }
  80.   if(state == WAITING && next == ENROLLING) {
  81.     // Do nothing
  82.   }
  83.  
  84.   //if(state == IDENTIFYING && next == IDENTIFYING) {
  85.   //  next = NONE;
  86.   //}
  87.   //if(state == ENROLLING && next == ENROLLING) {
  88.   //  next = NONE;
  89.   //}
  90.  
  91.   if(state == ENROLLING && next == IDENTIFYING) {
  92.     // We need this handler to finish before we can call StartIdentify.
  93.     // The next call to ChangeState will handle this case.
  94.     StopEnroll();
  95.   }
  96.   if(state == IDENTIFYING && next == ENROLLING) {
  97.     StopIdentify();
  98.   }
  99. }
  100.  
  101. void FPReader::SetUsername(std::string username) {
  102.   enrollingUser = username;
  103. }
  104.  
  105. void FPReader::AddUser(User* u) {
  106.   if(user_array) {
  107.     free(user_array);
  108.   }
  109.   if(db) {
  110.     if(db->SaveUser(u)) {
  111.       printf("User saved\n");
  112.     } else {
  113.       printf("User saving failed\n");
  114.     }
  115.   }
  116.  
  117.   users.push_back(u);
  118.   SetUsersArray();
  119. }
  120.  
  121. void FPReader::SetUsersArray() {
  122.   user_array = (fp_print_data**) malloc(sizeof(fp_print_data*) * (users.size()+1));
  123.   int i = 0;
  124.   for(std::vector<User*>::iterator iter = users.begin();
  125.       iter < users.end();
  126.       iter++, i++) {
  127.     user_array[i] = (*iter)->print;
  128.   }
  129.   user_array[users.size()] = NULL;
  130. }
  131.  
  132. void FPReader::OpenCallback(int status) {
  133.   // Probably won't use? Figure out.
  134. }
  135.  
  136. void FPReader::EnrollStageCallback(int result, struct fp_print_data* print, struct fp_img* img) {
  137.   printf("Enroll stage callbacked!");
  138.   if(result < 0) {
  139.     printf("result negative: %d\n", result);
  140.   }
  141.  
  142.   User* u;
  143.  
  144.   switch (result) {
  145.     case FP_ENROLL_COMPLETE:
  146.       u = new User(print, enrollingUser);
  147.       AddUser(u);
  148.       SendLearnGood(u);
  149.       StopEnroll();
  150.       break;
  151.     case FP_ENROLL_PASS:
  152.       SendLearnBad("Please try again.");
  153.       break;
  154.     case FP_ENROLL_FAIL:
  155.       SendLearnBad("Failed. Please try again.");
  156.       break;
  157.     case FP_ENROLL_RETRY:
  158.       SendLearnBad("Bad scan. Please try again.");
  159.       break;
  160.     case FP_ENROLL_RETRY_TOO_SHORT:
  161.       SendLearnBad("Swipe too short. Please try again.");
  162.       break;
  163.     case FP_ENROLL_RETRY_CENTER_FINGER:
  164.       SendLearnBad("Finger not centered. Please try again.");
  165.       break;
  166.     case FP_ENROLL_RETRY_REMOVE_FINGER:
  167.       SendLearnBad("Remove your finger and try again.");
  168.       break;
  169.     default:
  170.       SendLearnBad("Unknown error in enrollment!");
  171.   }
  172.  
  173.   if(img) {
  174.     fp_img_save_to_file(img, "file.pgm");
  175.     fp_img_free(img);
  176.   }
  177.   if(print && result != FP_ENROLL_COMPLETE) {
  178.     fp_print_data_free(print);
  179.   }
  180. }
  181.  
  182. void FPReader::EnrollStopCallback() {
  183.   //TODO: assert state == WAITING
  184.   state = NONE;
  185.   printf("Enroll stopped.\n");
  186.  
  187.   ChangeState(IDENTIFYING);
  188. }
  189.  
  190. void FPReader::IdentifyCallback(int result, size_t match_offset, struct fp_img *img) {
  191.   printf("Identify callbacked\n");
  192.   // If we don't immediately stop, the driver gets all excited.
  193.   // In our StopIdentify handler, we'll start identifying again
  194.   StopIdentify();
  195.  
  196.   // Mark down that we want to continue identifying
  197.   next = IDENTIFYING;
  198.  
  199.   switch(result) {
  200.     case FP_VERIFY_NO_MATCH:
  201.       // Did not find
  202.       SendBadRead("Fingerprint not recognized.");
  203.       break;
  204.     case FP_VERIFY_MATCH:
  205.       // Found it
  206.       SendGoodRead(users[match_offset]);
  207.       break;
  208.     case FP_VERIFY_RETRY:
  209.       // poor scan quality
  210.       SendBadRead("Fingerprint failed due to poor scan quality.");
  211.       break;
  212.     case FP_VERIFY_RETRY_TOO_SHORT:
  213.       // swipe too short. Not an issue with this reader.
  214.       SendBadRead("Fingerprint failed. Try again.");
  215.       break;
  216.     case FP_VERIFY_RETRY_CENTER_FINGER:
  217.       // center finger.
  218.       SendBadRead("Fingerprint failed. Center your finger and try again.");
  219.       break;
  220.     case FP_VERIFY_RETRY_REMOVE_FINGER:
  221.       // pressed too hard
  222.       SendBadRead("Fingerprint failed. Lift your finger and try again.");
  223.       break;
  224.     default:
  225.       SendBadRead("Fingerprint failed for an uknown reason.");
  226.       break;
  227.   }
  228.  
  229.   if(img) {
  230.     fp_img_free(img);
  231.   }
  232. }
  233.  
  234. void FPReader::IdentifyStopCallback() {
  235.   //TODO: assert state == WAITING
  236.   state = NONE;
  237.   printf("Identify stopped\n");
  238. }
  239.  
  240.  
  241. int FPReader::StartEnroll() {
  242.   printf("StartEnroll()\n");
  243.   state = ENROLLING;
  244.   return fp_async_enroll_start(device, &enroll_stage_cb, this);
  245. }
  246.  
  247. int FPReader::StopEnroll() {
  248.   state = WAITING;
  249.   printf("StopEnroll()\n");
  250.   return fp_async_enroll_stop(device, &enroll_stop_cb, this);
  251. }
  252. int FPReader::StartIdentify() {
  253.   printf("StartIdentify()\n");
  254.   state = IDENTIFYING;
  255.   return fp_async_identify_start(device, user_array, &identify_cb, this);
  256. }
  257. int FPReader::StopIdentify() {
  258.   state = WAITING;
  259.   printf("StopIdentify()\n");
  260.   return fp_async_identify_stop(device, &identify_stop_cb, this);
  261. }
  262.  
  263. User::User(fp_print_data* fingerprint_, std::string username_) {
  264.   print = fingerprint_;
  265.   username = username_;
  266. }
  267.  
  268. // By using this, you ignore the case where there might be multiple devices.
  269. // You _must_ have called fp_init before calling this function.
  270. bool FPReader::OpenDevice() {
  271.   fp_dscv_dev** handle = NULL;
  272.   fp_dscv_dev** p = NULL;
  273.   fp_dev* to_ret = NULL;
  274.  
  275.   handle = fp_discover_devs();
  276.   if(!handle) {
  277.     return NULL;
  278.   }
  279.  
  280.   p = handle;
  281.   while(*p) {
  282.     device = fp_dev_open(*p);
  283.  
  284.     printf("after open: 0x%x\n", device);
  285.     if(device) {
  286.       break;
  287.     }
  288.  
  289.     p++;
  290.   }
  291.  
  292.   // TODO: if device is null, throw an exception
  293.  
  294.   fp_dscv_devs_free(handle);
  295. }
  296.  
  297. void FPReader::SendGoodRead(User* u) {
  298.   if(u) {
  299.     printf("Sending good read for %s\n", u->username.c_str());
  300.     sio_write(SIO_DATA, "FP-GOODREAD\t%s", u->username.c_str());
  301.   } else {
  302.     sio_write(SIO_DATA, "FP-GOODREAD\t%s", "bad-user:null-pointer");
  303.   }
  304. }
  305. void FPReader::SendBadRead(std::string message) {
  306.   printf("Sending bad read: %s\n", message.c_str());
  307.   sio_write(SIO_DATA, "FP-BADREAD\t%s", message.c_str());
  308. }
  309. void FPReader::SendLearnGood(User* u) {
  310.   printf("Sending learn-good]n");
  311.   sio_write(SIO_DATA, "FP-LEARN-GOOD");
  312. }
  313. void FPReader::SendLearnBad(std::string message) {
  314.   printf("Sending learn-fail: %s\n", message.c_str());
  315.   sio_write(SIO_DATA, "FP-LEARN-FAIL\t%s", message.c_str());
  316. }
  317.  
  318. //int main(int argc, char** argv) {
  319. //  FPReader fp;
  320. //  std::string s = "kmowery";
  321. //
  322. //  fp.SetUsername(s);
  323. //  fp.StartEnroll();
  324. //
  325. //  while(true) {
  326. //    fp_handle_events();
  327. //    fp.UpdateState();
  328. //  }
  329. //
  330. //  printf("complete\n");
  331. //}
  332.  
  333. void dev_open_cb(struct fp_dev* dev,
  334.                  int status,
  335.                  void *user_data) {
  336.   if(user_data) {
  337.     ((FPReader*) user_data)->OpenCallback(status);
  338.   }
  339. }
  340.  
  341. void enroll_stage_cb(struct fp_dev *dev,
  342.                      int result,
  343.                      struct fp_print_data *print,
  344.                      struct fp_img *img,
  345.                      void *user_data) {
  346.   if(user_data) {
  347.     ((FPReader*) user_data)->EnrollStageCallback(result, print, img);
  348.   }
  349. }
  350. void enroll_stop_cb(struct fp_dev *dev,
  351.                     void *user_data) {
  352.   if(user_data) {
  353.     ((FPReader*) user_data)->EnrollStopCallback();
  354.   }
  355. }
  356. void identify_cb(struct fp_dev *dev,
  357.                  int result,
  358.                  size_t match_offset,
  359.                  struct fp_img *img,
  360.                  void *user_data) {
  361.   if(user_data) {
  362.     ((FPReader*) user_data)->IdentifyCallback(result, match_offset, img);
  363.   }
  364. }
  365. void identify_stop_cb(struct fp_dev *dev,
  366.                       void *user_data) {
  367.   if(user_data) {
  368.     ((FPReader*) user_data)->IdentifyStopCallback();
  369.   }
  370. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement