Home | History | Annotate | Download | only in zfm20
      1 /*
      2  * Author: Jon Trulson <jtrulson (at) ics.com>
      3  * Copyright (c) 2015 Intel Corporation.
      4  *
      5  * Thanks to Adafruit for supplying a google translated version of the
      6  * Chinese datasheet and some clues in their code.
      7  *
      8  * Permission is hereby granted, free of charge, to any person obtaining
      9  * a copy of this software and associated documentation files (the
     10  * "Software"), to deal in the Software without restriction, including
     11  * without limitation the rights to use, copy, modify, merge, publish,
     12  * distribute, sublicense, and/or sell copies of the Software, and to
     13  * permit persons to whom the Software is furnished to do so, subject to
     14  * the following conditions:
     15  *
     16  * The above copyright notice and this permission notice shall be
     17  * included in all copies or substantial portions of the Software.
     18  *
     19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     20  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     22  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
     23  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     24  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     25  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     26  */
     27 #pragma once
     28 
     29 #include <string>
     30 #include <iostream>
     31 
     32 #include <stdint.h>
     33 #include <stdlib.h>
     34 #include <unistd.h>
     35 #include <string.h>
     36 #include <fcntl.h>
     37 #include <errno.h>
     38 #include <termios.h>
     39 #include <sys/time.h>
     40 #include <sys/select.h>
     41 #include <sys/types.h>
     42 #include <sys/stat.h>
     43 
     44 #include <mraa/uart.h>
     45 
     46 #define ZFM20_DEFAULT_UART 0
     47 
     48 // protocol start codes
     49 #define ZFM20_START1 0xef
     50 #define ZFM20_START2 0x01
     51 
     52 #define ZFM20_MAX_PKT_LEN 256
     53 
     54 #define ZFM20_TIMEOUT 5000 // in ms
     55 
     56 #define ZFM20_DEFAULT_PASSWORD 0x00000000
     57 #define ZFM20_DEFAULT_ADDRESS  0xffffffff
     58 
     59 
     60 namespace upm {
     61     /**
     62      * @brief ZFM-20 Fingerprint Sensor Module library
     63      * @defgroup zfm20 libupm-zfm20
     64      * @ingroup seeed uart touch
     65      */
     66 
     67     /**
     68      * @library zfm20
     69      * @sensor zfm20
     70      * @comname ZFM-20 Fingerprint Sensor
     71      * @altname Grove Fingerprint Sensor
     72      * @type touch
     73      * @man seeed
     74      * @con uart
     75      *
     76      * @brief API for the ZFM-20 Fingerprint Sensor Module
     77      *
     78      * This class was tested on the Grove Fingerprint Sensor
     79      * Module. It can store up to 163 fingerprints.
     80      *
     81      * It is connected via a UART at 57,600 baud.
     82      *
     83      * @image html zfm20.jpg
     84      * This example demonstrates how to register and store a new fingerprint
     85      * @snippet zfm20-register.cxx Interesting
     86      * This example demonstrates reading a fingerprint and locating it in the DB
     87      * @snippet zfm20.cxx Interesting
     88      */
     89   class ZFM20 {
     90   public:
     91 
     92     // commands
     93     typedef enum {
     94       CMD_GEN_IMAGE                     = 0x01,
     95       CMD_IMG2TZ                        = 0x02,
     96       CMD_MATCH                         = 0x03,
     97       CMD_SEARCH                        = 0x04,
     98       CMD_REGMODEL                      = 0x05,
     99       CMD_STORE                         = 0x06,
    100       CMD_LOAD_TMPL                     = 0x07,
    101       CMD_UPLOAD_TMPL                   = 0x08,
    102       CMD_DOWNLOAD_TMPL                 = 0x09,
    103       CMD_UPLOAD_IMAGE                  = 0x0a,
    104       CMD_DOWNLOAD_IMAGE                = 0x0b,
    105       CMD_DELETE_TMPL                   = 0x0c,
    106       CMD_EMPTYDB                       = 0x0d,
    107       CMD_SET_SYSPARAMS                 = 0x0e,
    108       CMD_GET_SYSPARAMS                 = 0x0f,
    109       CMD_SET_PASSWORD                  = 0x12,
    110       CMD_VERIFY_PASSWORD               = 0x13,
    111       CMD_GET_RANDOM_NUMBER             = 0x14,
    112       CMD_SET_ADDRESS                   = 0x15,
    113       CMD_GET_TMPL_COUNT                = 0x1d,
    114       CMD_GET_INDEX_TABLE               = 0x1f
    115     } ZFM20_COMMAND_T;
    116 
    117     // Error response codes
    118     typedef enum {
    119       ERR_OK                            = 0x00,
    120       ERR_PACKET_RX_ERROR               = 0x01,
    121       ERR_NO_FINGER                     = 0x02,
    122       ERR_FP_IMAGE_FAILED               = 0x03,
    123       ERR_FP_TOO_MESSY                  = 0x06,
    124       ERR_FP_IMAGE_FEW_FEATURES         = 0x07,
    125       ERR_FP_NOMATCH                    = 0x08,
    126       ERR_FP_NOTFOUND                   = 0x09,
    127       ERR_FP_ENROLLMISMATCH             = 0x0a,
    128       ERR_BAD_LOCATION                  = 0x0b,
    129       ERR_DB_ERROR                      = 0x0c,
    130       ERR_UPLOAD_FEAT_FAILED            = 0x0d,
    131       ERR_NO_MORE_PACKETS               = 0x0e,
    132       ERR_UPLOAD_IMG_FAILED             = 0x0f,
    133       ERR_RM_TMPL_FAILED                = 0x10,
    134       ERR_EMPTY_DB_FAILED               = 0x11,
    135       ERR_INVALID_PWD                   = 0x13,
    136       ERR_INVALID_IMAGE                 = 0x15,
    137       ERR_RW_FLASH_ERROR                = 0x18,
    138       ERR_INVALID_REG                   = 0x1a,
    139       ERR_INVALID_ADDR                  = 0x20,
    140       ERR_NEEDS_PWD                     = 0x21,
    141       // end of module-specific errors
    142       ERR_INTERNAL_ERR                  = 0xff  // API internal error
    143     } ZFM20_ERRORS_T;
    144 
    145     typedef enum {
    146       PKT_COMMAND                       = 0x01,
    147       PKT_DATA                          = 0x02,
    148       PKT_ACK                           = 0x07,
    149       PKT_END_DATA                      = 0x08
    150     } ZFM20_PKTCODES_T;
    151 
    152     /**
    153      * ZFM20 constructor
    154      *
    155      * @param uart Default UART to use (0 or 1)
    156      */
    157     ZFM20(int uart);
    158 
    159     /**
    160      * ZFM20 destructor
    161      */
    162     ~ZFM20();
    163 
    164     /**
    165      * Checks to see if there is data available for reading
    166      *
    167      * @param millis Number of milliseconds to wait; 0 means no waiting
    168      * @return true if there is data available for reading
    169      */
    170     bool dataAvailable(unsigned int millis);
    171 
    172     /**
    173      * Reads any available data in a user-supplied buffer. Note: the
    174      * call blocks until data is available to be read. Use
    175      * dataAvailable() to determine whether there is data available
    176      * beforehand, to avoid blocking.
    177      *
    178      * @param buffer Buffer to hold the data read
    179      * @param len Length of the buffer
    180      * @return Number of bytes read
    181      */
    182     int readData(char *buffer, int len);
    183 
    184     /**
    185      * Writes the data in the buffer to the device
    186      *
    187      * @param buffer Buffer to hold the data read
    188      * @param len Length of the buffer
    189      * @return Number of bytes written
    190      */
    191     int writeData(char *buffer, int len);
    192 
    193     /**
    194      * Sets up proper tty I/O modes and the baud rate. For this device,
    195      * the default baud rate is 57,600 (B57600).
    196      *
    197      * @param baud Desired baud rate.
    198      * @return True if successful
    199      */
    200     bool setupTty(speed_t baud=B57600);
    201 
    202     /**
    203      * Composes and writes a command packet
    204      *
    205      * @param pkt Packet
    206      * @param len Length of packet
    207      * @return Number of bytes written
    208      */
    209     int writeCmdPacket(uint8_t *pkt, int len);
    210 
    211     /**
    212      * Verifies the packet header and indicates its validity
    213      *
    214      * @param pkt Packet to check
    215      * @param len Length of packet
    216      * @return True if the packet is valid, false otherwise
    217      */
    218     bool verifyPacket(uint8_t *pkt, int len);
    219 
    220     /**
    221      * Returns the number of milliseconds elapsed since initClock()
    222      * was last called
    223      *
    224      * @return Elapsed milliseconds
    225      */
    226     uint32_t getMillis();
    227 
    228     /**
    229      * Resets the clock
    230      *
    231      */
    232     void initClock();
    233 
    234     /**
    235      * Sets the address that should be used to access the module
    236      *
    237      * @param addr Address to use
    238      */
    239     void setAddress(uint32_t addr) { m_address = addr; };
    240 
    241     /**
    242      * Sets the password that should be used to access the module
    243      *
    244      * @param pw Password to use
    245      */
    246     void setPassword(uint32_t pw) { m_password = pw; };
    247 
    248     /**
    249      * Gets the returned data from a request
    250      *
    251      * @param pkt Buffer to store the returned data
    252      * @param len Expected response length; pkt should be at least this
    253      * large
    254      * @return True if successful
    255      */
    256     bool getResponse(uint8_t *pkt, int len);
    257 
    258     /**
    259      * Verifies and authenticates to the module. The password used is
    260      * the last one set by setPassword().
    261      *
    262      * @return True if successful
    263      */
    264     bool verifyPassword();
    265 
    266     /**
    267      * Queries the module for the number of stored templates
    268      * (fingerprints).
    269      *
    270      * @return Number of currently stored templates
    271      */
    272     int getNumTemplates();
    273 
    274     /**
    275      * Sets a new password for the module. This passowrd is
    276      * stored in the module, and is required to access
    277      * the module in the future.
    278      *
    279      * @param pwd New password to set on the module
    280      * @return True if successful
    281      */
    282     bool setNewPassword(uint32_t pwd);
    283 
    284     /**
    285      * Sets a new address for the module. This address is
    286      * stored in the module, and is required to access
    287      * the module in the future.
    288      *
    289      * @param addr New address to set on the module
    290      * @return True if successful
    291      */
    292     bool setNewAddress(uint32_t addr);
    293 
    294     /**
    295      * Generates a new fingerprint image (scans a fingerprint)
    296      *
    297      * @return One of the ZFM20_ERRORS_T values
    298      */
    299     uint8_t generateImage();
    300 
    301     /**
    302      * Converts the image in the image buffer (generated by
    303      * generateImage()) and stores it in one of the two characteristics
    304      * buffers, 1 or 2
    305      *
    306      * @param slot Characteristics buffer to use; must be 1 or 2
    307      * @return One of the ZFM20_ERRORS_T values
    308      */
    309     uint8_t image2Tz(int slot);
    310 
    311     /**
    312      * Based on the two characteristics buffers (1 & 2), creates a
    313      * fingerprint model. Once a model is successfully created,
    314      * it can be stored in the module with storeModel().
    315      *
    316      * @return One of the ZFM20_ERRORS_T values
    317      */
    318     uint8_t createModel();
    319 
    320     /**
    321      * Once a fingerprint model is created, this method can be
    322      * used to store it (via one of the characteristics buffers) in a
    323      * given location.
    324      *
    325      * @param slot Characteristics buffer to store the model, 1 or 2
    326      * @param id Location to store the model
    327      * @return One of the ZFM20_ERRORS_T values
    328      */
    329     uint8_t storeModel(int slot, uint16_t id);
    330 
    331     /**
    332      * Deletes a stored model
    333      *
    334      * @param id Location containing the model to delete
    335      * @return One of the ZFM20_ERRORS_T values
    336      */
    337     uint8_t deleteModel(uint16_t id);
    338 
    339     /**
    340      * Deletes the model database (DB)
    341      *
    342      * @return One of the ZFM20_ERRORS_T values
    343      */
    344     uint8_t deleteDB();
    345 
    346     /**
    347      * Searches the fingerprint DB and returns an ID and score, if found
    348      *
    349      *
    350      * @param slot Slot containing a converted image to search for
    351      * @param id ID if found, 0 otherwise
    352      * @param score Score if found, 0 otherwise
    353      * @return One of the ZFM20_ERRORS_T values
    354      */
    355     uint8_t search(int slot, uint16_t *id, uint16_t *score);
    356 
    357     /**
    358      * Compares the features in characteristics buffers 1 and 2 and
    359      * returns a score if they match
    360      *
    361      * @param score Score
    362      * @return One of the ZFM20_ERRORS_T values
    363      */
    364     uint8_t match(uint16_t *score);
    365 
    366 
    367   protected:
    368     int ttyFd() { return m_ttyFd; };
    369 
    370   private:
    371     mraa_uart_context m_uart;
    372     int m_ttyFd;
    373     uint32_t m_password;
    374     uint32_t m_address;
    375     struct timeval m_startTime;
    376   };
    377 }
    378 
    379 
    380