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:
Andrey Perminov 2020-05-05 13:10:01 -07:00
parent a72af76f31
commit 00bb0d53d0
11 changed files with 1033 additions and 744 deletions

View File

@ -45,6 +45,9 @@ CFLAGS +=\
-MP\ -MP\
-Wno-unused-result -Wno-unused-result
CFLAGS +=\
-DBMLITE_USE_CALLBACK
# C source files # C source files
C_SRCS = $(wildcard src/*.c) C_SRCS = $(wildcard src/*.c)

View File

@ -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 */

View 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

View 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

View File

@ -10,6 +10,11 @@
/** Communication acknowledge definition */ /** Communication acknowledge definition */
#define FPC_BEP_ACK 0x7f01ff7f #define FPC_BEP_ACK 0x7f01ff7f
typedef struct {
uint32_t size;
uint8_t *data;
} HCP_arg_t;
typedef struct { typedef struct {
/** Send data to BM-Lite */ /** Send data to BM-Lite */
fpc_bep_result_t (*write) (uint16_t, const uint8_t *, uint32_t, void *); fpc_bep_result_t (*write) (uint16_t, const uint8_t *, uint32_t, void *);
@ -25,25 +30,13 @@ typedef struct {
uint32_t pkt_size; uint32_t pkt_size;
/** Buffer of MTU size for transport layer */ /** Buffer of MTU size for transport layer */
uint8_t *txrx_buffer; 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; } 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 * @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 * @param arg_data2_length second argument
* @return ::fpc_bep_result_t * @return ::fpc_bep_result_t
*/ */
fpc_bep_result_t receive_result_args2(HCP_comm_t *chain, fpc_bep_result_t bmlite_receive(HCP_comm_t *hcp_comm);
fpc_hcp_arg_t arg_key1, void *arg_data1, uint16_t arg_data1_length, fpc_bep_result_t bmlite_send(HCP_comm_t *hcp_comm);
fpc_hcp_arg_t arg_key2, void *arg_data2, uint16_t arg_data2_length); 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 #endif

View File

@ -109,4 +109,14 @@ uint64_t platform_get_time(void);
*/ */
void platform_clear_screen(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 */ #endif /* PLATFORM_H */

View File

@ -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);
}

View 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);
}

View File

