Moved all BM-Lite commands to bmlite_if
Updated all BM-Lite commands for hcp_tyny.c compatibility Added callbacks for compatibility with embedded systems Change-Id: I473e3566576da4c6991bffa438fc0dae5a381b4a
This commit is contained in:
parent
a72af76f31
commit
00bb0d53d0
@ -45,6 +45,9 @@ CFLAGS +=\
|
||||
-MP\
|
||||
-Wno-unused-result
|
||||
|
||||
CFLAGS +=\
|
||||
-DBMLITE_USE_CALLBACK
|
||||
|
||||
# C source files
|
||||
C_SRCS = $(wildcard src/*.c)
|
||||
|
||||
|
||||
@ -1,178 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Fingerprint Cards AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef BEP_HOST_IF_H
|
||||
#define BEP_HOST_IF_H
|
||||
|
||||
/**
|
||||
* @file bep_host_if.h
|
||||
* @brief BEP Host Interface API
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "fpc_bep_types.h"
|
||||
// #include "fpc_com_chain.h"
|
||||
|
||||
#include "hcp_tiny.h"
|
||||
|
||||
#define REMOVE_ID_ALL_TEMPLATES 0U
|
||||
|
||||
/**
|
||||
* @brief Sends HCP commands for capturing an image in Bio MCU
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @param[in] timeout Timeout in ms
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_capture(HCP_comm_t *chain, uint16_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Sends HCP commands for enrolling a finger in Bio MCU
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_enroll_finger(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Sends HCP commands for identifying a finger in Bio MCU
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @param[out] template_id Template id that was identified (only valid if match is true)
|
||||
* @param[out] match True if match
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_identify_finger(HCP_comm_t *chain, uint32_t timeout, uint16_t *template_id, bool *match);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Sends HCP commands for saving template of an enrolled finger in Bio MCU
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @param[in] template_id Template id to save
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_save_template(HCP_comm_t *chain, uint16_t template_id);
|
||||
|
||||
/**
|
||||
* @brief Remove template(s) stored
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @param[in] template_id template id to remove, if =REMOVE_ID_ALL_TEMPLATES removes all templates
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_delete_template(HCP_comm_t *chain, uint16_t template_id);
|
||||
|
||||
/**
|
||||
* @brief Gets all template ids from Bio MCU
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @param[out] template_ids Should be allocated by the caller for storing template ids and should
|
||||
* have capacity to hold bio_get_template_count
|
||||
* @param[in] nof_templates This should be acquired using bio_get_template_count
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_get_template_ids(HCP_comm_t *chain, uint16_t *template_ids,
|
||||
uint32_t nof_templates);
|
||||
|
||||
/**
|
||||
* @brief Get the number of templates in Bio MCU
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @param[out] template_count
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_get_template_count(HCP_comm_t *chain, uint32_t *template_count);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Sends HCP commands for extracting a template from a previously capture image in Bio MCU
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_image_extract(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Sends HCP commands for getting the image size of a previously capture image in Bio MCU
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_image_get_size(HCP_comm_t *chain, uint32_t *size);
|
||||
|
||||
/**
|
||||
* @brief Sends HCP commands for getting the image data of a previously capture image in Bio MCU
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_image_get(HCP_comm_t *chain, uint8_t *data, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Sends HCP commands for fetching the version of the Bio MCU FW
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @param[out] version Version string buffer
|
||||
* @param[out] len Length of version string buffer
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_version(HCP_comm_t *chain, char *version, int len);
|
||||
|
||||
/**
|
||||
* @brief Sends HCP commands for resetting the Bio MCU
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_reset(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Sends HCP commands for calibrating the sensor in the Bio MCU
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_sensor_calibrate(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Sends HCP commands for removing the sensor calibration in the Bio MCU
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_sensor_calibrate_remove(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Sends HCP commands for setting the sensor in sleep and waiting for finger in the Bio MCU
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @param[in] timeout Timeout in ms
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_sensor_wait_for_finger(HCP_comm_t *chain, uint16_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Sends HCP commands that returns when finger is not on the sensor in the Bio MCU
|
||||
*
|
||||
* @param[in] chain HCP com chain
|
||||
* @param[in] timeout Timeout in ms
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_sensor_wait_finger_not_present(HCP_comm_t *chain, uint16_t timeout);
|
||||
|
||||
#endif /* BEP_HOST_IF_H */
|
||||
347
BMLite_example/inc/bmlite_if.h
Normal file
347
BMLite_example/inc/bmlite_if.h
Normal file
@ -0,0 +1,347 @@
|
||||
#ifndef BMLITE_IF_H
|
||||
#define BMLITE_IF_H
|
||||
|
||||
#include "hcp_tiny.h"
|
||||
#include "bmlite_if_callbacks.h"
|
||||
|
||||
/**
|
||||
* @brief Build and send command to FPC BM-Lite and receive answer
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @param[in] cmd - BM-Lite command
|
||||
* @param[in] arg_type - Argument without parameters
|
||||
* set to ARG_NONE if the command has no argument
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bmlite_send_cmd(HCP_comm_t *chain, uint16_t cmd, uint16_t arg_type);
|
||||
|
||||
/**
|
||||
* @brief Build and send command with additiona argument with parameters
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @param[in] cmd - BM-Lite command
|
||||
* @param[in] arg1_type - argument 1 without parameters
|
||||
* set to ARG_NONE if the command has no argument without paramener
|
||||
* @param[in] arg2_type - argument 2
|
||||
* @param[in] arg2_data - data pointer for argument 2
|
||||
* set to 0 if argument 2 has no parameter
|
||||
* @param[in] arg2_length - length of data for argument 2
|
||||
* set to 0 if argument 2 has no parameter
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bmlite_send_cmd_arg(HCP_comm_t *chain, uint16_t cmd, uint16_t arg1_type, uint16_t arg2_type, void *arg2_data, uint16_t arg2_length);
|
||||
|
||||
/**
|
||||
* @brief Wait for finger present on sensor"
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @param[in] timeout - timeout (msec). Maximum timeout 65535 msec
|
||||
* set to 0 for waiting indefinitely
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t sensor_wait_finger_present(HCP_comm_t *chain, uint16_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Wait for finger not present on sensor"
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @param[in] timeout - timeout (msec). Maximum timeout 65535 msec
|
||||
* set to 0 for waiting indefinitely
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t sensor_wait_finger_not_present(HCP_comm_t *chain, uint16_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Wait for finger present on sensor and capture image"
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @param[in] timeout - timeout (msec). Maximum timeout 65535 msec
|
||||
* set to 0 for waiting indefinitely
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_capture(HCP_comm_t *chain, uint16_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Get size of captured image
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
*
|
||||
* @param[out] size
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_image_get_size(HCP_comm_t *chain, uint32_t *size);
|
||||
|
||||
/**
|
||||
* @brief Allocates image buffer on FPC BM-LIte
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t image_create(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Deletes image buffer on FPC BM-LIte
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t image_delete(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Pull captured image from FPC BM-Lite
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
*
|
||||
* @param[in] data - pointer to image buffer
|
||||
* @param[in] size - size of the image buffer
|
||||
* if buffer size is not enough the image
|
||||
* will be truncated
|
||||
* chain->arg.size will contain real size of the image
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_image_get(HCP_comm_t *chain, uint8_t *data, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Push image to FPC BM-Lite
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
*
|
||||
* @param[in] data - pointer to image buffer
|
||||
* @param[in] size - size of the image buffer
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_image_put(HCP_comm_t *chain, uint8_t *data, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Extract image features to prepare image for enrolling or matching
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_image_extract(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Identify prepared image against existing templates in Flash storage
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_identify(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Enroll finger. Created template must be saved to FLASH storage
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_enroll_finger(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Capture and identify finger against existing templates in Flash storage
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @param[in] timeout - timeout (msec). Maximum timeout 65535 msec
|
||||
* set to 0 for waiting indefinitely
|
||||
*
|
||||
* @param[out] template_id - pointer for matched template ID
|
||||
* @param[out] match - pointer to match result
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_identify_finger(HCP_comm_t *chain, uint32_t timeout,
|
||||
uint16_t *template_id, bool *match);
|
||||
|
||||
/**
|
||||
* @brief Save template after enroll is finished to FLASH storage
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @param[out] template_id - template ID
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_template_save(HCP_comm_t *chain, uint16_t template_id);
|
||||
|
||||
/**
|
||||
* @brief Remove template from RAM
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @param[in] template_id - template ID
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_template_remove_ram(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Pull template stored in RAM from FPC BM-Lite
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
*
|
||||
* @param[in] data - pointer to template buffer
|
||||
* @param[in] size - size of the template buffer
|
||||
* if buffer size is not enough the template
|
||||
* will be truncated
|
||||
* chain->arg.size will contain real size of the template
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_template_get(HCP_comm_t *chain, uint8_t *data, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Push template to FPC BM-Lite and stored it to RAM
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
*
|
||||
* @param[in] data - pointer to template buffer
|
||||
* @param[in] size - size of the template buffer
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_template_put(HCP_comm_t *chain, uint8_t *data, uint16_t length);
|
||||
|
||||
/**
|
||||
* @brief Remove template from FLASH storage
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @param[in] template_id - template ID
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_template_remove(HCP_comm_t *chain, uint16_t template_id);
|
||||
|
||||
/**
|
||||
* @brief Remove all templates from FLASH storage
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_template_remove_all(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Copy template from FLASH storage to RAM
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @param[in] template_id - template ID
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_template_load_storage(HCP_comm_t *chain, uint16_t template_id);
|
||||
|
||||
/**
|
||||
* @brief Remove template from FLASH storage
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @param[out] template_id - template ID
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_template_get_count(HCP_comm_t *chain, uint16_t *count);
|
||||
|
||||
/**
|
||||
* @brief Get array of template ID stored on FPC BM-LIte
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @return ::fpc_bep_result_t
|
||||
* chain->arg.data - pointer to array of uint16_t of IDs
|
||||
* chain->arg.size - length of the array (in bytes). For calculating
|
||||
* number of templates divide the arg.size by 2
|
||||
*/
|
||||
fpc_bep_result_t bep_template_get_ids(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Software reset of FCP BM-Lite
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_sw_reset(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Calibrate FPC BM-LIte sensor and store calibration data to FLASH storage
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*
|
||||
* FPC BM-Lite must be restarted to activate new calibration data
|
||||
*/
|
||||
fpc_bep_result_t bep_sensor_calibrate(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Remove FPC BM-LIte sensor calibration data from FLASH storage
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*
|
||||
* FPC BM-Lite must be restarted to activate
|
||||
*/
|
||||
fpc_bep_result_t bep_sensor_calibrate_remove(HCP_comm_t *chain);
|
||||
|
||||
/**
|
||||
* @brief Get version of FPC BM-LIte firmware
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @param[in] version - pointer to data buffer
|
||||
* @param[in] size - size of the data buffer
|
||||
* if buffer size is not enough the data
|
||||
* will be truncated
|
||||
* chain->arg.size will contain real size of the data
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_version(HCP_comm_t *chain, char *version, int len);
|
||||
|
||||
/**
|
||||
* @brief Get version of FPC BM-LIte firmware
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @param[in] unique_id - pointer to data buffer
|
||||
* chain->arg.size will contain real size of the data
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_unique_id_get(HCP_comm_t *chain, uint8_t *unique_id);
|
||||
|
||||
/**
|
||||
* @brief Set requested UART communication speed
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @param[in] speed - UART speed
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_uart_speed_set(HCP_comm_t *chain, uint32_t speed);
|
||||
|
||||
/**
|
||||
* @brief Get current UART communication speed
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
* @param[out] speed - UART speed
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_uart_speed_get(HCP_comm_t *chain, uint32_t *speed);
|
||||
|
||||
/**
|
||||
* @brief Reset FPC BM-Lite fingerprint sensor
|
||||
*
|
||||
* @param[in] chain - HCP com chain
|
||||
*
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t bep_sensor_reset(HCP_comm_t *chain);
|
||||
|
||||
#endif
|
||||
92
BMLite_example/inc/bmlite_if_callbacks.h
Normal file
92
BMLite_example/inc/bmlite_if_callbacks.h
Normal file
@ -0,0 +1,92 @@
|
||||
#ifndef BMLITE_IF_CALLBACKS_H
|
||||
#define BMLITE_IF_CALLBACKS_H
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef BMLITE_USE_CALLBACK
|
||||
#define bmlite_on_error(error, value)
|
||||
#define bmlite_on_start_capture()
|
||||
#define bmlite_on_finish_capture()
|
||||
#define bmlite_on_finish_enroll()
|
||||
#define bmlite_on_start_enroll()
|
||||
#define bmlite_on_start_enrollcapture()
|
||||
#define bmlite_on_finish_enrollcapture()
|
||||
#define bmlite_on_identify_start()
|
||||
#define bmlite_on_identify_finish()
|
||||
|
||||
#else
|
||||
|
||||
typedef enum {
|
||||
BMLITE_ERROR_OK = 0,
|
||||
BMLITE_ERROR_CAPTURE,
|
||||
BMLITE_ERROR_CAPTURE_START,
|
||||
BMLITE_ERROR_ENROLL_START,
|
||||
BMLITE_ERROR_ENROLL_ADD,
|
||||
BMLITE_ERROR_ENROLL_FINISH,
|
||||
BMLITE_ERROR_WRONG_ANSWER,
|
||||
BMLITE_ERROR_FINGER_WAIT,
|
||||
BMLITE_ERROR_IDENTYFY,
|
||||
BMLITE_ERROR_TEMPLATE_SAVE,
|
||||
BMLITE_ERROR_TEMPLATE_DELETE,
|
||||
BMLITE_ERROR_TEMPLATE_COUNT,
|
||||
BMLITE_ERROR_TEMPLATE_GETIDS,
|
||||
BMLITE_ERROR_IMAGE_EXTRACT,
|
||||
BMLITE_ERROR_IMAGE_GETSIZE,
|
||||
BMLITE_ERROR_IMAGE_GET,
|
||||
BMLITE_ERROR_GETVERSION,
|
||||
BMLITE_ERROR_SW_RESET,
|
||||
BMLITE_ERROR_CALIBRATE,
|
||||
BMLITE_ERROR_CALIBRATE_DELETE,
|
||||
BMLITE_ERROR_SEND_CMD,
|
||||
BMLITE_ERROR_GET_ARG,
|
||||
} bmlite_error_t;
|
||||
|
||||
/**
|
||||
* @brief Error Callback function
|
||||
*
|
||||
* @param[in] Callback Error Code
|
||||
* @param[in] BEP result code
|
||||
*/
|
||||
void bmlite_on_error(bmlite_error_t error, int32_t value);
|
||||
|
||||
/**
|
||||
* @brief Starting Capture Callback function
|
||||
*/
|
||||
void bmlite_on_start_capture();
|
||||
|
||||
/**
|
||||
* @brief Finishing Capture Callback function
|
||||
*/
|
||||
void bmlite_on_finish_capture();
|
||||
|
||||
/**
|
||||
* @brief Starting Enroll Callback function
|
||||
*/
|
||||
void bmlite_on_start_enroll();
|
||||
|
||||
/**
|
||||
* @brief Finishing Enroll Callback function
|
||||
*/
|
||||
void bmlite_on_finish_enroll();
|
||||
|
||||
/**
|
||||
* @brief Starting Capture for Enroll Callback function
|
||||
*/
|
||||
void bmlite_on_start_enrollcapture();
|
||||
|
||||
/**
|
||||
* @brief Finishing Capture for Enroll Callback function
|
||||
*/
|
||||
void bmlite_on_finish_enrollcapture();
|
||||
|
||||
/**
|
||||
* @brief Starting Identify Callback function
|
||||
*/
|
||||
void bmlite_on_identify_start();
|
||||
|
||||
/**
|
||||
* @brief Finishing Identify Callback function
|
||||
*/
|
||||
void bmlite_on_identify_finish();
|
||||
#endif // BMLITE_USE_CALLBACK
|
||||
|
||||
#endif
|
||||
@ -10,6 +10,11 @@
|
||||
/** Communication acknowledge definition */
|
||||
#define FPC_BEP_ACK 0x7f01ff7f
|
||||
|
||||
typedef struct {
|
||||
uint32_t size;
|
||||
uint8_t *data;
|
||||
} HCP_arg_t;
|
||||
|
||||
typedef struct {
|
||||
/** Send data to BM-Lite */
|
||||
fpc_bep_result_t (*write) (uint16_t, const uint8_t *, uint32_t, void *);
|
||||
@ -25,25 +30,13 @@ typedef struct {
|
||||
uint32_t pkt_size;
|
||||
/** Buffer of MTU size for transport layer */
|
||||
uint8_t *txrx_buffer;
|
||||
/** Values of last argument pulled by bmlite_get_arg
|
||||
Values are valid only right after bmlite_get_arg() call */
|
||||
HCP_arg_t arg;
|
||||
/** Result of execution command on BM-Lite */
|
||||
fpc_bep_result_t bep_result;
|
||||
} HCP_comm_t;
|
||||
|
||||
/**
|
||||
* @brief Helper function for sending HCP commands
|
||||
*
|
||||
* @param chain HCP communication chain
|
||||
* @param command_id command to send
|
||||
* @param arg_key1 first key to add to the command
|
||||
* @param arg_data1 first argument data to add
|
||||
* @param arg_data1_length first data length of argument data
|
||||
* @param arg_key2 second key to add to the command
|
||||
* @param arg_data2 second argument data to add
|
||||
* @param arg_data2_length second data length of argument data
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t send_command_args2(HCP_comm_t *chain, fpc_hcp_cmd_t command_id,
|
||||
fpc_hcp_arg_t arg_key1, void *arg_data1, uint16_t arg_data1_length,
|
||||
fpc_hcp_arg_t arg_key2, void *arg_data2, uint16_t arg_data2_length);
|
||||
|
||||
/**
|
||||
* @brief Helper function for receiving HCP commands
|
||||
|
||||
@ -56,8 +49,15 @@ fpc_bep_result_t send_command_args2(HCP_comm_t *chain, fpc_hcp_cmd_t command_id,
|
||||
* @param arg_data2_length second argument
|
||||
* @return ::fpc_bep_result_t
|
||||
*/
|
||||
fpc_bep_result_t receive_result_args2(HCP_comm_t *chain,
|
||||
fpc_hcp_arg_t arg_key1, void *arg_data1, uint16_t arg_data1_length,
|
||||
fpc_hcp_arg_t arg_key2, void *arg_data2, uint16_t arg_data2_length);
|
||||
fpc_bep_result_t bmlite_receive(HCP_comm_t *hcp_comm);
|
||||
fpc_bep_result_t bmlite_send(HCP_comm_t *hcp_comm);
|
||||
fpc_bep_result_t bmlite_tranceive(HCP_comm_t *hcp_comm);
|
||||
|
||||
fpc_bep_result_t bmlite_init_cmd(HCP_comm_t *hcp_comm, uint16_t cmd, uint16_t arg);
|
||||
fpc_bep_result_t bmlite_add_arg(HCP_comm_t *hcp_comm, uint16_t arg, void *data, uint16_t size);
|
||||
fpc_bep_result_t bmlite_get_arg(HCP_comm_t *hcp_comm, uint16_t arg_type);
|
||||
fpc_bep_result_t bmlite_copy_arg(HCP_comm_t *hcp_comm, uint16_t arg_key, void *arg_data, uint16_t arg_data_length);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@ -109,4 +109,14 @@ uint64_t platform_get_time(void);
|
||||
*/
|
||||
void platform_clear_screen(void);
|
||||
|
||||
/**
|
||||
* @brief Busy wait.
|
||||
*
|
||||
* @param[in] ms Time to wait [ms].
|
||||
* 0 => return immediately
|
||||
* 1 => wait at least 1ms etc.
|
||||
*/
|
||||
void hal_timebase_busy_wait(uint32_t ms);
|
||||
|
||||
|
||||
#endif /* PLATFORM_H */
|
||||
|
||||
@ -1,400 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Fingerprint Cards AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file bep_host_if.c
|
||||
* @brief BEP Host Interface implementation.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "fpc_hcp_common.h"
|
||||
#include "bep_host_if.h"
|
||||
#include "hcp_tiny.h"
|
||||
|
||||
/** Returns the number of elements in an array. */
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
#define RECEIVE_TIMEOUT 10
|
||||
|
||||
#ifdef DEBUG
|
||||
#define log_debug(format, ...) printf(format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define log_debug(format, ...)
|
||||
#endif
|
||||
#define log_info(format, ...) printf(format, ##__VA_ARGS__)
|
||||
#define log_error(format, ...) printf(format, ##__VA_ARGS__)
|
||||
|
||||
/** Maximum attempts for capture image */
|
||||
static const uint8_t MAX_CAPTURE_ATTEMPTS = 15U;
|
||||
static const uint16_t CAPTURE_TIMEOUT = 3000;
|
||||
|
||||
static fpc_bep_result_t send_command_no_args(HCP_comm_t *chain, fpc_hcp_cmd_t command_id)
|
||||
{
|
||||
return send_command_args2(chain, command_id, ARG_NONE, NULL, 0, ARG_NONE, NULL, 0);
|
||||
}
|
||||
|
||||
static fpc_bep_result_t send_command(HCP_comm_t *chain, fpc_hcp_cmd_t command_id,
|
||||
fpc_hcp_arg_t arg_key, void *arg_data, uint16_t arg_data_length)
|
||||
{
|
||||
return send_command_args2(chain, command_id, arg_key, arg_data, arg_data_length,
|
||||
ARG_NONE, NULL, 0);
|
||||
}
|
||||
|
||||
static fpc_bep_result_t receive_result_no_args(HCP_comm_t *chain)
|
||||
{
|
||||
return receive_result_args2(chain, ARG_NONE, NULL, 0, ARG_NONE, NULL, 0);
|
||||
}
|
||||
|
||||
static fpc_bep_result_t receive_result_args1(HCP_comm_t *chain,
|
||||
fpc_hcp_arg_t arg_key, void *arg_data, uint16_t arg_data_length)
|
||||
{
|
||||
return receive_result_args2(chain, arg_key, arg_data, arg_data_length, ARG_NONE, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
fpc_bep_result_t bep_capture(HCP_comm_t *chain, uint16_t timeout)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
|
||||
log_info("Put finger on sensor\n");
|
||||
|
||||
/* Capture finger down */
|
||||
bep_result = send_command(chain, CMD_CAPTURE, ARG_TIMEOUT, &timeout, sizeof(timeout));
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u Error transmitting CMD_CAPTURE\n", __func__, __LINE__);
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
return receive_result_no_args(chain);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_enroll_finger(HCP_comm_t *chain)
|
||||
{
|
||||
uint32_t samples_remaining = 0;
|
||||
fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK;
|
||||
bool enroll_done = false;
|
||||
|
||||
/* Enroll start */
|
||||
bep_result = send_command(chain, CMD_ENROLL, ARG_START, NULL, 0);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s, ERROR line:%u\n", __func__, __LINE__);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
bep_result = receive_result_no_args(chain);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR receiving status=%d\n", __func__, __LINE__, bep_result);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < MAX_CAPTURE_ATTEMPTS; ++i) {
|
||||
|
||||
bep_result = bep_capture(chain, CAPTURE_TIMEOUT);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("Capture failed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
log_info("Capture done. Remove finger from sensor\n");
|
||||
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR receiving, result=%d\n", __func__, __LINE__, bep_result);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Enroll add */
|
||||
bep_result = send_command(chain, CMD_ENROLL, ARG_ADD, NULL, 0);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR\n", __func__, __LINE__);
|
||||
continue;
|
||||
}
|
||||
|
||||
bep_result = receive_result_args1(chain, ARG_COUNT, &samples_remaining,
|
||||
sizeof(samples_remaining));
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR receiving status=%d\n", __func__, __LINE__, bep_result);
|
||||
continue;
|
||||
}
|
||||
|
||||
log_info("Enroll samples remaining: %d\n", samples_remaining);
|
||||
|
||||
if (samples_remaining == 0U) {
|
||||
enroll_done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
bep_result = send_command(chain, CMD_WAIT, ARG_FINGER_UP, NULL, 0);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR\n", __func__, __LINE__);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Wait for finger to be lifted from sensor */
|
||||
bep_result = receive_result_no_args(chain);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR receiving status=%d\n", __func__, __LINE__, bep_result);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
bep_result = send_command(chain, CMD_ENROLL, ARG_FINISH, NULL, 0);
|
||||
if (bep_result == FPC_BEP_RESULT_OK) {
|
||||
bep_result = receive_result_no_args(chain);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR receiving status=%d\n", __func__, __LINE__, bep_result);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return (!enroll_done) ? FPC_BEP_RESULT_GENERAL_ERROR : bep_result;
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_identify_finger(HCP_comm_t *chain, uint32_t timeout, uint16_t *template_id, bool *match)
|
||||
{
|
||||
fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK;
|
||||
|
||||
*match = false;
|
||||
|
||||
uint32_t prev_timeout = chain->phy_rx_timeout;
|
||||
chain->phy_rx_timeout = timeout;
|
||||
bep_result = bep_capture(chain, timeout);
|
||||
chain->phy_rx_timeout = prev_timeout;
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("Capture failed result=%d\n", bep_result);
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
log_info("Capture done. Remove finger from sensor\n");
|
||||
|
||||
bep_result = bep_image_extract(chain);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("Extract failed\n");
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
bep_result = send_command(chain, CMD_IDENTIFY, ARG_NONE, NULL, 0);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("Identify failed\n");
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
bep_result = receive_result_args2(chain, ARG_MATCH, match, sizeof(bool),
|
||||
ARG_ID, template_id, sizeof(uint16_t));
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("Identify failed\n");
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_save_template(HCP_comm_t *chain, uint16_t template_id)
|
||||
{
|
||||
fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK;
|
||||
|
||||
bep_result = send_command_args2(chain, CMD_TEMPLATE, ARG_SAVE, NULL, 0, ARG_ID, &template_id,
|
||||
sizeof(template_id));
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR\n", __func__, __LINE__);
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
return receive_result_no_args(chain);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_delete_template(HCP_comm_t *chain, uint16_t template_id)
|
||||
{
|
||||
fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK;
|
||||
|
||||
if (template_id == REMOVE_ID_ALL_TEMPLATES) {
|
||||
bep_result = send_command_args2(chain, CMD_STORAGE_TEMPLATE, ARG_DELETE, NULL, 0,
|
||||
ARG_ALL, NULL, 0);
|
||||
} else {
|
||||
bep_result = send_command_args2(chain, CMD_STORAGE_TEMPLATE, ARG_DELETE, NULL, 0,
|
||||
ARG_ID, &template_id, sizeof(template_id));
|
||||
}
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR\n", __func__, __LINE__);
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
return receive_result_no_args(chain);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_get_template_count(HCP_comm_t *chain, uint32_t *template_count)
|
||||
{
|
||||
fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK;
|
||||
|
||||
bep_result = send_command(chain, CMD_STORAGE_TEMPLATE, ARG_COUNT, NULL, 0);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u ERROR sending CMD_STORAGE_TEMPLATE\n", __func__, __LINE__);
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
bep_result = receive_result_args1(chain, ARG_COUNT, template_count, sizeof(template_count[0]));
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR receiving status=%d\n", __func__, __LINE__, bep_result);
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_get_template_ids(HCP_comm_t *chain, uint16_t *template_ids,
|
||||
uint32_t nof_templates)
|
||||
{
|
||||
fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK;
|
||||
|
||||
bep_result = send_command(chain, CMD_STORAGE_TEMPLATE, ARG_ID, NULL, 0);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u ERROR sending CMD_STORAGE_TEMPLATE\n", __func__, __LINE__);
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
bep_result = receive_result_args1(chain, ARG_DATA, template_ids, nof_templates *
|
||||
sizeof(template_ids[0]));
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR receiving status=%d\n", __func__, __LINE__, bep_result);
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_image_extract(HCP_comm_t *chain)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
|
||||
bep_result = send_command(chain, CMD_IMAGE, ARG_EXTRACT, NULL, 0);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("Extract failed\n");
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
return receive_result_no_args(chain);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_image_get_size(HCP_comm_t *chain, uint32_t *size)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
|
||||
bep_result = send_command(chain, CMD_IMAGE, ARG_SIZE, NULL, 0);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("Extract failed\n");
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
log_info("Downloading image data...\n");
|
||||
|
||||
return receive_result_args1(chain, ARG_SIZE, size, sizeof(size));
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_image_get(HCP_comm_t *chain, uint8_t *data, uint32_t size)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
|
||||
bep_result = send_command(chain, CMD_IMAGE, ARG_UPLOAD, NULL, 0);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("Extract failed\n");
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
return receive_result_args1(chain, ARG_DATA, data, size);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_version(HCP_comm_t *chain, char *version, int len)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
|
||||
bep_result = send_command_args2(chain, CMD_INFO, ARG_GET, NULL, 0, ARG_VERSION, NULL, 0);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s, ERROR line:%u\n", __func__, __LINE__);
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
return receive_result_args1(chain, ARG_VERSION, version, len);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_reset(HCP_comm_t *chain)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
|
||||
bep_result = send_command_no_args(chain, CMD_RESET);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR\n", __func__, __LINE__);
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
return receive_result_no_args(chain);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_sensor_calibrate(HCP_comm_t *chain)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
|
||||
bep_result = send_command_no_args(chain, CMD_STORAGE_CALIBRATION);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR\n", __func__, __LINE__);
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
return receive_result_no_args(chain);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_sensor_calibrate_remove(HCP_comm_t *chain)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
|
||||
bep_result = send_command(chain, CMD_STORAGE_CALIBRATION, ARG_DELETE, NULL, 0);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR\n", __func__, __LINE__);
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
return receive_result_no_args(chain);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_sensor_wait_for_finger(HCP_comm_t *chain, uint16_t timeout)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
|
||||
bep_result = send_command(chain, CMD_WAIT, ARG_FINGER_DOWN, NULL, 0);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR\n", __func__, __LINE__);
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
/* Wait for finger on sensor */
|
||||
return receive_result_no_args(chain);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_sensor_wait_finger_not_present(HCP_comm_t *chain, uint16_t timeout)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
|
||||
bep_result = send_command(chain, CMD_WAIT, ARG_FINGER_UP, NULL, 0);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
log_error("%s:%u, ERROR\n", __func__, __LINE__);
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
/* Wait for finger to be lifted from sensor */
|
||||
return receive_result_no_args(chain);
|
||||
}
|
||||
307
BMLite_example/src/bmlite_if.c
Normal file
307
BMLite_example/src/bmlite_if.c
Normal file
@ -0,0 +1,307 @@
|
||||
#include "hcp_tiny.h"
|
||||
#include "bmlite_if.h"
|
||||
#include "platform.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bmlite_if_callbacks.h"
|
||||
|
||||
#define MAX_CAPTURE_ATTEMPTS 15
|
||||
#define CAPTURE_TIMEOUT 3000
|
||||
|
||||
#define exit_if_err(c) { bep_result = c; if(bep_result) goto exit; }
|
||||
|
||||
#define assert(c) { fpc_bep_result_t res = c; if(res) return res; }
|
||||
|
||||
#ifdef BMLITE_USE_CALLBACK
|
||||
/**
|
||||
* @brief Mock callback functions
|
||||
*/
|
||||
__attribute__((weak)) void bmlite_on_error(bmlite_error_t error, int32_t value) { (void)error; (void)value; }
|
||||
|
||||
__attribute__((weak)) void bmlite_on_start_capture() {}
|
||||
__attribute__((weak)) void bmlite_on_finish_capture() {}
|
||||
|
||||
__attribute__((weak)) void bmlite_on_start_enroll() {}
|
||||
__attribute__((weak)) void bmlite_on_finish_enroll() {}
|
||||
|
||||
__attribute__((weak)) void bmlite_on_start_enrollcapture() {}
|
||||
__attribute__((weak)) void bmlite_on_finish_enrollcapture() {}
|
||||
|
||||
__attribute__((weak)) void bmlite_on_identify_start() {}
|
||||
__attribute__((weak)) void bmlite_on_identify_finish() {}
|
||||
#endif
|
||||
|
||||
fpc_bep_result_t bmlite_send_cmd(HCP_comm_t *chain, uint16_t cmd, uint16_t arg_type)
|
||||
{
|
||||
assert(bmlite_init_cmd(chain, cmd, arg_type));
|
||||
return bmlite_tranceive(chain);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bmlite_send_cmd_arg(HCP_comm_t *chain, uint16_t cmd, uint16_t arg1_type, uint16_t arg2_type, void *arg2_data, uint16_t arg2_length)
|
||||
{
|
||||
assert(bmlite_init_cmd(chain, cmd, arg1_type));
|
||||
assert(bmlite_add_arg(chain, arg2_type, arg2_data, arg2_length));
|
||||
|
||||
return bmlite_tranceive(chain);
|
||||
}
|
||||
|
||||
fpc_bep_result_t sensor_wait_finger_present(HCP_comm_t *chain, uint16_t timeout)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
uint32_t prev_timeout = chain->phy_rx_timeout;
|
||||
|
||||
bmlite_on_start_capture();
|
||||
chain->phy_rx_timeout = timeout;
|
||||
bep_result = bmlite_send_cmd_arg(chain, CMD_WAIT, ARG_FINGER_DOWN, ARG_TIMEOUT, &timeout, sizeof(timeout));
|
||||
chain->phy_rx_timeout = prev_timeout;
|
||||
bmlite_on_finish_capture();
|
||||
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
fpc_bep_result_t sensor_wait_finger_not_present(HCP_comm_t *chain, uint16_t timeout)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
uint32_t prev_timeout = chain->phy_rx_timeout;
|
||||
|
||||
chain->phy_rx_timeout = timeout;
|
||||
bep_result = bmlite_send_cmd_arg(chain, CMD_WAIT, ARG_FINGER_UP, ARG_TIMEOUT, &timeout, sizeof(timeout));
|
||||
chain->phy_rx_timeout = prev_timeout;
|
||||
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_capture(HCP_comm_t *chain, uint16_t timeout)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
uint32_t prev_timeout = chain->phy_rx_timeout;
|
||||
|
||||
bmlite_on_start_capture();
|
||||
chain->phy_rx_timeout = timeout;
|
||||
bep_result = bmlite_send_cmd_arg(chain, CMD_CAPTURE, ARG_NONE, ARG_TIMEOUT, &timeout, sizeof(timeout));
|
||||
chain->phy_rx_timeout = prev_timeout;
|
||||
bmlite_on_finish_capture();
|
||||
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_image_get_size(HCP_comm_t *chain, uint32_t *size)
|
||||
{
|
||||
assert(bmlite_send_cmd(chain, CMD_IMAGE, ARG_SIZE));
|
||||
assert(bmlite_get_arg(chain, ARG_SIZE));
|
||||
|
||||
*size = *(uint32_t*)chain->arg.data;
|
||||
|
||||
return FPC_BEP_RESULT_OK;
|
||||
}
|
||||
|
||||
fpc_bep_result_t image_create(HCP_comm_t *chain)
|
||||
{
|
||||
return bmlite_send_cmd(chain, CMD_IMAGE, ARG_CREATE);
|
||||
}
|
||||
|
||||
fpc_bep_result_t image_delete(HCP_comm_t *chain)
|
||||
{
|
||||
return bmlite_send_cmd(chain, CMD_IMAGE, ARG_DELETE);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_image_get(HCP_comm_t *chain, uint8_t *data, uint32_t size)
|
||||
{
|
||||
assert(bmlite_send_cmd(chain, CMD_IMAGE, ARG_UPLOAD));
|
||||
return bmlite_copy_arg(chain, ARG_DATA, data, size);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_image_put(HCP_comm_t *chain, uint8_t *data, uint32_t size)
|
||||
{
|
||||
return bmlite_send_cmd_arg(chain, CMD_IMAGE, ARG_DOWNLOAD, ARG_DATA, data, size);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_image_extract(HCP_comm_t *chain)
|
||||
{
|
||||
return bmlite_send_cmd(chain, CMD_IMAGE, ARG_EXTRACT);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_identify(HCP_comm_t *chain)
|
||||
{
|
||||
return bmlite_send_cmd(chain, CMD_IDENTIFY, ARG_NONE);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_enroll_finger(HCP_comm_t *chain)
|
||||
{
|
||||
uint32_t samples_remaining = 0;
|
||||
fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK;
|
||||
bool enroll_done = false;
|
||||
|
||||
bmlite_on_start_enroll();
|
||||
/* Enroll start */
|
||||
exit_if_err(bmlite_send_cmd(chain, CMD_ENROLL, ARG_START));
|
||||
|
||||
for (uint8_t i = 0; i < MAX_CAPTURE_ATTEMPTS; ++i) {
|
||||
|
||||
bmlite_on_start_enrollcapture();
|
||||
bep_result = bep_capture(chain, CAPTURE_TIMEOUT);
|
||||
bmlite_on_finish_enrollcapture();
|
||||
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Enroll add */
|
||||
bep_result = bmlite_send_cmd(chain, CMD_ENROLL, ARG_ADD);
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bmlite_get_arg(chain, ARG_COUNT);
|
||||
samples_remaining = *(uint32_t *)chain->arg.data;
|
||||
|
||||
// log_info("Enroll samples remaining: %d\n", samples_remaining);
|
||||
|
||||
/* Break enrolling if we can't collect enough correct images for enroll*/
|
||||
if (samples_remaining == 0U) {
|
||||
enroll_done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
sensor_wait_finger_not_present(chain, 0);
|
||||
}
|
||||
|
||||
bep_result = bmlite_send_cmd(chain, CMD_ENROLL, ARG_FINISH);
|
||||
|
||||
exit:
|
||||
bmlite_on_finish_enroll();
|
||||
return (!enroll_done) ? FPC_BEP_RESULT_GENERAL_ERROR : bep_result;
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_identify_finger(HCP_comm_t *chain, uint32_t timeout, uint16_t *template_id, bool *match)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
*match = false;
|
||||
|
||||
bmlite_on_identify_start();
|
||||
|
||||
exit_if_err(bep_capture(chain, timeout));
|
||||
exit_if_err(bep_image_extract(chain));
|
||||
exit_if_err(bep_identify(chain));
|
||||
exit_if_err(bmlite_get_arg(chain, ARG_MATCH));
|
||||
*match = *(bool *)chain->arg.data;
|
||||
if(*match) {
|
||||
bmlite_get_arg(chain, ARG_ID);
|
||||
*template_id = *(uint16_t *)chain->arg.data;
|
||||
// Delay for possible updating template on BM-Lite
|
||||
hal_timebase_busy_wait(50);
|
||||
}
|
||||
|
||||
bep_result = sensor_wait_finger_not_present(chain, 0);
|
||||
|
||||
exit:
|
||||
bmlite_on_identify_finish();
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_template_save(HCP_comm_t *chain, uint16_t template_id)
|
||||
{
|
||||
return bmlite_send_cmd_arg(chain, CMD_TEMPLATE, ARG_SAVE, ARG_ID, &template_id, sizeof(template_id));
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_template_remove_ram(HCP_comm_t *chain)
|
||||
{
|
||||
return bmlite_send_cmd(chain, CMD_TEMPLATE, ARG_DELETE);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_template_get(HCP_comm_t *chain, uint8_t *data, uint32_t size)
|
||||
{
|
||||
assert(bmlite_send_cmd(chain, CMD_TEMPLATE, ARG_UPLOAD));
|
||||
return bmlite_copy_arg(chain, ARG_DATA, data, size);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_template_put(HCP_comm_t *chain, uint8_t *data, uint16_t length)
|
||||
{
|
||||
return bmlite_send_cmd_arg(chain, CMD_TEMPLATE, ARG_DOWNLOAD,
|
||||
ARG_DATA, data, length);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_template_remove(HCP_comm_t *chain, uint16_t template_id)
|
||||
{
|
||||
return bmlite_send_cmd_arg(chain, CMD_STORAGE_TEMPLATE, ARG_DELETE,
|
||||
ARG_ID, &template_id, sizeof(template_id));
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_template_remove_all(HCP_comm_t *chain)
|
||||
{
|
||||
return bmlite_send_cmd_arg(chain, CMD_STORAGE_TEMPLATE, ARG_DELETE,
|
||||
ARG_ALL, 0, 0);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_template_load_storage(HCP_comm_t *chain, uint16_t template_id)
|
||||
{
|
||||
return bmlite_send_cmd_arg(chain, CMD_STORAGE_TEMPLATE, ARG_UPLOAD,
|
||||
ARG_ID, &template_id, sizeof(template_id));
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_template_get_count(HCP_comm_t *chain, uint16_t *count)
|
||||
{
|
||||
assert(bmlite_send_cmd(chain, CMD_STORAGE_TEMPLATE, ARG_COUNT));
|
||||
assert(bmlite_get_arg(chain, ARG_COUNT));
|
||||
*count = *(uint16_t*)chain->arg.data;
|
||||
return FPC_BEP_RESULT_OK;
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_template_get_ids(HCP_comm_t *chain)
|
||||
{
|
||||
assert(bmlite_send_cmd(chain, CMD_STORAGE_TEMPLATE, ARG_ID));
|
||||
return bmlite_get_arg(chain, ARG_DATA);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_sw_reset(HCP_comm_t *chain)
|
||||
{
|
||||
return bmlite_send_cmd(chain, CMD_RESET, ARG_NONE);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_sensor_calibrate(HCP_comm_t *chain)
|
||||
{
|
||||
return bmlite_send_cmd(chain, CMD_STORAGE_CALIBRATION, ARG_NONE);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_sensor_calibrate_remove(HCP_comm_t *chain)
|
||||
{
|
||||
return bmlite_send_cmd(chain, CMD_STORAGE_CALIBRATION, ARG_DELETE);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_version(HCP_comm_t *chain, char *version, int len)
|
||||
{
|
||||
assert(bmlite_send_cmd_arg(chain, CMD_INFO, ARG_GET, ARG_VERSION, 0, 0));
|
||||
return bmlite_copy_arg(chain, ARG_VERSION, version, len);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_unique_id_get(HCP_comm_t *chain, uint8_t *unique_id)
|
||||
{
|
||||
assert(bmlite_send_cmd_arg(chain, CMD_INFO, ARG_GET, ARG_UNIQUE_ID, 0, 0));
|
||||
return bmlite_copy_arg(chain, ARG_UNIQUE_ID, unique_id, 12);
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_uart_speed_set(HCP_comm_t *chain, uint32_t speed)
|
||||
{
|
||||
assert(bmlite_init_cmd(chain, CMD_COMMUNICATION, ARG_SPEED));
|
||||
assert(bmlite_add_arg(chain, ARG_SET, 0, 0));
|
||||
assert(bmlite_add_arg(chain, ARG_DATA, (uint8_t*)&speed, sizeof(speed)));
|
||||
return bmlite_tranceive(chain);
|
||||
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_uart_speed_get(HCP_comm_t *chain, uint32_t *speed)
|
||||
{
|
||||
assert(bmlite_init_cmd(chain, CMD_COMMUNICATION, ARG_SPEED));
|
||||
assert(bmlite_add_arg(chain, ARG_GET, 0, 0));
|
||||
assert(bmlite_tranceive(chain));
|
||||
return bmlite_copy_arg(chain, ARG_DATA, speed, sizeof(speed));
|
||||
|
||||
}
|
||||
|
||||
fpc_bep_result_t bep_sensor_reset(HCP_comm_t *chain)
|
||||
{
|
||||
// Delay for possible updating template on BM-Lite
|
||||
hal_timebase_busy_wait(50);
|
||||
|
||||
return bmlite_send_cmd(chain, CMD_SENSOR, ARG_RESET);
|
||||
}
|
||||
@ -1,26 +1,27 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bep_host_if.h"
|
||||
#include "platform.h"
|
||||
#include "fpc_crc.h"
|
||||
#include "fpc_hcp_common.h"
|
||||
#include "hcp_tiny.h"
|
||||
|
||||
#define DEBUG(...) printf(__VA_ARGS__)
|
||||
#include "bmlite_if_callbacks.h"
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define LOG_DEBUG(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define LOG_DEBUG(...)
|
||||
#endif
|
||||
|
||||
static uint32_t fpc_com_ack = FPC_BEP_ACK;
|
||||
|
||||
static fpc_bep_result_t _rx_application(HCP_comm_t *hcp_comm);
|
||||
static fpc_bep_result_t _rx_link(HCP_comm_t *hcp_comm);
|
||||
static fpc_bep_result_t _tx_application(HCP_comm_t *hcp_comm);
|
||||
static fpc_bep_result_t _tx_link(HCP_comm_t *hcp_comm);
|
||||
|
||||
static fpc_bep_result_t hcp_init_cmd(HCP_comm_t *hcp_comm, uint16_t cmd);
|
||||
static fpc_bep_result_t hcp_add_arg(HCP_comm_t *hcp_comm, uint16_t arg, uint8_t *data, uint16_t size);
|
||||
static fpc_bep_result_t hcp_get_arg(HCP_comm_t *hcp_comm, uint16_t arg_type, uint16_t *size, uint8_t **payload);
|
||||
|
||||
typedef struct {
|
||||
uint16_t cmd;
|
||||
uint16_t args_nr;
|
||||
@ -42,18 +43,30 @@ typedef struct {
|
||||
_HCP_cmd_t t_pld;
|
||||
} _HPC_pkt_t;
|
||||
|
||||
fpc_bep_result_t hcp_init_cmd(HCP_comm_t *hcp_comm, uint16_t cmd)
|
||||
fpc_bep_result_t bmlite_init_cmd(HCP_comm_t *hcp_comm, uint16_t cmd, uint16_t arg_key)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
|
||||
_HCP_cmd_t *out = (_HCP_cmd_t *)hcp_comm->pkt_buffer;
|
||||
out->cmd = cmd;
|
||||
out->args_nr = 0;
|
||||
hcp_comm->pkt_size = 4;
|
||||
|
||||
if(arg_key != ARG_NONE) {
|
||||
bep_result = bmlite_add_arg(hcp_comm, arg_key, NULL, 0);
|
||||
if(bep_result) {
|
||||
bmlite_on_error(BMLITE_ERROR_SEND_CMD, bep_result);
|
||||
return bep_result;
|
||||
}
|
||||
}
|
||||
|
||||
return FPC_BEP_RESULT_OK;
|
||||
}
|
||||
|
||||
fpc_bep_result_t hcp_add_arg(HCP_comm_t *hcp_comm, uint16_t arg, uint8_t *data, uint16_t size)
|
||||
fpc_bep_result_t bmlite_add_arg(HCP_comm_t *hcp_comm, uint16_t arg, void *data, uint16_t size)
|
||||
{
|
||||
if(hcp_comm->pkt_size + 4 + size > hcp_comm->pkt_size_max) {
|
||||
bmlite_on_error(BMLITE_ERROR_SEND_CMD, FPC_BEP_RESULT_NO_MEMORY);
|
||||
return FPC_BEP_RESULT_NO_MEMORY;
|
||||
}
|
||||
|
||||
@ -68,7 +81,7 @@ fpc_bep_result_t hcp_add_arg(HCP_comm_t *hcp_comm, uint16_t arg, uint8_t *data,
|
||||
return FPC_BEP_RESULT_OK;
|
||||
}
|
||||
|
||||
fpc_bep_result_t hcp_get_arg(HCP_comm_t *hcp_comm, uint16_t arg_type, uint16_t *size, uint8_t **payload)
|
||||
fpc_bep_result_t bmlite_get_arg(HCP_comm_t *hcp_comm, uint16_t arg_type)
|
||||
{
|
||||
uint16_t i = 0;
|
||||
uint8_t *buffer = hcp_comm->pkt_buffer;
|
||||
@ -77,51 +90,99 @@ fpc_bep_result_t hcp_get_arg(HCP_comm_t *hcp_comm, uint16_t arg_type, uint16_t *
|
||||
while (i < args_nr && (pdata - buffer) <= hcp_comm->pkt_size) {
|
||||
_CMD_arg_t *parg = (_CMD_arg_t *)pdata;
|
||||
if(parg->arg == arg_type) {
|
||||
*size = parg->size;
|
||||
*payload = parg->pld;
|
||||
hcp_comm->arg.size = parg->size;
|
||||
hcp_comm->arg.data = parg->pld;
|
||||
return FPC_BEP_RESULT_OK;
|
||||
} else {
|
||||
i++;
|
||||
pdata += 4 + parg->size;
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore missing ARG_RESULT because some command return result other way
|
||||
// if (arg_type != ARG_RESULT) {
|
||||
bmlite_on_error(BMLITE_ERROR_GET_ARG, FPC_BEP_RESULT_INVALID_ARGUMENT);
|
||||
// }
|
||||
return FPC_BEP_RESULT_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
static fpc_bep_result_t _rx_application(HCP_comm_t *hcp_comm)
|
||||
fpc_bep_result_t bmlite_copy_arg(HCP_comm_t *hcp_comm, uint16_t arg_key, void *arg_data, uint16_t arg_data_length)
|
||||
{
|
||||
fpc_bep_result_t status = FPC_BEP_RESULT_OK;
|
||||
fpc_bep_result_t bep_result;
|
||||
bep_result = bmlite_get_arg(hcp_comm, arg_key);
|
||||
if(bep_result == FPC_BEP_RESULT_OK) {
|
||||
if(arg_data == NULL) {
|
||||
bmlite_on_error(BMLITE_ERROR_GET_ARG, FPC_BEP_RESULT_NO_MEMORY);
|
||||
return FPC_BEP_RESULT_NO_MEMORY;
|
||||
}
|
||||
memcpy(arg_data, hcp_comm->arg.data, HCP_MIN(arg_data_length, hcp_comm->arg.size));
|
||||
} else {
|
||||
bmlite_on_error(BMLITE_ERROR_GET_ARG, FPC_BEP_RESULT_INVALID_ARGUMENT);
|
||||
return FPC_BEP_RESULT_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
fpc_bep_result_t bmlite_tranceive(HCP_comm_t *hcp_comm)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
|
||||
bep_result = bmlite_send(hcp_comm);
|
||||
if (bep_result == FPC_BEP_RESULT_OK) {
|
||||
bep_result = bmlite_receive(hcp_comm);
|
||||
|
||||
if (bmlite_get_arg(hcp_comm, ARG_RESULT) == FPC_BEP_RESULT_OK) {
|
||||
hcp_comm->bep_result = *(int8_t*)hcp_comm->arg.data;
|
||||
} else {
|
||||
hcp_comm->bep_result = FPC_BEP_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
fpc_bep_result_t bmlite_receive(HCP_comm_t *hcp_comm)
|
||||
{
|
||||
fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK;
|
||||
fpc_bep_result_t com_result = FPC_BEP_RESULT_OK;
|
||||
uint16_t seq_nr = 0;
|
||||
uint16_t seq_len = 1;
|
||||
uint16_t len;
|
||||
uint8_t *p = hcp_comm->pkt_buffer;
|
||||
_HPC_pkt_t *pkt = (_HPC_pkt_t *)hcp_comm->txrx_buffer;
|
||||
uint16_t buf_len = 0;
|
||||
|
||||
while(seq_nr < seq_len) {
|
||||
status = _rx_link(hcp_comm);
|
||||
bep_result = _rx_link(hcp_comm);
|
||||
|
||||
if (!status) {
|
||||
len = pkt->lnk_size - 4;
|
||||
if (!bep_result) {
|
||||
seq_nr = pkt->t_seq_nr;
|
||||
seq_len = pkt->t_seq_len;
|
||||
if(buf_len + len < hcp_comm->pkt_size_max) {
|
||||
memcpy(p, &pkt->t_pld, len);
|
||||
p += len;
|
||||
buf_len += len;
|
||||
if(pkt->t_size != pkt->lnk_size - 6) {
|
||||
com_result = FPC_BEP_RESULT_IO_ERROR;
|
||||
continue;
|
||||
}
|
||||
if(buf_len + pkt->t_size < hcp_comm->pkt_size_max) {
|
||||
memcpy(p, &pkt->t_pld, pkt->t_size);
|
||||
p += pkt->t_size;
|
||||
buf_len += pkt->t_size;
|
||||
} else {
|
||||
com_result = FPC_BEP_RESULT_NO_MEMORY;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (seq_len > 1)
|
||||
DEBUG("S: Seqence %d of %d\n", seq_nr, seq_len);
|
||||
LOG_DEBUG("Received data chunk %d of %d\n", seq_nr, seq_len);
|
||||
#endif
|
||||
} else {
|
||||
DEBUG("S: Receiving chunk error %d\n", status);
|
||||
return status;
|
||||
bmlite_on_error(BMLITE_ERROR_SEND_CMD, bep_result);
|
||||
return bep_result;
|
||||
}
|
||||
}
|
||||
|
||||
hcp_comm->pkt_size = buf_len;
|
||||
if(com_result != FPC_BEP_RESULT_OK) {
|
||||
bmlite_on_error(BMLITE_ERROR_SEND_CMD, com_result);
|
||||
}
|
||||
return com_result;
|
||||
}
|
||||
|
||||
@ -133,7 +194,7 @@ static fpc_bep_result_t _rx_link(HCP_comm_t *hcp_comm)
|
||||
uint16_t size;
|
||||
|
||||
if (result) {
|
||||
//DEBUG("Timed out waiting for response.\n");
|
||||
LOG_DEBUG("Timed out waiting for response.\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -141,7 +202,8 @@ static fpc_bep_result_t _rx_link(HCP_comm_t *hcp_comm)
|
||||
|
||||
// Check if size plus header and crc is larger than max package size.
|
||||
if (MTU < size + 8) {
|
||||
DEBUG("S: Invalid size %d, larger than MTU %d.\n", size, MTU);
|
||||
// LOG_DEBUG("S: Invalid size %d, larger than MTU %d.\n", size, MTU);
|
||||
bmlite_on_error(BMLITE_ERROR_SEND_CMD, FPC_BEP_RESULT_IO_ERROR);
|
||||
return FPC_BEP_RESULT_IO_ERROR;
|
||||
}
|
||||
|
||||
@ -151,20 +213,21 @@ static fpc_bep_result_t _rx_link(HCP_comm_t *hcp_comm)
|
||||
uint32_t crc_calc = fpc_crc(0, hcp_comm->txrx_buffer+4, size);
|
||||
|
||||
if (crc_calc != crc) {
|
||||
DEBUG("S: CRC mismatch. Calculated %08X, received %08X\n", crc_calc, crc);
|
||||
LOG_DEBUG("CRC mismatch. Calculated %08X, received %08X\n", crc_calc, crc);
|
||||
bmlite_on_error(BMLITE_ERROR_SEND_CMD, FPC_BEP_RESULT_IO_ERROR);
|
||||
return FPC_BEP_RESULT_IO_ERROR;
|
||||
}
|
||||
|
||||
// Send Ack
|
||||
hcp_comm->write(4, (uint8_t *)&fpc_com_ack, 0, NULL);
|
||||
|
||||
return 0;
|
||||
return FPC_BEP_RESULT_OK;
|
||||
}
|
||||
|
||||
static fpc_bep_result_t _tx_application(HCP_comm_t *hcp_comm)
|
||||
fpc_bep_result_t bmlite_send(HCP_comm_t *hcp_comm)
|
||||
{
|
||||
uint16_t seq_nr = 1;
|
||||
fpc_bep_result_t status = FPC_BEP_RESULT_OK;
|
||||
fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK;
|
||||
uint16_t data_left = hcp_comm->pkt_size;
|
||||
uint8_t *p = hcp_comm->pkt_buffer;
|
||||
|
||||
@ -179,48 +242,46 @@ static fpc_bep_result_t _tx_application(HCP_comm_t *hcp_comm)
|
||||
phy_frm->lnk_chn = 0;
|
||||
phy_frm->t_seq_len = seq_len;
|
||||
|
||||
for (seq_nr = 1; seq_nr <= seq_len && !status; seq_nr++) {
|
||||
for (seq_nr = 1; seq_nr <= seq_len && !bep_result; seq_nr++) {
|
||||
phy_frm->t_seq_nr = seq_nr;
|
||||
if (data_left < app_mtu) {
|
||||
phy_frm->t_size = data_left;
|
||||
memcpy(hcp_comm->txrx_buffer + 10, p, data_left);
|
||||
phy_frm->lnk_size = data_left + 6;
|
||||
} else {
|
||||
phy_frm->t_size = app_mtu;
|
||||
memcpy(hcp_comm->txrx_buffer + 10, p, app_mtu);
|
||||
phy_frm->lnk_size = app_mtu + 6;
|
||||
p += app_mtu;
|
||||
data_left -= app_mtu;
|
||||
}
|
||||
memcpy(&phy_frm->t_pld, p, phy_frm->t_size);
|
||||
phy_frm->lnk_size = phy_frm->t_size + 6;
|
||||
p += phy_frm->t_size;
|
||||
data_left -= phy_frm->t_size;
|
||||
|
||||
status = _tx_link(hcp_comm);
|
||||
bep_result = _tx_link(hcp_comm);
|
||||
}
|
||||
|
||||
return status;
|
||||
if(bep_result) {
|
||||
bmlite_on_error(BMLITE_ERROR_SEND_CMD, bep_result);
|
||||
}
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
fpc_bep_result_t _tx_link(HCP_comm_t *hcp_comm)
|
||||
{
|
||||
fpc_bep_result_t result;
|
||||
fpc_bep_result_t bep_result;
|
||||
|
||||
_HPC_pkt_t *pkt = (_HPC_pkt_t *)hcp_comm->txrx_buffer;
|
||||
|
||||
uint32_t crc_calc = fpc_crc(0, &pkt->t_size, pkt->lnk_size);
|
||||
*(uint32_t *)(hcp_comm->txrx_buffer + 4 + pkt->lnk_size) = crc_calc;
|
||||
*(uint32_t *)(hcp_comm->txrx_buffer + pkt->lnk_size + 4) = crc_calc;
|
||||
uint16_t size = pkt->lnk_size + 8;
|
||||
|
||||
result = hcp_comm->write(size, hcp_comm->txrx_buffer, 0, NULL);
|
||||
if(result) {
|
||||
DEBUG("S: Sending error\n");
|
||||
return result;
|
||||
}
|
||||
bep_result = hcp_comm->write(size, hcp_comm->txrx_buffer, 0, NULL);
|
||||
|
||||
// Wait for ACK
|
||||
uint32_t ack;
|
||||
result = hcp_comm->read(4, (uint8_t *)&ack, 100, NULL);
|
||||
if (result == FPC_BEP_RESULT_TIMEOUT) {
|
||||
DEBUG("S: ASK timeout\n");
|
||||
return FPC_BEP_RESULT_OK;
|
||||
bep_result = hcp_comm->read(4, (uint8_t *)&ack, 500, NULL);
|
||||
if (bep_result == FPC_BEP_RESULT_TIMEOUT) {
|
||||
LOG_DEBUG("ASK read timeout\n");
|
||||
bmlite_on_error(BMLITE_ERROR_SEND_CMD, FPC_BEP_RESULT_TIMEOUT);
|
||||
return FPC_BEP_RESULT_IO_ERROR;
|
||||
}
|
||||
|
||||
if(ack != fpc_com_ack) {
|
||||
@ -230,76 +291,3 @@ fpc_bep_result_t _tx_link(HCP_comm_t *hcp_comm)
|
||||
return FPC_BEP_RESULT_OK;
|
||||
}
|
||||
|
||||
fpc_bep_result_t send_command_args2(HCP_comm_t *chain, fpc_hcp_cmd_t command_id,
|
||||
fpc_hcp_arg_t arg_key1, void *arg_data1, uint16_t arg_data1_length,
|
||||
fpc_hcp_arg_t arg_key2, void *arg_data2, uint16_t arg_data2_length)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
hcp_init_cmd(chain, command_id);
|
||||
|
||||
if(arg_key1 != ARG_NONE) {
|
||||
bep_result = hcp_add_arg(chain, arg_key1, arg_data1, arg_data1_length);
|
||||
if(bep_result) {
|
||||
return bep_result;
|
||||
}
|
||||
}
|
||||
|
||||
if(arg_key2 != ARG_NONE) {
|
||||
bep_result = hcp_add_arg(chain, arg_key2, arg_data2, arg_data2_length);
|
||||
if(bep_result) {
|
||||
return bep_result;
|
||||
}
|
||||
}
|
||||
|
||||
bep_result = _tx_application(chain);
|
||||
|
||||
if (bep_result != FPC_BEP_RESULT_OK) {
|
||||
DEBUG("%s:%u ERROR %d\n", __func__, __LINE__, bep_result);
|
||||
}
|
||||
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
fpc_bep_result_t receive_result_args2(HCP_comm_t *chain,
|
||||
fpc_hcp_arg_t arg_key1, void *arg_data1, uint16_t arg_data1_length,
|
||||
fpc_hcp_arg_t arg_key2, void *arg_data2, uint16_t arg_data2_length)
|
||||
{
|
||||
fpc_bep_result_t bep_result;
|
||||
uint16_t size;
|
||||
uint8_t *pld;
|
||||
|
||||
|
||||
bep_result = _rx_application(chain);
|
||||
if(bep_result) {
|
||||
DEBUG("S: Receive err: %d\n", bep_result);
|
||||
return bep_result;
|
||||
}
|
||||
|
||||
if (arg_key1 != ARG_NONE) {
|
||||
bep_result = hcp_get_arg(chain, arg_key1, &size, &pld);
|
||||
if(bep_result == FPC_BEP_RESULT_OK) {
|
||||
if(arg_data1 == NULL) {
|
||||
return FPC_BEP_RESULT_NO_MEMORY;
|
||||
}
|
||||
memcpy(arg_data1, pld, arg_data1_length);
|
||||
} else {
|
||||
DEBUG("Arg1 0x%04X not found\n", arg_key1);
|
||||
return FPC_BEP_RESULT_INVALID_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
if (arg_key2 != ARG_NONE) {
|
||||
bep_result = hcp_get_arg(chain, arg_key2, &size, &pld);
|
||||
if(bep_result == FPC_BEP_RESULT_OK) {
|
||||
if(arg_data2 == NULL) {
|
||||
return FPC_BEP_RESULT_NO_MEMORY;
|
||||
}
|
||||
memcpy(arg_data2, pld, arg_data2_length);
|
||||
} else {
|
||||
DEBUG("Arg2 0x%04X not found\n", arg_key2);
|
||||
//return FPC_BEP_RESULT_INVALID_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
return FPC_BEP_RESULT_OK;
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bep_host_if.h"
|
||||
#include "bmlite_if.h"
|
||||
#include "platform.h"
|
||||
|
||||
#define DATA_BUFFER_SIZE 102400
|
||||
@ -48,13 +48,62 @@ static HCP_comm_t hcp_chain = {
|
||||
.phy_rx_timeout = 2000,
|
||||
};
|
||||
|
||||
|
||||
static void help(void)
|
||||
{
|
||||
fprintf(stderr, "BEP Host Communication Application\n");
|
||||
fprintf(stderr, "Syntax: bep_host_com [-s] [-p port] [-b baudrate] [-t timeout]\n");
|
||||
}
|
||||
|
||||
void bmlite_on_error(bmlite_error_t error, int32_t value)
|
||||
{
|
||||
printf("Error: %d, return code %d\n", error, (int16_t)value);
|
||||
}
|
||||
|
||||
void bmlite_on_start_capture()
|
||||
{
|
||||
printf("Put finger on the sensor\n");
|
||||
}
|
||||
void bmlite_on_finish_capture()
|
||||
{
|
||||
printf("Remove finger from the sensor\n");
|
||||
}
|
||||
|
||||
void bmlite_on_start_enroll()
|
||||
{
|
||||
printf("Start enrolling\n");
|
||||
}
|
||||
|
||||
void bmlite_on_finish_enroll()
|
||||
{
|
||||
printf("Finish enrolling\n");
|
||||
}
|
||||
|
||||
void bmlite_on_start_enrollcapture() {}
|
||||
void bmlite_on_finish_enrollcapture() {}
|
||||
|
||||
void bmlite_on_identify_start()
|
||||
{
|
||||
printf("Start Identifying\n");
|
||||
}
|
||||
void bmlite_on_identify_finish()
|
||||
{
|
||||
printf("Finish Identifying\n");
|
||||
}
|
||||
|
||||
void save_to_pgm(FILE *f, uint8_t *image, int res_x, int res_y)
|
||||
{
|
||||
/* Print 8-bpp PGM ASCII header */
|
||||
fprintf(f, "P2\n%d %d\n255\n", res_x, res_y);
|
||||
for (int y = 0; y < res_y; y++) {
|
||||
for (int x = 0; x < res_x; x++, image++)
|
||||
fprintf(f,"%d ", *image);
|
||||
fprintf(f,"\n");
|
||||
}
|
||||
|
||||
fprintf(f,"\x04"); /* End Of Transmission */
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
char *port = NULL;
|
||||
@ -62,9 +111,6 @@ int main (int argc, char **argv)
|
||||
int timeout = 5;
|
||||
int index;
|
||||
int c;
|
||||
// uint8_t buffer[512];
|
||||
// uint16_t size[2] = { 256, 256 };
|
||||
//fpc_com_chain_t hcp_chain;
|
||||
interface_t iface = COM_INTERFACE;
|
||||
|
||||
opterr = 0;
|
||||
@ -130,8 +176,6 @@ int main (int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// init_com_chain(&hcp_chain, buffer, size, NULL, iface);
|
||||
// hcp_chain.channel = 1;
|
||||
if (iface == COM_INTERFACE) {
|
||||
hcp_chain.read = platform_com_receive;
|
||||
hcp_chain.write = platform_com_send;
|
||||
@ -146,7 +190,7 @@ int main (int argc, char **argv)
|
||||
uint16_t template_id;
|
||||
bool match;
|
||||
|
||||
platform_clear_screen();
|
||||
// platform_clear_screen();
|
||||
printf("BM-Lite Interface\n");
|
||||
if (iface == SPI_INTERFACE)
|
||||
printf("SPI port: speed %d Hz\n", baudrate);
|
||||
@ -160,9 +204,11 @@ int main (int argc, char **argv)
|
||||
printf("c: Remove all templates\n");
|
||||
printf("d: Save template\n");
|
||||
printf("e: Remove template\n");
|
||||
printf("l: List of templates\n");
|
||||
printf("f: Capture image\n");
|
||||
printf("g: Image upload\n");
|
||||
printf("g: Pull captured image\n");
|
||||
printf("h: Get version\n");
|
||||
printf("r: SW Reset\n");
|
||||
printf("q: Exit program\n");
|
||||
printf("\nOption>> ");
|
||||
fgets(cmd, sizeof(cmd), stdin);
|
||||
@ -181,19 +227,30 @@ int main (int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
res = bep_delete_template(&hcp_chain, REMOVE_ID_ALL_TEMPLATES);
|
||||
res = bep_template_remove_all(&hcp_chain);
|
||||
break;
|
||||
case 'd':
|
||||
printf("Template id: ");
|
||||
fgets(cmd, sizeof(cmd), stdin);
|
||||
template_id = atoi(cmd);
|
||||
res = bep_save_template(&hcp_chain, template_id);
|
||||
res = bep_template_save(&hcp_chain, template_id);
|
||||
// res = bep_template_remove_ram(&hcp_chain);
|
||||
break;
|
||||
case 'e':
|
||||
printf("Template id: ");
|
||||
fgets(cmd, sizeof(cmd), stdin);
|
||||
template_id = atoi(cmd);
|
||||
res = bep_delete_template(&hcp_chain, template_id);
|
||||
res = bep_template_remove(&hcp_chain, template_id);
|
||||
break;
|
||||
case 'l':
|
||||
res = bep_template_get_ids(&hcp_chain);
|
||||
if (hcp_chain.bep_result == FPC_BEP_RESULT_OK) {
|
||||
printf("Template list\n");
|
||||
for(int i=0; i < hcp_chain.arg.size/2; i++) {
|
||||
printf("%d ", *(uint16_t *)(hcp_chain.arg.data+i*2));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
break;
|
||||
case 'f': {
|
||||
printf("Timeout (ms): ");
|
||||
@ -212,16 +269,63 @@ int main (int argc, char **argv)
|
||||
if (buf) {
|
||||
res = bep_image_get(&hcp_chain, buf, size);
|
||||
if (res == FPC_BEP_RESULT_OK) {
|
||||
FILE *f = fopen("image.raw", "wb");
|
||||
// if(size != hcp_chain.arg.size) {
|
||||
printf("Image size: %d. Received %d bytes\n", size, hcp_chain.arg.size);
|
||||
// }
|
||||
FILE *f = fopen("image.raw", "wb");
|
||||
if (f) {
|
||||
fwrite(buf, 1, size, f);
|
||||
fclose(f);
|
||||
printf("Image saved as image.raw\n");
|
||||
}
|
||||
f = fopen("image.pgm", "wb");
|
||||
if(f) {
|
||||
save_to_pgm(f, buf, 160, 160);
|
||||
fclose(f);
|
||||
printf("Image saved as image.pgm\n");
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'T': {
|
||||
uint32_t size;
|
||||
uint8_t *buf = malloc(102400);
|
||||
FILE *f = fopen("stemplate.raw", "rb");
|
||||
if (f) {
|
||||
size = fread(buf, 1, 102400, f);
|
||||
fclose(f);
|
||||
if(size > 0) {
|
||||
printf("Pushing template size %d\n", size);
|
||||
res = bep_template_put(&hcp_chain, buf, size);
|
||||
if (res != FPC_BEP_RESULT_OK) {
|
||||
printf("Pushing template error: %d\n", res);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
|
||||
break;
|
||||
}
|
||||
case 't': {
|
||||
uint8_t *buf = malloc(102400);
|
||||
if (buf) {
|
||||
res = bep_template_get(&hcp_chain, buf, 102400);
|
||||
if (res == FPC_BEP_RESULT_OK) {
|
||||
// if(size != hcp_chain.arg.size) {
|
||||
printf("Template size received %d bytes\n", hcp_chain.arg.size);
|
||||
// }
|
||||
FILE *f = fopen("template.raw", "wb");
|
||||
if (f) {
|
||||
fwrite(buf, 1, size, f);
|
||||
fwrite(buf, 1, hcp_chain.arg.size, f);
|
||||
fclose(f);
|
||||
printf("Image saved as image.raw\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
free(buf);
|
||||
break;
|
||||
}
|
||||
case 'h': {
|
||||
@ -234,16 +338,26 @@ int main (int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'r':
|
||||
bep_sw_reset(&hcp_chain);
|
||||
break;
|
||||
case 'q':
|
||||
return 0;
|
||||
default:
|
||||
printf("\nUnknown command\n");
|
||||
}
|
||||
if (res == FPC_BEP_RESULT_OK) {
|
||||
if (hcp_chain.bep_result == FPC_BEP_RESULT_OK) {
|
||||
printf("\nCommand succeded\n");
|
||||
} else {
|
||||
printf("\nCommand failed with error code %d\n", res);
|
||||
printf("\nCommand failed with error code %d\n", hcp_chain.bep_result);
|
||||
}
|
||||
|
||||
if (res == FPC_BEP_RESULT_OK) {
|
||||
printf("Transfer succeded\n");
|
||||
} else {
|
||||
printf("Transfer failed with error code %d\n", res);
|
||||
}
|
||||
|
||||
printf("Press any key to continue...");
|
||||
fgets(cmd, sizeof(cmd), stdin);
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
@ -46,4 +47,9 @@ uint64_t platform_get_time(void)
|
||||
void platform_clear_screen(void)
|
||||
{
|
||||
system("clear");
|
||||
}
|
||||
|
||||
void hal_timebase_busy_wait(uint32_t ms)
|
||||
{
|
||||
usleep(ms * 1000);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user