@ -1,26 +1,27 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "bep_host_if.h"
#include "platform.h" #include "platform.h"
#include "fpc_crc.h" #include "fpc_crc.h"
#include "fpc_hcp_common.h" #include "fpc_hcp_common.h"
#include "hcp_tiny.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 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 _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 _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 { typedef struct {
uint16_t cmd; uint16_t cmd;
uint16_t args_nr; uint16_t args_nr;
@ -42,18 +43,30 @@ typedef struct {
_HCP_cmd_t t_pld; _HCP_cmd_t t_pld;
} _HPC_pkt_t; } _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; _HCP_cmd_t *out = (_HCP_cmd_t *)hcp_comm->pkt_buffer;
out->cmd = cmd; out->cmd = cmd;
out->args_nr = 0; out->args_nr = 0;
hcp_comm->pkt_size = 4; 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; 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) { 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; 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; 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; uint16_t i = 0;
uint8_t *buffer = hcp_comm->pkt_buffer; 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) { while (i < args_nr && (pdata - buffer) <= hcp_comm->pkt_size) {
_CMD_arg_t *parg = (_CMD_arg_t *)pdata; _CMD_arg_t *parg = (_CMD_arg_t *)pdata;
if(parg->arg == arg_type) { if(parg->arg == arg_type) {
*size = parg->size; hcp_comm->arg.size = parg->size;
*payload = parg->pld; hcp_comm->arg.data = parg->pld;
return FPC_BEP_RESULT_OK; return FPC_BEP_RESULT_OK;
} else { } else {
i++; i++;
pdata += 4 + parg->size; 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; 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; fpc_bep_result_t com_result = FPC_BEP_RESULT_OK;
uint16_t seq_nr = 0; uint16_t seq_nr = 0;
uint16_t seq_len = 1; uint16_t seq_len = 1;
uint16_t len;
uint8_t *p = hcp_comm->pkt_buffer; uint8_t *p = hcp_comm->pkt_buffer;
_HPC_pkt_t *pkt = (_HPC_pkt_t *)hcp_comm->txrx_buffer; _HPC_pkt_t *pkt = (_HPC_pkt_t *)hcp_comm->txrx_buffer;
uint16_t buf_len = 0; uint16_t buf_len = 0;
while(seq_nr < seq_len) { while(seq_nr < seq_len) {
status = _rx_link(hcp_comm); bep_result = _rx_link(hcp_comm);
if (!status) { if (!bep_result) {
len = pkt->lnk_size - 4;
seq_nr = pkt->t_seq_nr; seq_nr = pkt->t_seq_nr;
seq_len = pkt->t_seq_len; seq_len = pkt->t_seq_len;
if(buf_len + len < hcp_comm->pkt_size_max) { if(pkt->t_size != pkt->lnk_size - 6) {
memcpy(p, &pkt->t_pld, len); com_result = FPC_BEP_RESULT_IO_ERROR;
p += len; continue;
buf_len += len; }
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 { } else {
com_result = FPC_BEP_RESULT_NO_MEMORY; com_result = FPC_BEP_RESULT_NO_MEMORY;
} }
#ifdef DEBUG
if (seq_len > 1) 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 { } else {
DEBUG("S: Receiving chunk error %d\n", status); bmlite_on_error(BMLITE_ERROR_SEND_CMD, bep_result);
return status; return bep_result;
} }
} }
hcp_comm->pkt_size = buf_len; 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; return com_result;
} }
@ -133,7 +194,7 @@ static fpc_bep_result_t _rx_link(HCP_comm_t *hcp_comm)
uint16_t size; uint16_t size;
if (result) { if (result) {
//DEBUG("Timed out waiting for response.\n"); LOG_DEBUG("Timed out waiting for response.\n");
return result; 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. // Check if size plus header and crc is larger than max package size.
if (MTU < size + 8) { 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; 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); uint32_t crc_calc = fpc_crc(0, hcp_comm->txrx_buffer+4, size);
if (crc_calc != crc) { 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; return FPC_BEP_RESULT_IO_ERROR;
} }
// Send Ack // Send Ack
hcp_comm->write(4, (uint8_t *)&fpc_com_ack, 0, NULL); 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; 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; uint16_t data_left = hcp_comm->pkt_size;
uint8_t *p = hcp_comm->pkt_buffer; 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->lnk_chn = 0;
phy_frm->t_seq_len = seq_len; 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; phy_frm->t_seq_nr = seq_nr;
if (data_left < app_mtu) { if (data_left < app_mtu) {
phy_frm->t_size = data_left; phy_frm->t_size = data_left;
memcpy(hcp_comm->txrx_buffer + 10, p, data_left);
phy_frm->lnk_size = data_left + 6;
} else { } else {
phy_frm->t_size = app_mtu; 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 _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; _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 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; uint16_t size = pkt->lnk_size + 8;
result = hcp_comm->write(size, hcp_comm->txrx_buffer, 0, NULL); bep_result = hcp_comm->write(size, hcp_comm->txrx_buffer, 0, NULL);
if(result) {
DEBUG("S: Sending error\n");
return result;
}
// Wait for ACK // Wait for ACK
uint32_t ack; uint32_t ack;
result = hcp_comm->read(4, (uint8_t *)&ack, 100, NULL); bep_result = hcp_comm->read(4, (uint8_t *)&ack, 500, NULL);
if (result == FPC_BEP_RESULT_TIMEOUT) { if (bep_result == FPC_BEP_RESULT_TIMEOUT) {
DEBUG("S: ASK timeout\n"); LOG_DEBUG("ASK read timeout\n");
return FPC_BEP_RESULT_OK; bmlite_on_error(BMLITE_ERROR_SEND_CMD, FPC_BEP_RESULT_TIMEOUT);
return FPC_BEP_RESULT_IO_ERROR;
} }
if(ack != fpc_com_ack) { 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; 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;
}

View File

@ -31,7 +31,7 @@
#include <getopt.h> #include <getopt.h>
#include <string.h> #include <string.h>
#include "bep_host_if.h" #include "bmlite_if.h"
#include "platform.h" #include "platform.h"
#define DATA_BUFFER_SIZE 102400 #define DATA_BUFFER_SIZE 102400
@ -48,13 +48,62 @@ static HCP_comm_t hcp_chain = {
.phy_rx_timeout = 2000, .phy_rx_timeout = 2000,
}; };
static void help(void) static void help(void)
{ {
fprintf(stderr, "BEP Host Communication Application\n"); fprintf(stderr, "BEP Host Communication Application\n");
fprintf(stderr, "Syntax: bep_host_com [-s] [-p port] [-b baudrate] [-t timeout]\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) int main (int argc, char **argv)
{ {
char *port = NULL; char *port = NULL;
@ -62,9 +111,6 @@ int main (int argc, char **argv)
int timeout = 5; int timeout = 5;
int index; int index;
int c; int c;
// uint8_t buffer[512];
// uint16_t size[2] = { 256, 256 };
//fpc_com_chain_t hcp_chain;
interface_t iface = COM_INTERFACE; interface_t iface = COM_INTERFACE;
opterr = 0; opterr = 0;
@ -130,8 +176,6 @@ int main (int argc, char **argv)
exit(1); exit(1);
} }
// init_com_chain(&hcp_chain, buffer, size, NULL, iface);
// hcp_chain.channel = 1;
if (iface == COM_INTERFACE) { if (iface == COM_INTERFACE) {
hcp_chain.read = platform_com_receive; hcp_chain.read = platform_com_receive;
hcp_chain.write = platform_com_send; hcp_chain.write = platform_com_send;
@ -146,7 +190,7 @@ int main (int argc, char **argv)
uint16_t template_id; uint16_t template_id;
bool match; bool match;
platform_clear_screen(); // platform_clear_screen();
printf("BM-Lite Interface\n"); printf("BM-Lite Interface\n");
if (iface == SPI_INTERFACE) if (iface == SPI_INTERFACE)
printf("SPI port: speed %d Hz\n", baudrate); 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("c: Remove all templates\n");
printf("d: Save template\n"); printf("d: Save template\n");
printf("e: Remove template\n"); printf("e: Remove template\n");
printf("l: List of templates\n");
printf("f: Capture image\n"); printf("f: Capture image\n");
printf("g: Image upload\n"); printf("g: Pull captured image\n");
printf("h: Get version\n"); printf("h: Get version\n");
printf("r: SW Reset\n");
printf("q: Exit program\n"); printf("q: Exit program\n");
printf("\nOption>> "); printf("\nOption>> ");
fgets(cmd, sizeof(cmd), stdin); fgets(cmd, sizeof(cmd), stdin);
@ -181,19 +227,30 @@ int main (int argc, char **argv)
} }
break; break;
case 'c': case 'c':
res = bep_delete_template(&hcp_chain, REMOVE_ID_ALL_TEMPLATES); res = bep_template_remove_all(&hcp_chain);
break; break;
case 'd': case 'd':
printf("Template id: "); printf("Template id: ");
fgets(cmd, sizeof(cmd), stdin); fgets(cmd, sizeof(cmd), stdin);
template_id = atoi(cmd); 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; break;
case 'e': case 'e':
printf("Template id: "); printf("Template id: ");
fgets(cmd, sizeof(cmd), stdin); fgets(cmd, sizeof(cmd), stdin);
template_id = atoi(cmd); 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; break;
case 'f': { case 'f': {
printf("Timeout (ms): "); printf("Timeout (ms): ");
@ -212,16 +269,63 @@ int main (int argc, char **argv)
if (buf) { if (buf) {
res = bep_image_get(&hcp_chain, buf, size); res = bep_image_get(&hcp_chain, buf, size);
if (res == FPC_BEP_RESULT_OK) { 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) { if (f) {
fwrite(buf, 1, size, f); fwrite(buf, 1, hcp_chain.arg.size, f);
fclose(f); fclose(f);
printf("Image saved as image.raw\n"); printf("Image saved as image.raw\n");
} }
} }
} }
free(buf);
}
break; break;
} }
case 'h': { case 'h': {
@ -234,16 +338,26 @@ int main (int argc, char **argv)
} }
break; break;
} }
case 'r':
bep_sw_reset(&hcp_chain);
break;
case 'q': case 'q':
return 0; return 0;
default: default:
printf("\nUnknown command\n"); printf("\nUnknown command\n");
} }
if (res == FPC_BEP_RESULT_OK) { if (hcp_chain.bep_result == FPC_BEP_RESULT_OK) {
printf("\nCommand succeded\n"); printf("\nCommand succeded\n");
} else { } 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..."); printf("Press any key to continue...");
fgets(cmd, sizeof(cmd), stdin); fgets(cmd, sizeof(cmd), stdin);
} }

View File

@ -28,6 +28,7 @@
#include <string.h> #include <string.h>
#include <termios.h> #include <termios.h>
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h>
#include "platform.h" #include "platform.h"
@ -46,4 +47,9 @@ uint64_t platform_get_time(void)
void platform_clear_screen(void) void platform_clear_screen(void)
{ {
system("clear"); system("clear");
}
void hal_timebase_busy_wait(uint32_t ms)
{
usleep(ms * 1000);
} }